Как определить, какой параметр передается команде с оператором перенаправления?

9

Это работает:

$ echo "уведомить-отправить HELLO" | сейчас

Это не:

$ сейчас <echo "уведомить-отправить HELLO"

Там написано «файл или каталог не найден».

Я понимаю, что есть -fопция для этой команды, с помощью которой я могу предоставить файл для выполнения в данный момент.

Так что это заставило меня задуматься ... в общем, как мне узнать, для какого параметра операторы перенаправления предоставляют значение?

влад-Ardelean
источник
5
Ваш вопрос не очень понятен. Что вы подразумеваете под «какой параметр». Ваша проблема, вероятно, в том, что вы (по ошибке) так думаете foo | barи bar < fooэквивалентны. Они не.
Тердон

Ответы:

16

Вы используете две разные вещи здесь и должны использовать третью. Посмотрим:

  1. |Это оператор канала , он служит для передачи вывода одного процесса в качестве ввода другому:

    foo | bar

    Это запускает программу fooи передает ее вывод в качестве ввода в программу bar.

  2. >, <, >>И <<: Это те операторы перенаправления , они служат для передачи данных в / из файлов :

    • foo > bar: запускает программу fooи сохраняет ее вывод в файл bar , перезаписывая 1 его содержимое и создавая его, если он не существует.

    • foo >> bar: запускает программу fooи сохраняет ее вывод в файл bar , добавляя его содержимое и создавая его, если он не существует.

    • foo < bar: бежит foo, приказывая прочитать входные данные из файла bar .

    • Это <<особый случай, поскольку нет смысла «добавлять» ввод в команду, в <<основном (исключительно AFAIK) используется для Here Documents :

      $ cat << EOF > file.txt
      > Hello World!
      > EOF
      

      Конструкция << SomeStringHere > Out.fileбудет перенаправлять весь написанный текст, пока не встретит конечную строку ( EOFв примере выше) в целевой файл. Здесь документы позволяют легко форматировать многострочные строки и включать переменные и специальные символы.

  3. <<<Оператор, то здесь строка , это как здесь документ , но она расширяется переменные. Так, например:

    grep foo <<< "$bar"

    Команда выше эквивалентна echo "$bar" | grep foo.

  4. То, что вы на самом деле ищете, называется подстановкой процесса и является еще одним способом передачи вывода команды другой. Он состоит из <(command).

    foo <(bar) 

    Итак, для вашего atпримера, вы могли бы сделать

    at now < <(echo "notify-send HELLO")

    Вышесказанное работает, потому что процесс подстановки фактически создает файл (для получения более подробной информации прочитайте ссылку выше), и именно файловый дескриптор этого файла передается <в at now.


1 Поведение по умолчанию - перезапись, это можно изменить, установив noclobberопцию bash. Если установлено, echo foo > barпотерпит неудачу, если barсуществует. В этом случае его можно принудительно использовать echo foo |> barвместо. Смотрите раздел 3.6.2 здесь .

terdon
источник
1
Хороший ответ! очень тщательно (особенно с учетом различий между перенаправителями файлов)
steeldriver
@steeldriver ЗВС, лузга, спасибо :) И так было это под Оценил камень. Я хотел бы дать вам +1 за каждую из ловушек, которые ваше решение молча избегает.
Тердон
Не могли бы вы также расширить, чтобы включить некоторую информацию о <<и <<<(который @steeldriver упомянул в своем ответе). Более того, есть еще что-то вроде >>>>>>или <<<<<<<<<<?
Адитья
@ Aditya сделано. И не волнуйтесь, это останавливается на <<<:)
Terdon
12

В данном случае echo "notify-send HELLO"это процесс, а не файл, поэтому вам нужна замена процесса, а не перенаправление файла.

at now < <(echo "notify-send HELLO")

Вы также могли бы использовать здесь строку, чтобы полностью избежать echoкоманды

at now <<< "notify-send HELLO"
steeldriver
источник
5
Видя вопросы, которые вам нравятся (те же, что и у меня), я думаю, вам стоит потратить немного больше времени на Unix и Linux . Мы живем и умираем за классные трюки с
ракушками
@terdon: то же самое для игроков в Perl?
Сильвен Пино
1
@SylvainPineau ооо да. Даже очень :). Серьезно, вопрос, который вам, стальным водителю и мне, очень нравится, встречается там гораздо чаще. Это место полно фанатов командной строки, некоторые из которых нелепо осведомлены.
Тердон