Приоритет stdin и stdout перенаправления в Bash

Мой любимый момент был, когда коллега, который является emacs пользователем, хотел отредактировать важный файл.

Поскольку emacs слишком много должен ввести, он имел, устанавливают псевдоним для emacs:

alias em=emacs

Под влиянием недостаточно или слишком много кофе он, конечно, ввел с опечаткой em ...

Ну, это - просто другая причина использовать vi ... ;)

9
02.06.2011, 20:55
2 ответа

Стандарт POSIX указывает, что перенаправление оболочки слева направо; то есть, порядок является значительным:

Конструкция 2>&1 часто используется для перенаправления стандартной погрешности в тот же файл как стандартный вывод. Так как перенаправления происходят, начиная заканчиваться, порядок перенаправлений является значительным. Например:

ls > foo 2>&1

направляет и стандартный вывод и стандартную погрешность в файл foo. Однако:

ls 2>&1 > foo

только направляет стандартный вывод к файлу foo потому что стандартная погрешность была дублирована как стандартный вывод, прежде чем стандартный вывод был предписан зарегистрировать foo.

bash работает в соответствии с этой частью стандарта:

$ ls doesnotexist > foo 2>&1
$ cat foo
ls: cannot access doesnotexist: No such file or directory
$ ls doesnotexist 2>&1 > foo
ls: cannot access doesnotexist: No such file or directory
$ cat foo
$ 

Что касается передачи по каналу:

Поскольку конвейерное присвоение стандартного ввода-вывода или стандартный вывод или оба происходят перед перенаправлением это может быть изменено перенаправлением. Например:

$ command1 2>&1 | command2

отправляет и стандартный вывод и стандартную погрешность command1 к стандартному входу command2.

10
27.01.2020, 20:06
  • 1
    Это предполагает, что оболочка Bash является POSIX-complient. –  fpmurphy 02.06.2011, 19:13
  • 2
    я не получаю его. Так как Вы сказали, что порядок слева направо, не был должен ls > foo 2>&1 подразумевайте, что перенаправление stdout к нечто затем перенаправляет stderr к stdout. Таким образом, это не должно работать. Столь же вторая команда должна работать. Что я пропускаю здесь? –  Deepak Mittal 02.06.2011, 20:31
  • 3
    @fpmurphy bash обычно совместимый POSIX, кроме ситуаций, обрисованных в общих чертах здесь, где значение по умолчанию bash поведение отличается. Сделать bash соответствуйте больше, можно использовать --posix опция. –  Matt Eckert 02.06.2011, 21:08
  • 4
    @dpacmittal первый пример, ls > foo 2>&1, работает как это: во-первых, стандартный вывод перенаправляется к foo, затем, стандартная погрешность перенаправляется к стандартному выводу, который является теперь файлом foo. Второй пример, ls 2>&1 > foo, работает как это: стандартная погрешность перенаправляется к стандартному выводу, прежде чем стандартный вывод будет перенаправлен к foo, таким образом, стандартная погрешность отражена локально вместо того, чтобы быть направленной к файлу. –  Matt Eckert 02.06.2011, 21:15
  • 5
    @dpacmittal.. ре ls 2>&1 >foo возможно, можно думать о нем как это. stderr от 'ls' перенаправляется к stdout. Это произойдет! Это пойдет туда, где stdout в настоящее время присваивают пойти, независимо от дальнейших директив, касающихся stdout.. (потому что это - его главная/первая директива).. Затем вдоль прибывшего другая директива, в которой говорится, что stdout перейдет к "нечто", и это делает... Помните: stderr не преобразовывается в фактическое становление stdout.. Это просто идет туда, где stdout был присвоен во время директивы. (например, терминал) –  Peter.O 02.06.2011, 21:45

Я не предполагаю ни одного. Пара круглой скобки означает подоболочку. Но в этом случае, никакая подоболочка не будет запущена из-за перенаправления. Bash просто питается cmd2 в stdin и подачу stdout в cmd3.

Я думаю, сделайте Вы имеете в виду что-то как cmd1 | cmd2 | cmd3? Поскольку Ваш cmd2 и cmd3 обычно нормальные файлы вместо "cmds".

4
27.01.2020, 20:06

Теги

Похожие вопросы