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