Иногда вы хотите перенаправить как 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 &>?