program 2> error.log
program &> filename
program >> filename 2>&1
program 2>&1
Мне удалось понять, что означают эти строки.
Однако я не совсем понимаю, где я должен поставить пробелы. Я также волнуюсь, что на самом деле не имеет значения, где поставить пробелы. Спасибо за чтение.
Да, интервал между словами и перенаправлениями не имеет значения. Это короткий ответ.
Подробности заключаются в том, что оболочка (для простоты, давайте просто обратимся только к bash
) обрабатывает определенные символы и группы символов как «слова» и «метасимволы». Из руководства по bash 4.3:
метасимвол
Символ, который без кавычек разделяет слова. Одно из следующего:
| & ; ( ) < > space tab
И
слово Последовательность символов, рассматриваемая оболочкой как единое целое. Также известен как жетон.
Итак, когда мы делаем:
$ echo "hello world">/dev/null
или
$ echo "hello world" > /dev/null
, это все еще 3 слова («привет мир» можно считать одним словом оболочки, потому что оно в кавычках) , с одним >
метасимволом и парой пробелов. Оболочка увидит его и сначала выполнит перенаправление (поэтому сначала ищет метасимволы), а затем запускает команды в соответствии со своим стандартным поведением.
Однако порядок перенаправлений имеет большое значение, особенно когда вы дублируете файловые дескрипторы с чем-то вроде 2>&1
. Допустим, вы хотите отправить оба stderr и stdin в одно и то же место. Вот неправильный способ сделать это:
$ stat ./non-existent file 2>&1 > /dev/null
stat: cannot stat './non-existent': No such file or directory
stat: cannot stat 'file': No such file or directory
Вы делаете вывод файлового дескриптора 2
в то же место, что и 1
, который является вашим терминалом, но он уже делал это. Вот почему появляется stderr.
Если сначала перенаправить stdout
, и только потом изменить, куда указывает 2
, - тогда это будет работать:
$ stat ./non-existent file > /dev/null 2>&1