У чому різниця між &> та 2> & 1


30

Існує дві форми перенаправлення на стандартний вихід і стандартну помилку на стандартний вихід . Але який з них кращий? і чому &>вважається ідеальним?

Я не можу знайти, в чому різниці, так що багато навчальних посібників і навіть ручний стан, що &>краще!

Так чому я повинен використовувати, &>а ні2>&1

В основному використовують bashоболонку


EDIT: Дякую за коментарів

Тільки> & працює у csh чи tcsh

У ksh працює лише 2> & 1.

використання тире> лише файл 2> і 1 переспрямування

Тоді який з них використовувати для забезпечення сумісності мого сценарію з іншими системами незалежно від використовуваних оболонок!


кращий - це те, що робить те, що вам потрібно зробити. це роблять дуже різні речі. яку оболонку ви використовуєте?
Скаперен

@Skaperen using bash
Maythux

1
що ти хочеш досягти?
Скаперен

Я просто хочу знати, в чому полягають відмінності, те, що я хочу, не в обох, але мені просто потрібно знати, чи є різниця, щоб один раз було вказано інше
Maythux

2
&> somewhere- це лише скорочення скорочень > somewhere 2>&1: за словами керівника з bash, вони "символічно еквівалентні"
steeldriver

Відповіді:


23

Сторінка чоловіка Баша згадує про два способи перенаправлення stderr і stdout : &> file і >& file. Тепер зауважте, що він говорить і stderr, і stdout.

У разі цього >file 2>&1ми робимо перенаправлення stdout (1) на файл, але потім також повідомляємо stderr (2) переспрямовуватися на те саме місце, що і stdout! Тож мета може бути однаковою, але ідея трохи іншою. Іншими словами "Джон, йди до школи; Сьюзі йди куди йде Джон".

Що з перевагою? &>це bashріч. Тож якщо ви переносите сценарій, це не зробить. Але якщо ви на 100% впевнені, що ваш сценарій буде працювати тільки в системі з bash - тоді переваг немає

Ось приклад із dashпрограмою Debian Amquist Shell, яка є замовчуванням Ubuntu.

$ grep "YOLO" * &> /dev/null
$ grep: Desktop: Is a directory
grep: Documents: Is a directory
grep: Downloads: Is a directory
grep: Music: Is a directory
grep: Pictures: Is a directory
grep: Public: Is a directory
grep: Templates: Is a directory
grep: Videos: Is a directory
grep: YOLO: Is a directory
grep: bin: Is a directory

Як бачите, stderr не перенаправляється

Щоб вирішити свої зміни у питанні, ви можете використовувати, якщо оператор перевіряє змінну $ SHELL і відповідно змінює переспрямування

Але в більшості випадків > file 2>&1має працювати


Більш технічно висловлюється, форма [integer]>&wordназивається копіювальним файлом дескриптора вихідних файлів і є особливістю, визначеною стандартом мови командної оболонки POSIX, що підтримується більшістю оболонок, сумісних з POSIX та оболонками Брурна.

Дивіться також Що означає та що означає саме перенаправлення виводу?


Тоді що відбувається при використанні на деяких інших оболонках?
Maythux

zsh підтримує &>.... @Maythux У оболонках, які не підтримують, &>наприклад dash, потрібно використовувати тривіальне >file 2>&1перенаправлення ..
heemayl

Тоді який з них використовувати, якщо я хочу бути впевненим, що мій сценарій буде сумісний з різними оболонками
Maythux

3
@Maythux Використання >file 2>&1. Ця робота над усіма снарядами
Сергій Колодяжний

1
@ TSJNachos117 оболонки, встановлені /etc/passwdдля кожного користувача, є інтерактивними оболонками. Системні сценарії зазвичай є, dash якщо не вказано інше. Що стосується того, що за замовчуванням, воно визначається тим, що позначено /bin/shу випадку Ubuntu dash. У RHEL - це bash, у FreeBSD - це tcsh джерело та ще одне джерело
Сергій Колодяжний,

6

Я б, як правило, рекомендував дотримуватися способу ведення Борна знову Шелла , оскільки bash, мабуть, найпопулярніша оболонка Unix там. Bash зазвичай використовує або &>або 2>&1. ІМХО, і це не "ідеально", тому я рекомендую забути про ці дурниці. Реально, який саме ви повинні використовувати, залежить від того, що ви намагаєтеся зробити.

2>&1зливається stderr з stdout, що може бути корисно, якщо, наприклад, ви хочете передати текст stderr. Так, наприклад, якщо ви хочете побачити, чи програма надрукує певне повідомлення stderr, але не хочете, щоб ваш екран був наповнений (імовірно) неважливим сміттям, ви можете зробити щось на кшталт program 2>&1 | grep crashedякого буде шукати stdout та stderr з програми називається "програма" для слова "розбився".

З іншого боку, якщо ви не хочете, щоб програма взагалі щось друкувала, ви можете просто запустити program &> /dev/null, який перенаправить і stderr, і stdout на / dev / null, спеціальний файл, який магічно змушує речі зникати. Або, якщо ви хочете зберегти висновок програми (можливо, повідомити про помилку чи щось таке), ви можете перенаправити і stderr, і stdout у файл: program &> log.txtперенаправить усі дані у файл під назвою "log.txt". Якщо ви цього хочете, ви можете перенаправити stdout і stderr через program 2> log.txt > log.txtабо program 2>&1 | cat > log.txt, і те і інше матиме такий же ефект, як і використання &>. Якщо ви робите щось на кшталт program 2>&1 > file, лише stdout буде переспрямовано, але stderr все одно може бути перенесений на іншу програму, наприклад, cat, яку можна переспрямувати, як показано вище. Однак, набравши текст&>простіше, ніж будь-який із наведених вище прикладів, оскільки він передбачає введення меншої кількості символів (і людині трохи легше читати). Зверніть увагу, що, program 2> log.txt > log.txtшвидше за все, вони будуть працювати на снарядах без удару.

PS: якщо ви переживаєте за людей, які використовують інші оболонки, є щось, що ви можете додати до першого рядка сценарію, який називається "магічне число" або "шебанг". Це, по суті, спосіб переконатись, що інші комп’ютери (особливо ті, що працюють у операційних системах, подібних Unix) знають, яку програму використовувати для виконання сценарію. Різні сценарії використовують різні шебанги. Шибанг для баш сценарію виглядає так:

#!/bin/bash

Якщо ви використовуєте вище, як перший рядок даного сценарію, bash, як правило, буде використовуватися для виконання зазначеного сценарію. Це комусь значно ускладнить випадкове виконання сценарію з неправильною оболонкою.

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


Хоча я згоден з вами щодо використання #!лінії для прямого запиту bash, вона не завжди доступна в інших системах. Дуже часто розробникам / sysadmins доводиться писати портативні скрипти для систем, на яких вони bashможуть бути недоступні, а встановлення може не знаходитись під їх контролем bash. Це >file 2>&1просто багато портативного.
Сергій Колодяжний

Ви зробили помилку обернення вище, що не призводить до результату, який ви вимагаєте чи бажаєте. Перенаправляємо stderr на stdout, а потім перенаправляємо stdout залишає stderr на вихідний stdout.
ubfan1

Серг: Я не мав на увазі, що баш був універсальним. Однак, я думаю, що більше людей використовують це, ніж кажуть (t) csh. Якщо ви не знаєте, що хтось інший використовує, і вам належить зробити сліпу здогадку, баш - це, мабуть, найкраща ставка. Крім того, я зазвичай не знаю про портативність, оскільки я використовую лише bash. Те, що >file 2>&1є більш портативним, добре знати. Я зроблю редагування, щоб це відобразити.
TSJNachos117

Ubfan1, дякую за інформацію. Я б ніколи не здогадувався за мільйон років, що баш не перенаправить stderr до файлу в цьому випадку. Я щойно відредагував свою відповідь, щоб не допустити інших помилок.
TSJNachos117

4

З Довідкового посібника Bash -> 3.6.4 Перенаправлення стандартного виводу та стандартна помилка :

Ця конструкція дозволяє як стандартний вихід (дескриптор файлу 1), так і стандартний вихід помилок (дескриптор файлу 2) перенаправляти на файл, ім'я якого є розширенням слова.

Існує два формати для перенаправлення стандартного виводу та стандартної помилки:

&>word

і

>&word

З двох форм перша є кращою. Це семантично рівнозначно

>word 2>&1

При використанні другої форми слово може не розширюватися на число або "-". У цьому випадку інші оператори перенаправлення застосовуються (див. Копіювання файлів Дескриптори нижче) з міркувань сумісності.

Також добре посилатися на вікі Грега щодо Input and Output -> 4.2. Маніпуляція з дескриптором файлів :

Для зручності Bash також пропонує вам ще одну форму перенаправлення. Оператор перенаправлення &> насправді є лише коротшою версією того, що ми тут зробили [ 2>&1]; переадресація як stdout, так і stderr у файл.


4

Так чому я повинен використовувати &>, а не 2> & 1

2>&1 є стандартною оболонкою Bourne / POSIX.

&>є баш-розширенням і не є де-юре стандартом.

Якщо ви пишете сценарії, використовуючи розширення bash, рано чи пізно ви зіткнетеся з помилками, що виникають в голові, з повідомленнями про помилки синтаксису, оскільки вони запускаються у стандартній оболонці.

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