В чем разница между & и 2 и 1

21

Существует две формы перенаправления стандартного вывода и стандартной ошибки в стандартный вывод . Но какой из них лучше? и почему &> считается идеальным?

Я не могу найти различия, так что многие руководства и даже руководство bash указывают, что &> лучше!

Итак, почему я должен использовать &> , а не 2>&1

В основном использование bash shell

EDIT: Спасибо за комментарии

Только > & amp; работает в csh или tcsh

В ksh работает только 2 & amp; 1.

тире использовать > файл 2 > & amp; 1 только перенаправление

Затем какой из них следует использовать для обеспечения того, чтобы мой скрипт был совместим с другими системами, независимо от того, какие используемые оболочки были!

    
задан Maythux 11.06.2015 в 12:30
источник

4 ответа

17

В man-странице Bash упоминаются два способа перенаправления stderr и stdout : &> file и >& file . Теперь обратите внимание, что он говорит как stderr, так и stdout.

В случае этого >file 2>&1 мы перенаправляем stdout (1) в файл, а затем также указываем stderr (2) на то же место, что и stdout! Таким образом, цель может быть одинаковой, но идея немного отличается. Другими словами: «Джон, иди в школу, Сюззи отправляется туда, куда идет Иоанн».

Как насчет предпочтения? &> - вещь bash . Поэтому, если вы портируете скрипт, это не будет сделано. Но если вы на 100% уверены, что ваш скрипт будет работать только с системой с bash - тогда нет предпочтений

Вот пример с dash , Shell Debian Amquist, который по умолчанию является 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 не перенаправляется

Чтобы обратиться к вашим изменениям в вопросе, вы можете использовать оператор if для проверки переменной $ SHELL и соответственно переадресации изменений.

Но для большинства случаев > file 2>&1 должно работать

В более технических терминах форма [integer]>&word называется Дублирование дескриптора выходного файла и является функцией, заданной стандартом языка командной строки POSIX, которая поддерживается большинством POSIX-совместимых и Brourne-подобных оболочек.

См. также Что делает & amp; означает точно в перенаправлении вывода?

    
ответ дан Sergiy Kolodyazhnyy 11.06.2015 в 12:50
5

Я бы вообще рекомендовал следовать примеру Борна Шэлла, потому что bash, возможно, является самой популярной оболочкой Unix. Обычно Bash использует &> или 2>&1 . ИМХО, не является «совершенным», поэтому я рекомендую забыть об этом глупости. Реально, какой из них вы должны использовать, зависит от того, что вы пытаетесь сделать.

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

С другой стороны, если вы вообще не хотите, чтобы программа вообще ничего печатала, вы могли бы просто запустить 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 может с большей вероятностью работать с оболочками без bash.

PS: если вы беспокоитесь о том, что люди используют другие оболочки, вы можете добавить первую строку своего сценария под названием «магическое число» или «shebang». Это, по сути, способ убедиться, что другие компьютеры (особенно те, которые используют Unix-подобные операционные системы) знают, какую программу использовать для выполнения скрипта. В разных сценариях используются разные shebangs. Шейнг для сценария bash выглядит следующим образом:

#!/bin/bash

Если вы используете вышеуказанное как первую строку данного скрипта, bash обычно используется для выполнения указанного скрипта. Это затруднит кому-то случайное выполнение скрипта с неправильной оболочкой.

PS: Я не собираюсь лгать: до сих пор я не знал, что можно использовать >& , но, насколько это касается bash, похоже, он делает то же самое, что и &> . Вы узнаете что-то новое каждый день.

    
ответ дан TSJNachos117 17.07.2016 в 03:37
3

От Справочное руководство Bash - > 3.6.4 Перенаправление стандартного вывода и стандартная ошибка :

This construct allows both the standard output (file descriptor 1) and the standard error output (file descriptor 2) to be redirected to the file whose name is the expansion of word.

There are two formats for redirecting standard output and standard error:

&>word

and

>&word

Of the two forms, the first is preferred. This is semantically equivalent to

>word 2>&1

When using the second form, word may not expand to a number or ‘-’. If it does, other redirection operators apply (see Duplicating File Descriptors below) for compatibility reasons.

Также полезно ссылаться на Вики Грега по вводу и выводу - > 4.2. Манипуляция дескриптора файла :

For convenience, Bash also makes yet another form of redirection available to you. The &> redirection operator is actually just a shorter version of what we did here [ 2>&1 ]; redirecting both stdout and stderr to a file.

    
ответ дан fedorqui 11.06.2015 в 16:16
3

So Why shall I use &> and not 2>&1

2>&1 - стандартная оболочка Bourne / POSIX.

&> является расширением bash, а не стандартом de jure .

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

    
ответ дан Stephen M. Webb 23.07.2016 в 05:17