বাশে পাটিগণিতের বিস্তারের মূল্যায়ন


13

নিম্নলিখিত লাইনটি তৈরি করে file_c-6.txtতবে ফলাফলগুলি 5:

$ i=5; ls file_a-${i}.txt file_b-${i}.txt > file_c-$(( ++i )).txt; echo $i
5
$ cat file_c-6.txt
file_a-5.txt
file_b-5.txt

যদি >এটি অপসারণ করে তবে এটি তালিকা file_c-6.txtএবং আউটপুট দেবে 5:

আমি কেন বুঝতে পারি না iএটি প্রথম উদাহরণে কেন মান রাখে না ।

$ i=5; ls file_a-${i}.txt file_b-${i}.txt file_c-$(( ++i )).txt; echo $i
file_a-5.txt  file_b-5.txt  file_c-6.txt
6

4
এটা উদ্ভট।
গ্লেন জ্যাকম্যান

2
আমি যদি এর echoপরিবর্তে ব্যবহার করি তবে lsএটি উভয় ক্ষেত্রেই দ্বিতীয়ভাবে কাজ করে।
চোরোবা

1
এই উত্তরের কোড উদাহরণের সাথে কিছুটা মিল রয়েছে ।
ওয়াইল্ডকার্ড

4
/bin/echoপার্থক্যটি সংরক্ষণ করে, সুতরাং মনে হয় বাহ্যিক কমান্ডগুলির আউটপুট পুনঃনির্দেশগুলি সাব-শেলের মধ্যে ঘটে।
চিপনার

2
Bug-bash@gnu.org- এ অবশ্যই একটি বাগ রিপোর্ট মূল্যবান; এটি বর্তমানে উন্নয়নের অধীনে ৪.৪-এ স্থির হয়নি।
চিপনার

উত্তর:


1

যদি আপনি এটি স্ট্রেসের অধীনে চালনা করেন তবে আপনি দেখতে পাচ্ছেন যে সংস্করণটি ব্যবহার lsকরে তা সাবশেলে কমান্ড শুরু হয়, যেখানে প্রতিধ্বনি ব্যবহার করা সংস্করণটি বিদ্যমান শেলের মধ্যে এটি কার্যকর করে।

এর আউটপুট তুলনা করুন

$ strace -f /bin/bash -o trace.txt -c 'i=5; echo $i; echo file_c-$((++i)).txt; echo $i'
5
6
6

বিরুদ্ধে

strace -f /bin/bash -o trace.txt -c 'i=5; echo $i; ls > file_c-$((++i)).txt; echo $i'
5
5

আপনি প্রথমটি দেখতে পাবেন:

1251  execve("/bin/bash", ["/bin/bash", "-c", "i=5; echo $i; echo file_c-$(( ++"...], [/* 19 vars */]) = 0
...
1251  write(1, "5\n", 2)                = 2
1251  write(1, "file_c-6.txt\n", 13)    = 13
1251  write(1, "6\n", 2)                = 2

এবং দ্বিতীয়টিতে:

1258  execve("/bin/bash", ["/bin/bash", "-c", "i=5; echo $i; ls > file_c-$(( ++"...], [/* 19 vars */]) = 0
...
1258  write(1, "5\n", 2)                = 2
...
1258  stat("/bin/ls", {st_mode=S_IFREG|0755, st_size=110080, ...}) = 0
1258  access("/bin/ls", R_OK)           = 0
1258  clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f7301f40a10) = 1259
1259  open("file_c-6.txt", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
1259  dup2(3, 1)                        = 1
1259  close(3)                          = 0
1259  execve("/bin/ls", ["ls"], [/* 19 vars */]) = 0
1259  write(1, "71\nbin\nfile_a-5.txt\nfile_b-5.txt"..., 110) = 110
1259  close(1)                          = 0
1259  munmap(0x7f0e81c56000, 4096)      = 0
1259  close(2)                          = 0
1259  exit_group(0)                     = ?
1259  +++ exited with 0 +++
1258  <... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 1259
1258  rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 0x7f7301570d40}, {0x4438a0, [], SA_RESTORER, 0x7f7301570d40}, 8) = 0
1258  rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
1258  --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=1259, si_status=0, si_utime=0, si_stime=0} ---
1258  wait4(-1, 0x7ffd23d86e98, WNOHANG, NULL) = -1 ECHILD (No child processes)
1258  rt_sigreturn()                    = 0
1258  write(1, "5\n", 2)                = 2

এই শেষ উদাহরণে, আপনি এটি cloneএকটি নতুন প্রক্রিয়াতে দেখেন (1258 -> 1259 থেকে), সুতরাং এখন আমরা একটি উপ-প্রসেসে আছি। File_c-6.txt এর খোলার অর্থ হ'ল আমরা সাব-শেলের $((++i))মধ্যে মূল্যায়ন করেছি এবং এর স্টাডআউটটি কার্যকর lsকরে ফাইলে সেট করেছি।

পরিশেষে, আমরা দেখতে পেলাম যে উপ-প্রস্থানটি প্রস্থান করে, আমরা শিশুটিকে ফসল কাটা করি, তারপরে আমরা যেখানে রেখেছিলাম সেখানেই চালিয়ে যাব ... $i5 এর সেট সহ এবং আমরা এটিকে আবার প্রতিধ্বনিত করব।

(মনে রাখবেন সাব-প্রসেসের পরিবর্তনশীল পরিবর্তনগুলি পিতামাতার প্রক্রিয়া পর্যন্ত সঞ্চারিত হবে না, যদি না আপনি সন্তানের পরিবর্তনগুলি ধরতে পিতামাতার মধ্যে স্পষ্টভাবে কিছু করেন)


দুর্দান্ত বিশ্লেষণ। ওয়ান সমাধান বৃদ্ধি মান একটি অস্থায়ী পরিবর্তনশীল ব্যবহার করতে হবে: i=5; j=$(( i + 1 )); ls file_a-${i}.txt file_b-${i}.txt > file_c-${j}.txt; i=${j}; echo $i
মার্ফি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.