Иногда вы хотите перенаправить как stdout, так и stderr в одно и то же место. Это когда >&
используется - он указывает один дескриптор файла на другой.
Например, если вы хотите записать и stdout, и stderr в один и тот же файл (будь то /dev/null
или output.txt
), вы можете перенаправить их отдельно, с помощью
app 1>/dev/null 2>/dev/null
или вы можете перенаправить один файловый дескриптор в файл, а другой файловый дескриптор - в первый:
app 1>/dev/null 2>&1
app 2>/dev/null 1>&2
В первом примере 2>&1
указатель дескриптора файла № 2 указывает на то место, где номер 1 уже указывает. Второй пример достигает того же самого, просто вместо этого начинается с stderr.
В качестве другого примера, есть случаи, когда stdout (дескриптор файла # 1) уже указывает на желаемое местоположение, но вы не можете ссылаться на него по имени (это может быть связано с каналом, сокетом или подобным). Это часто происходит, когда используется расширение процесса ( операторы ` `
or $( )
), которое обычно захватывает только стандартный вывод, но вы можете включить в него stderr. В этом случае вы также >&
должны указать stderr на stdout:
out=$(app 2>&1)
Другой распространенный пример - пейджер или grep
аналогичная утилита, поскольку канал |
обычно работает только на stdout, перед перенаправлением канала stderr перенаправляется на stdout:
app 2>&1 | grep hello
Как узнать, что из 2>&1
или 1>&2
правильно? Уже настроил дескриптор файла идет справа >&
, а файл дескриптора вы хотите редирект идет налево. ( 2>&1
означает «указать дескриптор файла № 2 на дескриптор файла № 1».)
Некоторые оболочки имеют ярлыки для общего перенаправления; Вот примеры из Bash:
1>
можно сократить до всего >
1>foo 2>&1
к >&foo
или&>foo
2>&1 | program
в |& program
app 1>/dev/null 2>&1
будет означать, что 2> & 1 будет указывать на файл, на который 1 уже перенаправлял. Я так понимаю, я мог бы так же легко сделатьapp > /dev/null &>
?