Розуміння того, як входи надсилаються до труб у Bash


17

Я не дуже розумію, як труби працюють в баш.

Я знаю, що він приймає вихід з однієї команди як вхід в іншу команду.

Який вихід я можу отримати, тому що це команда, яка виводить на екран.

Але як я можу знати, який вхід буде приймати команда?

Ось приклад, який я думав, що спрацює:

which gem | rm

На жаль, не вдалося.

Який самоцвіт роздруковує /usr/bin/gemтак, що має бути правильним?

Я думав, що це було дано rm, так було б, rm /usr/bin/gemале я помилявся.

Отже, моє запитання полягає в тому, як я можу знати, який вхід бере команда?


2
Крім усього іншого, rm /usr/bin/gemце жахлива ідея. Залиште це gem(і інтерпретатор Ruby, з яким він йде), і встановіть потрібний перекладач Ruby (і gem), використовуючи rvm: rvm.beginrescueend.com
Telemachus

Відповіді:


23

"Введення" та "аргументи командного рядка" - це різні речі.

rm видаляє файли, надані як аргументи.

Труба перенаправляє вихід лівої команди на вхід праворуч команди. Це не впливає на аргументи командного рядка праворуч.

Щоб зробити те, що ви намагаєтеся, спробуйте xargsперетворити стандартний вхід в аргументи командного рядка для виконання програми. Це його робота.

which gem | xargs rm, наприклад, видалить gemваш PATH.


12

rmне приймає вхід, він бере аргументи. Це різні. Аргументи - це комутатори та назви файлів тощо, які ви надаєте програмі в командному рядку, щоб впливати на її поведінку. Вхідні дані - це дані, над якими працює програма. Наприклад, grepбере і введення, і аргументи:

grep "foo" file.txt

Є два аргументи "foo"і там file.txt. Вхід є змістом з file.txt, а не рядки file.txtсамого. Оскільки grep приймає вхід, ви можете використовувати його з трубами:

cat file.txt | grep "foo"

виробляє той же результат, так як кішка приймає в file.txtякості аргументу, і виробляючи вміст з в file.txtякості вихідного сигналу. Потім цей результат передається в файл grep, даючи такий же ефект, як і сам файл grep, відкриваючи файл, як у першому прикладі.

Якщо ви хочете використовувати вихід однієї програми в якості аргументу іншій, використовуйте зворотні посилання:

rm `which gem`

або цей альтернативний (баш-специфічний) синтаксис:

rm $(which gem)

Редагувати: або xargsяк вказує інший відповідь. Багато способів скинути кішку командним рядком.


Варто зазначити, що це cat file.txt | grep "foo"може бути в сотні разів повільніше, ніж grep "foo" file.txt.
Borealid

1
це частина, яку я не отримую. як я можу знати, що таке аргумент та що таке стандартне введення?
ajsie

8
@ajsie: Якщо ви введете його після назви програми та перед натисканням клавіші Enter, це аргумент. Якщо ви введете його в програму після запуску, це стандартний ввід.
Borealid

1
Зрозумів! Це все пояснило. Тепер я знаю, що я можу використовувати команду безпосередньо і побачити, чи підкаже це мені (grep), і я також міг прочитати посібник (man grep), щоб побачити, чи використовує він std.
ajsie

@ajsie: Якщо ви не хочете зануритися на сторінку, також grep --helpє короткий огляд прийнятих аргументів.
Borealid

3

Перегляньте manсторінки команд, які вас цікавлять. Ці програми означать, що вони читають stdin(спробуйте man grepпопулярну команду, яка читає stdin).


Я спробував man grep | grep 'standard input'і дістався If no file arguments are specified, the standard input is used.як останній матч. 👍 Мені довелося grepтрохи покуштувати власну медицину. 😎
ma11hew28

2

Усі вони небезпечні для запуску, якщо у вашому PATH є каталог, який містить пробіл, або якщо ім'я команди містить пробіл:

rm `which gem`       # Dangerous
rm $(which gem)      # Dangerous
which gem | xargs rm # Dangerous

GNU Parallel http: // www.gnu.org/software/parallel/ не має цієї проблеми, тому це буде працювати, навіть якщо у вашому PATH є каталог, який містить пробіл, або якщо ім'я команди містить пробіл:

which gem | parallel rm
parallel -a <(which bass) rm

Перегляньте вступне відео для GNU Parallel: http://www.youtube.com/watch?v=OpaiGYxkSuQ

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.