سؤال كيفية إخراج أنابيب الإخراج إلى أوامر أخرى؟


مثال:

ls | echo لا تطبع شيئا (خط فارغ ، في الواقع). كنت أتوقع أن تطبع قائمة من الملفات.

ls | grep 'foo'، من ناحية أخرى ، يعمل كما هو متوقع (طباعة الملفات مع "foo" في أسمائهم).

ما أفعله في هذه المواقف هو شيء مثل:       ls | while read OUT; do echo $OUT; done لكن هذا مرهق

لماذا تعمل الأنابيب مع بعض الأوامر ، ولكن ليس مع الآخرين؟ كيف يمكنني التحايل على هذه المشكلة؟


78
2017-09-16 13:40


الأصل


ماذا تتوقع ls | echo لكى يفعل؟ لماذا لا تعمل ببساطة ls؟ - theomega
لقد استخدمت أبسط مثال يوضح وجهة نظري. لقد واجهت هذه المشكلة في الواقع عندما كنت أحاول أن أحدد خطًا واحدًا يعرض كائنات git في مخزن العناصر ونوعها. لذلك ، أنا piped كائن معرف ل git cat-fileلكنها لم تنجح. على ما يبدو ، صدى له نفس السلوك ، لذلك استخدمته كمثال. - Mihai Rotaru
انظر أيضا إلى الأمر -n ل xargs ، فإنه يقول كم حجج لوضعها على subcommand. `... | xargs -n1 git cat-file` - Rich Homolka


الأجوبة:


هناك فرق بين حجج سطر الأوامر والمدخلات القياسية. سوف يربط الأنبوب الإخراج القياسي لعملية واحدة إلى الإدخال القياسي لآخر. وبالتالي

ls | echo

يربط الإخراج القياسي من ls إلى المدخلات القياسية للصدى. حسنا على حق؟ حسنًا ، يتجاهل الصدى الإدخال القياسي ، وسيتخلص من حجج سطر الأوامر - التي لا توجد في هذه الحالة - المعياري الخاص به. الإخراج: لا شيء على الإطلاق.

هناك بعض الحلول في هذه الحالة. واحد هو استخدام الأمر الذي يقرأ stdin ومقالب إلى stdout ، مثل القط.

ls | cat

سوف "العمل" ، وهذا يتوقف على ما هو تعريفك للعمل.

لكن ماذا عن الحالة العامة. ما تريده حقاً هو تحويل stdout من أمر واحد إلى args سطر آخر من سطر الأوامر. كما قال آخرون ، xargs هي أداة المساعد الكنسي في هذه الحالة ، قراءة سطر الأوامر الخاص بها لأمر من stdin الخاص به ، وبناء أوامر لتشغيل.

ls | xargs echo

يمكنك أيضًا تحويل هذا ، باستخدام أمر الاستبدال $()

echo $(ls)

سوف تفعل أيضا ما تريد.

كلتا هاتين الأداتين هما جوهران أساسيان في كتابة النصوص البرمجية ، يجب أن تتعلمهما.

للتأكد من اكتمالها ، كما أشرت في السؤال ، فإن الطريقة الأساسية الأخرى لتحويل stdin إلى سطر الأوامر args هي بنية shell read أمر. فإنه يحول "الكلمات" (الكلمات كما هو محدد من قبل IFS متغير) إلى متغير مؤقت ، والتي يمكنك استخدامها في أي تشغيل الأوامر.


109
2017-09-16 14:16



مفيد جدا إجابة بالمعلومات ، شكرا لك! أنا أتعلم الآن bash ، ولقد رأيت كل من xargs و $ (*) تدوين من قبل ، ولكن لم يبدوا اهتماما كبيرا لهم. الآن أعرف مدى أهميتها ، وسوف ننظر بالتأكيد فيها. - Mihai Rotaru
xargs قد يكون ما يبحث عنه البروتوكول الاختياري. - Iktys


ls | echo يطبع مجرد خط فارغ ل echo لا يقرأ أي مدخلات ؛ الأمر الأخير من خط الأنابيب هو في الواقع echo لا تطبع شيئا سوى خط فارغ.

عموما:

a | b

يتأكد من أن الناتج a تصبح مدخلا b. أقترح عليك أن تقرأ Pipelines قسم من man bash.


إذا كنت تريد حقا أن تستخدم ls و echo هنا بعض الأمثلة (عديمة الفائدة):

ls | xargs -L 1 echo
echo `ls`
for i in `ls` ; do echo $i ; done

16
2017-09-16 13:54





أذا أردت echo ال ls محاولة الأمر:

ls | xargs echo

هذا سوف ندعو echo مع ناتج ls.


7
2017-09-16 14:03



أو ls | xargs -I {} echo {} إذا كنت تريد أن يتم استدعائها لكل سطر على حدة - Alex Abdugafarov


لماذا لا نستخدم ببساطة:

echo `ls`

أو أكثر أمانًا بكثير:

echo "`ls -lrt`"

3
2017-11-09 09:48



أو حتى فقط echo *. - Kazark