linux - 3> & 1 ইঙ্গিত করে 4> & 3 5> এবং 3 ইত্যাদি?




bash shell (2)

একটি tee বাগ?

জন কুগেলম্যানের উত্তর ঠিক আছে, তবে সমস্যাটি জটিল হওয়ায় আমি আরও কিছুটা এগিয়ে যাব:

bash -c 'exec 2> >(exec sed -ue "s/^/StdErr: /");
    exec 1> >(exec sed -ue "s/^/StdOut: /");
    tee /dev/fd/{2..6} <<<foo'
StdErr: foo
StdOut: foo
StdErr: foo
StdErr: foo
StdErr: foo
StdErr: foo

এসটিডিআরটিতে * STDERR এবং 1 এক্সে ইনপুট (ফু) মুলিপিলেড 5x দেখানো হচ্ছে। সুতরাং সমস্ত /dev/fd/{3..6} /dev/fd/2 /dev/fd/{3..6}

strace -o >(grep dev/fd) -e openat tee /dev/fd/{2..6} <<<foo 4>/dev/null
foo
foo
foo
foo
openat(AT_FDCWD, "/dev/fd/2", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
openat(AT_FDCWD, "/dev/fd/3", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 5
openat(AT_FDCWD, "/dev/fd/4", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 6
openat(AT_FDCWD, "/dev/fd/5", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 7
openat(AT_FDCWD, "/dev/fd/6", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 8

সুতরাং tee 5 এর পরিবর্তে tty 4x ইনপুট উত্পাদন করে ( 2..6 + 2..6 = 6 , - 1x / দেব / নাল => 5 উপস্থিত foo ):

  1. অ্যাক্সেস /dev/fd/2 , ফাইল বর্ণনাকারী 3 খোলার ... এবং তাই তৈরি করুন /dev/fd/3 , তারপরে
  2. অ্যাক্সেস /dev/fd/3 , এখন যা বিদ্যমান রয়েছে, পূর্ববর্তী ক্রিয়াকলাপ থেকে, ফাইল বর্ণনাকারী 5 খুলুন (কারণ /dev/fd/4 কমান্ড লাইনের দ্বারা /dev/fd/5 ... এবং তাই /dev/fd/5 তাহলে
  3. অ্যাক্সেস /dev/fd/4 (কমান্ড লাইনের দ্বারা /dev/null /dev/fd/6 ) এবং /dev/fd/6 তৈরি করুন
  4. অ্যাক্সেস /dev/fd/5 , এখন যা বিদ্যমান, (3 টি আবদ্ধ, 2 তে আবদ্ধ) ...
  5. অ্যাক্সেস /dev/fd/6 , যা এখন বিদ্যমান, তবে /dev/fd/4 উইন্ডে বাঁধা হয় /dev/fd/4 আবদ্ধ করা হয়।

প্রত্যাশিত আউটপুট হতে পারে:

tee /dev/fd/{2..6} <<<foo
foo
tee: /dev/fd/3: No such file or directory
tee: /dev/fd/4: No such file or directory
tee: /dev/fd/5: No such file or directory
tee: /dev/fd/6: No such file or directory
foo

আউটপুট সাথে STDERR এ 1 বার এবং STDOUT এ 1 বার এবং 4 টি ত্রুটি লাইনের সাথে।

সুতরাং tee শুরুর আগে লক্ষ্যগুলি অস্তিত্ব চেক করবেন না। তবে এটি কি বাগ !?

write mode কোনও ফাইল খোলার সাথে সাথে ফাইলটি না থাকলেও ঠিক হতে পারে (নতুন ফাইল তৈরি করা) be

পরীক্ষার সময়-ব্যবহার (টেকটিউ) রেস কন্ডিশন জন কুগেলম্যানের মন্তব্য দ্বারা নির্দেশিত কেন প্রাক চেক করা একটি ভুল ভাল ধারণা তা বুঝতে সহায়তা করে।

সুতরাং যদি কোনও বাগ হয় তবে আমি মনে করি /dev/fd/ সরাসরি /dev/fd/ tee /dev/fd/ দ্বারা পুনরায় উল্লেখ করা হ'ল বাগটি এখানেই রয়েছে (কমান্ড লাইনে)। ... tee বাগ নয়, কেবল বগি ব্যবহারকারী ;-)

আমি আশা করব

echo foo | tee /proc/self/fd/{3..6} 3>&1

/ proc / স্ব / fd / 4 এর মতো ত্রুটিগুলি সহ ব্যর্থ হওয়া : এ জাতীয় কোনও ফাইল বা ডিরেক্টরি ইত্যাদি নয়, তবে আমার আশ্চর্যের বিষয়, এটি আউটপুট

foo
foo
foo
foo
foo

এটি 3>&1 এর মতো নিম্নলিখিত সমস্ত বর্ণনাকারীকে স্টডআউটে পুনঃনির্দেশিত করে, কারণ যদি আমি 3 অন্য কিছুতে পরিবর্তন করি তবে এটি কাজ করে না

$ echo foo | tee /proc/self/fd/{3..6} 4>&1
tee: /proc/self/fd/3: No such file or directory
tee: /proc/self/fd/5: No such file or directory
tee: /proc/self/fd/6: No such file or directory
foo
foo
$ echo foo | tee /proc/self/fd/{4..6} 4>&1
tee: /proc/self/fd/5: No such file or directory
tee: /proc/self/fd/6: No such file or directory
foo
foo

এই আচরণের কোনও ব্যাখ্যা আছে কি?


strace সিস্টেম কলগুলির এই ক্রমটি দেখায়:

$ strace -o strace.log tee /proc/self/fd/{3..6} 3>&1
...
$ cat strace.log
...
openat(AT_FDCWD, "/proc/self/fd/3", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 4
openat(AT_FDCWD, "/proc/self/fd/4", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 5
openat(AT_FDCWD, "/proc/self/fd/5", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 6
openat(AT_FDCWD, "/proc/self/fd/6", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 7
...

প্রথম লাইনটি /proc/self/fd/3 খোলে এবং এটি পরবর্তী উপলভুক্ত এফডি সংখ্যা নির্ধারিত করে, ৪ /proc/self/fd/3 একটি বিশেষ পথ। এটি খোলার ফলে dup 3: ফড 4 পয়েন্ট একই জায়গায় 4 ডি পয়েন্ট, dup অনুরূপ প্রভাব রয়েছে dup

প্রতিটি ক্রমাগত openat() কলের জন্য একই জিনিস ঘটে। ধুলো যখন এফডিএস 4, 5, 6, এবং 7 স্থির করে তখন এফডি 3 এর নকল।

  • 1 → tty
  • 3 → tty
  • 4 → tty
  • 5 → tty
  • 6 → tty
  • 7 → টিটি

নোট করুন যে 3>&1 পুনর্নির্দেশ গুরুত্বপূর্ণ নয়। সবচেয়ে গুরুত্বপূর্ণটি হ'ল আমরা টি /proc/self/fd/N খুলতে বলছি যেখানে এন ইতিমধ্যে ব্যবহৃত। আমরা 3>&1 মুক্তি পেয়ে এবং পরিবর্তে /proc/self/fd/2 এ টি শুরু করলে আমাদের একই ফলাফল পাওয়া উচিত। দেখা যাক:

$ echo foo | tee /proc/self/fd/{2..6}
foo
foo
foo
foo
foo
foo

নিশ্চিত হয়েছে! একই ফলাফল।

আমরা একই সাথে এফডি সংখ্যাটিও বারবার করতে পারি। আমরা যখন এফডি 6. এ আঘাত করি তখন আমরা একই ফল পাই it এটি শেষের দিকে পৌঁছানোর সাথে সাথে এটি des টি জাম্পকে সম্ভব করার জন্য পর্যাপ্ত বর্ণনাকারী খুলেছে।

$ echo foo | tee /proc/self/fd/{2,2,2,2,6}
foo
foo
foo
foo
foo
foo






proc-filesystem