Різниця між 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і т.д.


2
Зауважте, що, хоча mksh підтримує &>сумісність з GNU bash, настійно рекомендується не використовувати це, оскільки його аналіз може порушити семантику існуючих сценаріїв POSIX, а mksh відключить цю функцію в режимі POSIX вже.
mirabilos

Я також бачив, ^ /dev/nullщо це робить?
balupton

Відповіді:


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. Мій досвід роботи з тими 2, в порівнянні з операторами перенаправлення bash, полягає в тому, що bash є кращим в цьому плані. Докладнішу інформацію див. На сторінці man-tcsh .

З команд, про яких ви запитали жодну, безпосередньо не підтримується csh / tcsh. Для побудови подібних функцій вам доведеться використовувати різні синтаксиси.


У нас є переможець. Але отже, немає різниці в продуктивності чи щось подібне з 2>&-vs 2>/dev/null(крім того, що деякі "погано" написані програми не розбираються 2>&-правильно)?
Дет

3
Різниці в продуктивності не повинно бути.
slm

5
&>був bashз самого початку (і порушує сумісність Bourne та POSIX, оскільки це означає щось інше там, хоча навряд чи вдасться). >&і |&походять (t)csh(і це їх єдиний спосіб перенаправити stderr). Вони були zshз самого початку та були додані лише нещодавно до bash. Дивіться також rcпро краще розроблені оператори.
Stéphane Chazelas

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>&-

    Призначений для закриття дескриптора файлів, який використовується при переадресації

Це всі стандартні методи перенаправлення для оболонок Борна.


4
|&і не&>/dev/null є портативними.
Кріс Даун

4

Розглянемо це доповненням до обраної відповіді. Ви можете дізнатися, які форми є POSIX, а які - ні.

Залучаються дві форми POSIX:

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

Два загальні формати перенаправлення виводу:

[n]> слово

[n]> | слово

де необов'язково n представляє номер дескриптора файлу. Якщо число опущено, перенаправлення має посилатися на стандартний вихід (дескриптор файлу 1).

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

-

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

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

[n]> & слово

повинен дублювати один дескриптор вихідного файлу з іншого або закривати його. Якщо слово оцінюється однією або кількома цифрами, дескриптор файлу, позначений 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
Я завжди хочу знати більше.
Дет
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.