Что «2> & 1» делает в командной строке?

59

Я знаю, что >знак используется для перенаправления вывода в командной строке, но у меня возникают проблемы с поиском чего-то, что объясняет использование 2>&1в командной строке. Например:

curl http://www.google.com > /dev/null 2>&1 &
Мэтт Хаггинс
источник

Ответы:

78

1Обозначает стандартный вывод (STDOUT). 2Обозначает стандартную ошибку (STDERR).

Так 2>&1говорит отправлять стандартную ошибку туда, куда когда-либо перенаправляется стандартный вывод. Который, поскольку он отправляется, /dev/nullсродни игнорированию любого вывода.

Chealion
источник
2
Есть ли причина, по которой амперсанд появляется перед 1, но не перед 2? Я думал, что & был зарезервированным символом для выполнения задания в фоновом режиме, но я думаю, что это только в том случае, если амперсанд появляется в виде длинного символа в конце команды ...?
Мэтт Хаггинс
8
Поскольку 0(stdin), 1(stdout) и 2(stderr) на самом деле являются файловыми дескрипторами, для перенаправления оболочка требует наличия амперсанда и перед ними. В этом случае он дублирует файловый дескриптор, эффективно объединяя два потока информации.
Chealion
12
Подумайте об этом так: если у вас просто «1» без амперсанда, оболочка создаст файл с именем «1» и перенаправит вывод stderr на него.
CarlF
1
Хорошо, тогда одно это будет действительно? curl http://www.google.com 2>/dev/nullКак из командной строки узнать, что «2» здесь означает «stderr», и на самом деле это не второй параметр, который я передаю команде curl?
Мэтт Хаггинс
1
@Matt Huggins: Да. Это отправило бы весь вывод stderrпрямо на место /dev/null. Вы можете увидеть это на практике, попробовав curl, curl 1>/dev/nullи curl 2>/dev/nullпросто увидев изменение результата. Опять же, амперсанд необходим только для перенаправления дескриптора файла.
Chealion
23

ТЛ; др

Получить http://www.google.comв фоновом режиме и отказаться от обоих stdoutи stderr.

curl http://www.google.com > /dev/null 2>&1 &

такой же как

curl http://www.google.com > /dev/null 2>/dev/null &

основы

0, 1И 2представляют собой стандартные файловые дескрипторы в POSIX операционных систем. Дескриптор файла - это системная ссылка на (в основном) файл или сокет .

Создание нового файлового дескриптора в C может выглядеть примерно так:

fd = open("data.dat", O_RDONLY)

Большинство системных команд Unix принимают ввод и выводят результат на терминал. curlполучит все, что находится по указанному URL ( google dot com ) и отобразит результат в stdout.

результат скручивания

Перенаправление

Как вы сказали, <и >используются для перенаправления вывода команды в другое место, например, в файл.

Так , например, в ls > myfiles.txt, lsполучает содержимое текущего каталога и >перенаправляет свой вывод myfiles.txt(если файл не существует , он будет создан, в противном случае перезаписаны, но вы можете использовать >>вместо >добавляемого в файл , а). Если вы выполните команду выше, вы заметите, что ничего не отображается на терминале. Это обычно означает успех в системах Unix. Чтобы проверить это, cat myfiles.txtчтобы отобразить содержимое файла на экране.

> / dev / null 2> & 1

Первая часть > /dev/nullперенаправляет вывод stdout, то есть curl, на /dev/null(подробнее об этом впереди) и 2>&1перенаправляет stderrна stdout(который был просто перенаправлен, /dev/nullчтобы все было отправлено /dev/null).

В левой части 2>&1указывается, что будет перенаправлено, а в правой - куда . &Используются на правой стороне , чтобы отличить stdout (1)или stderr (2)из файлов с именем 1или 2. Таким образом, в 2>1конечном итоге будет создан новый файл (если он еще не существует) с именем 1и получится stderrрезультат.

/ DEV / нуль

/dev/nullэто пустой файл, механизм, используемый для отбрасывания всего, что ему написано. Таким образом, curl http://www.google.com > /dev/nullэффективно подавляет curlвыходной.

> / dev / null

Но почему некоторые вещи все еще отображаются на терминале? Это не curl обычный вывод, а данные, отправляемые в stderr, используемые здесь для отображения информации о ходе работы и диагностики, а не только ошибок .

curl http://www.google.com > /dev/null 2>&1игнорирует как curlвывод, так и curlинформацию о прогрессе. В результате ничего не отображается на терминале.

в заключение

В &конце указано, как вы указываете оболочке запускать команду как задание в фоновом режиме . Это заставляет приглашение немедленно вернуться, пока команда выполняется асинхронно за кулисами. Чтобы увидеть текущие вакансии типа jobsв вашем терминале. Обратите внимание, что это отличается от процессов, запущенных в вашей системе. Чтобы увидеть те, topв терминале.

Рекомендации

Хорхе Букаран
источник
1
Это один из лучших ответов на весь сайт с точки зрения верстки, молодец!
ОмарОтман
Одна вещь, которую я не понимаю, - почему ты хочешь отправить все /dev/null? Разве вам не нужны результаты curlхотя бы где-нибудь полезного?
skube
@skube Верно. В этом случае мне не понятно, почему пользователь хочет отказаться от stdout и stderr. OP, вероятно, просто хотел понять, что означает синтаксис.
Хорхе Букаран
5

2относится к STDERR. 2>&1отправит STDERR в то же место, что и 1(STDOUT).

Джон Т
источник
0

Я понимаю, как следует:

Если вы хотите только прочитать информацию «Вывод и ошибка» команды на экране, просто напишите: curl http://www.google.com

И иногда вы хотите сохранить информацию вывода в файл вместо экрана терминала для последующего просмотра, тогда вы можете написать: curl http://www.google.com > logfile

Но в этом случае информация StdErr будет опущена, поскольку >перенаправляется только StdOut logfile.

Таким образом, если вы заботитесь об информации об ошибке команды, когда она не выполняется, вам нужно объединить StdOut с StdErr с помощью 2>&1(что означает сворачивание StdErr в StdOut), поэтому можно написать следующую командную строку: curl http://www.google.com > logfile2> & 1

YaOzI
источник