Разница между 2> & -, 2> / dev / null, | &, &> / dev / null и> / dev / null 2> & 1

192

Просто ищу разницу между

  • 2>&-
  • 2>/dev/null
  • |&
  • &>/dev/null
  • >/dev/null 2>&1

и их портативность с non-Bourne shellsкак tcsh, mkshи т.д.

Det
источник
2
Обратите внимание, что, хотя mksh поддерживает &>совместимость с GNU bash, настоятельно рекомендуется не использовать это, так как синтаксический анализ может нарушить семантику существующих сценариев POSIX, а mksh уже отключает это в режиме POSIX.
Мирабилось
Я также видел, ^ /dev/nullчто это делает?
Балуптон

Ответы:

241

Для фона:

  • число 1 = стандартное устройство вывода (т.е. STDOUT)
  • номер 2 = стандартная ошибка (т.е. STDERR)
  • если число явно не задано, то оболочка принимает число 1 (bash)

Сначала давайте рассмотрим функцию этих. Для справки см. Расширенное руководство по написанию сценариев .

функции

2>&-

Общая форма этого - M>&-где «M» - номер дескриптора файла. Это закроет вывод для любого дескриптора файла, на который есть ссылка, то есть «M» .

2>/dev/null

Общая форма этого - M>/dev/nullгде «M» - номер дескриптора файла. Это перенаправит дескриптор файла «M» на /dev/null.

2>&1

Общая форма этого - M>&Nгде «M» и «N» - номера файловых дескрипторов. Он объединяет вывод файловых дескрипторов «M» и «N» в один поток.

|&

Это просто аббревиатура для 2>&1 |. Это было добавлено в Bash 4.

&>/dev/null

Это просто аббревиатура для >/dev/null 2>&1. Он перенаправляет файловый дескриптор 2 (STDERR) и дескриптор 1 (STDOUT) в /dev/null.

>/dev/null

Это просто аббревиатура для 1>/dev/null. Перенаправляет файловый дескриптор 1 (STDOUT) на /dev/null.

Переносимость на не-bash, tcsh, mksh и т. Д.

Я не имел дело с другими оболочками за пределами cshи tcsh. Мой опыт работы с этими двумя по сравнению с операторами перенаправления bash заключается в том, что bash превосходит их. Смотрите страницу руководства tcsh для более подробной информации.

Из команд, которые вы спрашивали ни о одной, напрямую не поддерживается csh / tcsh. Вам придется использовать разные синтаксисы для создания похожих функций.

SLM
источник
У нас есть победитель. Но так что нет никакой разницы в производительности или что-то подобное с 2>&-vs 2>/dev/null(кроме того, что некоторые «плохо» написанные программы 2>&-неправильно понимают )?
Дет
3
Там не должно быть никакой разницы в производительности.
SLM
5
&>был bashс самого начала (и нарушает совместимость с Bourne и POSIX, так как это означает что-то другое, хотя вряд ли ударит). >&и |&прийти (t)csh(и это единственный способ перенаправить stderr). Они были в zshначале и были добавлены только недавно bash. Смотрите также rcдля лучшего дизайна операторов.
Стефан Шазелас
1
Обновление: о проблеме производительности, который также подтвердил здесь: unix.stackexchange.com/questions/163955/...
Det
1
Привет @slm, спасибо за контакт. Я рад, что мой репо не изменился (+2-2=0). Теперь, что касается редакции, я не много редактирую, но в этом случае я бы сделал это, потому что она разъясняет, что данные после операции будут в N. Я прочитал ваш ответ, и это очень хорошо во всех аспектах. Именно эта небольшая двусмысленность заставила меня задуматься, вот почему издание. Но хорошо, не стесняйтесь повторно добавить или отклонить это, как вы будете. Я надеюсь, что смогу объяснить суть. Продолжайте хорошую работу.
Доктор Беко
11

Это для перенаправления STDERR & STDOUT:

  • 2>/dev/null

    Перенаправить STDERR в / dev / null (не показывать на консоли)

  • |&

    Перенаправить STDERR и STDOUT в STDIN для конвейерной команды (cmd1 | & cmd2)

  • &>/dev/null

    Перенаправьте STDERR и STDOUT в / dev / null (на консоли ничего не отображается)

  • >/dev/null

    Перенаправить STDOUT в / dev / null (на консоли отображается только STDERR)

  • 2>&-

    Для закрытия файлового дескриптора, используемого с перенаправлением

Все это стандартные методы перенаправления для оболочек Борна.

BriGuy
источник
4
|&и &>/dev/nullэто не портативны.
Крис Даун
4

Считайте, что это дополнение к выбранному ответу. Вы можете узнать, какие формы POSIX, а какие нет.

Две формы POSIX участвуют:

2.7.2 Перенаправление вывода

Два основных формата перенаправления вывода:

[П]> слово

[П]> | слово

где необязательный n представляет номер дескриптора файла. Если номер опущен, перенаправление должно ссылаться на стандартный вывод (дескриптор файла 1).

Перенаправление вывода с использованием формата '>' завершится неудачно, если установлена ​​опция noclobber (см. Описание набора -C), а файл, названный расширением слова, существует и является обычным файлом. В противном случае, перенаправление с помощью «>» или «> |» форматы должны вызывать создание и открытие файла, имя которого является результатом раскрытия слова, для вывода в указанном дескрипторе файла или стандартного вывода, если ничего не указано. Если файл не существует, он должен быть создан; в противном случае он должен быть обрезан до пустого файла после открытия.

-

2.7.6 Дублирование дескриптора выходного файла

Оператор перенаправления:

[П]> & слово

дублирует один дескриптор выходного файла из другого или закрывает один. Если слово соответствует одной или нескольким цифрам, дескриптор файла, обозначенный n, или стандартный вывод, если n не указано, должны быть сделаны как копия дескриптора файла, обозначенного словом; если цифры в слове не представляют файловый дескриптор, уже открытый для вывода, должна произойти ошибка перенаправления; см. Последствия ошибок оболочки. Если слово оценивается как '-', дескриптор файла n или стандартный вывод, если n не указано, закрывается. Попытки закрыть дескриптор файла, который не открыт, не являются ошибкой. Если слово оценивает что-то еще, поведение не определено.

Следовательно:

Function      POSIX-compat    POSIX 
2>&-          Yes             close 
2>/dev/null   Yes             redir
2>&1          Yes             dup 
|&            No              
&>/dev/null   No
>/dev/null    Yes             redir
>&/dev/null   ?               ?dup

Последняя строка не в оригинальном вопросе, но она работает без жалоб в bash. (Также работает с / dev / tty, заменяющим / dev / null).

Крейг Хикс
источник
1
Я всегда хочу знать больше.
Det