яка різниця між `>> / dev / stderr` (з пробілом) та`> & 2`?


11

В баш.

У мене виникають труднощі визначити, що мені слід використовувати?

усі мої сценарії використовують ">> / dev / stderr"

на баш підкажіть, якщо я намагаюся:
echo test >>/dev/stderrроботи
echo test >> /dev/stderrроботи
echo test >/dev/stderrроботи
echo test > /dev/stderrроботи

echo test >>&2ПОМИЛКИ!
echo test >> &2ПОМИЛКИ!
echo test >&2працює
echo test > &2НЕОБХІДНО!

Я готовий змінити всі свої сценарії на >&2.

Здається, це також має великий вплив на ssh (after su SomeUser), де він >>/dev/stderrвзагалі не працюватиме (дозвіл відмовлено), лише >&2працюватиме.


чи можете ви показати приклад помилки ssh? Я не можу це відтворити.
Джефф Шаллер

@JeffSchaller ви маєте рацію. Лише після suцього виникає проблема, оновлено питання
Водолій

@AquariusPower, ... щоб до речі пояснити цю невідповідність: з su -c 'some command', командою керує /bin/sh, ні bash, тому поведінка, специфічна для bash (наприклад, моделювання /dev/stderrдля цілей перенаправлення, коли вони відсутні), не гарантується.
Чарльз Даффі

Відповіді:


22

>& nє синтаксисом оболонки, щоб безпосередньо дублювати дескриптор файлу . Дескриптор файлу 2 - stderr; ось так це працює. Ви можете копіювати й інші дескриптори файлів, а не лише stderr. Тут ви не можете використовувати режим додавання, оскільки дублювання дескриптора файлу ніколи не скорочується (навіть якщо ваш stderr - файл) і >&є одним маркером, тому ви не можете помістити простір всередині нього, але >& 2працює.

>> name- це інший дозволений синтаксис, де nameє ім'я файлу (а маркер є >>). У такому випадку ви використовуєте ім'я файлу /dev/stderr, що в залежності від ОС (в Linux це посилання на симулятор /proc/self/fd/2) також означає стандартну помилку. Режим додавання та обрізання обох завершується, роблячи те ж саме, коли stderr - це термінал, оскільки його не можна обрізати. Якщо ваша стандартна помилка - це файл, він буде усічений:

anthony@Zia:~$ bash -c 'echo hi >/dev/stderr; echo bye >/dev/stderr' 2>/tmp/foo
anthony@Zia:~$ cat /tmp/foo
bye

Якщо ви бачите помилку з /dev/stderrнад ssh, можливо, адміністратор сервера застосував певний захід безпеки, що запобігає роботі цього симпосилання. (Наприклад, ви не можете отримати доступ /procабо /dev). Хоча я очікував, що викличе будь-які дивні поломки, використання синтаксису дескриптора файлів-дублікатів є цілком розумним (і, можливо, трохи більш ефективним) підходом. Особисто я віддаю перевагу.


У мене виникли великі проблеми, намагаючись повторити ту проблему укорочення, яку я мав раніше (інакше я б додав це до питання хе-хе), тому я змінив все, щоб використовувати >>, thx для вказівки на це! Також я пропустив крок su SomeUserпісля підключення через ssh.
Сила Водолія

це bash -c 'echo hi >&2; echo bye >&2' 2>/tmp/foo;cat /tmp/fooне буде усікати тхо! (навіть із 2>&1 |tee /tmp/foo), що ідеально підходить для ведення журналів, і буде працювати ідеально після того, як я все це зміню >&2. Тож я здогадуюсь, що лише безпосередньо використання файлів /dev/stderrдозволяє виконувати обрізання, а не дубльований дескриптор.
Сила Водолія

@AquariusPower правильний, повторюваний дескриптор файлу ніколи не скорочується. Це в першому абзаці, можливо, мені потрібно це якось виділити?
derobert

не потрібен, я повільний іноді ehehe
Водолій Сила

3
Цю відповідь можна вдосконалити. > & - це один знак не два, і в цьому лежить плутанина ОП.
Джошуа

8

Випадки відмов трапляються тому, що синтаксис bash для використання &у перенаправленнях вказує одиницю >та вимагає, щоб він існував безпосередньо поруч із &знаком:

[n]> & слово


2

Використовувати '>'для переадресації (скорочує, якщо існує) або '>>'(додає, якщо існує).

Використовуйте , '>&'щоб дублювати потік, наприклад, якщо ви хочете стандартний висновок і стандартну помилку в тому ж файл, ви поміняєте в файл , '> output.log'а також помилки з'2>&'

myjob.sh > output.log 2>&
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.