2016-06-21 2 views
2

В Баш скрипт я позволяет IP-переадресацию с помощью следующей команды:Перенаправление стандартный вывод и стандартный поток ошибок после команды перенаправления

echo 1 > /proc/sys/net/ipv4/ip_forward

Однако я также хочу, чтобы включить свои собственные сообщения об ошибках, так что я должен перенаправить стандартный вывод и STDERR к /dev/null, который выглядит следующим образом:

echo 1 > /proc/sys/net/ipv4/ip_forward >/dev/null 2>&1

Это работает для команд, которые не имеют символ перенаправления в нем, для exampl е:

route add default gw 10.8.0.1 > /dev/null 2>&1

Есть ли способ, что я могу сделать эту работу для команд, которые действительно имеют перенаправление в них? Есть ли обходной путь для этого? Как я могу сделать это лучше?

+1

Непонятно, какую проблему вы пытаетесь решить. Вы можете иметь только одно перенаправление на дескриптор файла по команде. – chepner

+0

Я хочу выполнить 'echo 1>/proc/sys/net/ipv4/ip_forward', и если это пойдет не так, я хочу, чтобы stderr и stdout (сообщение об ошибке и вывод) были перенаправлены на/dev/null. Другими словами, я не хочу сообщения, когда возникает ошибка. – Stan

+1

Вам не нужно перенаправлять стандартный вывод снова; он уже будет '/ proc/...' Вам нужно только 'echo 1>/proc/... 2>/dev/null'. – chepner

ответ

3

Ваши переадресации являются бессмысленными (без обид).

Это:

echo 1 > /proc/sys/net/ipv4/ip_forward >/dev/null 2>&1 

будет:

  1. перенаправлением echo «ы стандартный вывод в /proc/sys/net/ipv4/ip_forward;
  2. перенаправлением echo «ы стандартный вывод на /dev/null
  3. переадрессации echo» ы стандартной ошибки, где дескриптора файла 1 точки, то есть, чтобы /dev/null.

Следовательно, глобально, перенаправление 2 отменяет перенаправление 1: ничего не будет сделано до /proc/sys/net/ipv4/ip_forward!

Я думаю, вы хотите перенаправить echo на стандартный вывод на /proc/sys/net/ipv4/ip_forward и echo на стандартную ошибку до /dev/null. Это достигается путем:

echo 1 > /proc/sys/net/ipv4/ip_forward 2>/dev/null 

Но, читайте дальше, я считаю, что это не тот ответ, который вы ищете!


Почему вы хотите, чтобы перенаправить стандартную ошибку echo «s к /dev/null? echo очень редко записывает стандартную ошибку. Фактически, единственный раз, когда echo будет писать стандартную ошибку, возникает ошибка записи.Там не несколько способов это может произойти:

  • если диск заполнен (что может быть смоделировано с /dev/full):

    $ echo hello >/dev/full 
    bash: echo: write error: No space left on device 
    $ echo hello >/dev/full 2>/dev/null 
    $ 
    

    (никаких сообщений об ошибках, показанные с перенаправлением 2>/dev/null).

  • , если echo «ы стандартный вывод закрыт:

    $ (exec >&-; echo hello) 
    bash: echo: write error: Bad file descriptor 
    $ (exec >&-; echo hello 2> /dev/null) 
    $ 
    

    (нет сообщений об ошибках, показанные с перенаправлением 2>/dev/null).

Могут быть и другие случаи, когда echo выдает стандартную ошибку. Но следующие, конечно, среди них:

  • Перенаправление echo «s стандартного вывода несуществующего дескриптора файла:

    $ echo hello >&42 
    bash: 42: Bad file descriptor 
    $ echo hello >&42 2>/dev/null 
    bash: 42: Bad file descriptor 
    $ 
    

    Перенаправление 2>/dev/null ничего не исправить; вы можете увидеть, что ошибка исходит от bash, а не от echo (последняя имела бы bash: echo: в качестве префикса).

  • Перенаправление echo «S стандартный вывод в файл без разрешения записи:

    $ touch testfile 
    $ chmod -w testfile 
    $ echo hello > testfile 
    bash: testfile: Permission denied 
    $ echo hello > testfile 2>/dev/null 
    bash: testfile: Permission denied 
    $ 
    

    же, как описано выше, перенаправление 2>/dev/null ничего не исправить.

предыдущие случаи не зафиксированы 2>/dev/null, так как ошибка происходит на уровне Bash, прежде, чем команда даже казнили и переназначения выполняется, потому что в момент перенаправления, что Bash встречает ошибку: он не может открыть поток для записи и выводит сообщение об ошибке на стандартный вывод. & кинжал;

Теперь я предполагаю, что вы пытаетесь исправить следующий сценарий: когда пользователь не имеет достаточных прав на запись в /proc/sys/net/ipv4/ip_forward:

$ echo 1 >/proc/sys/net/ipv4/ip_forward 
bash: /proc/sys/net/ipv4/ip_forward: Permission denied 
$ 

Сообщение об ошибке на стандартной ошибки не может быть переадресован с простым переадресацией & Dagger;:

$ echo 1 >/proc/sys/net/ipv4/ip_forward 2>/dev/null 
bash: /proc/sys/net/ipv4/ip_forward: Permission denied 
$ 

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

$ { echo 1 >/proc/sys/net/ipv4/ip_forward; } 2>/dev/null 

Теперь, объясняет, почему решение вы вывесили в ответ работает: давайте пройти через это, и мы увидим, что есть что-то, что показывает не полностью понял перенаправления (и, надеюсь, этот пост поможет вам понять несколько вещей); Ваш код:

function ip_forward 
{ 
    echo 1 > /proc/sys/net/ipv4/ip_forward 
} 
ip_forward >/dev/null 2>&1 

Это запустит функцию ip_forward, и перенаправлять:

  1. его стандартный выходной поток /dev/null;
  2. , а затем его стандартную ошибку, где ее стандартные выходные точки (т. Е. До /dev/null).

Но функция ip_forward не выводит ничего на стандартный выход! поэтому перенаправление >/dev/nullтолько полезно для 2>&1 часть перенаправления. На самом деле, ваш код полностью эквивалентен:

function ip_forward 
{ 
    echo 1 > /proc/sys/net/ipv4/ip_forward 
} 
ip_forward 2>/dev/null 

Но тогда (так как используется только функция построения как способ достичь того, чего вы хотите, а не потому, что вы хотите функцию), это гораздо лучше, чтобы написать свой код либо как:

echo 1 2>/dev/null >/proc/sys/net/ipv4/ip_forward 

или

{ echo 1 > /proc/sys/net/ipv4/ip_forward; } 2>/dev/null 

(причем последнее предпочтительнее).

Извините за этот длинный пост!


& dagger; Есть что-то, о чем мы должны знать: порядок перенаправления. Они выполняются слева направо, как их читает Баш. Как насчет того, что мы сначала перенаправляем стандартную ошибку, а затем стандартный вывод в несуществующий/незаписываемый поток?

$ echo hello 2>/dev/null >&42 
$ 

Правильно, это работает.

& Dagger; Ну, банка, если вы поняли предыдущую сноску:

$ echo 1 2>/dev/null >/proc/sys/net/ipv4/ip_forward 
$ echo $? 
1 
$ 

Нет ошибку на стандартной ошибке! это из-за порядка перенаправления.

+0

@Stan: Как я уже сказал, 'echo' редко записывает на стандартный вывод ... у вас действительно есть сценарий, где полезно использовать' 2>/dev/null', как вы его написали (т. Е. Как последнее перенаправление)? Я бы: либо не перенаправлял стандартную ошибку вообще, либо перенаправлял _all_ стандартной ошибки, как я показал в этом ответе (используя группы или перенаправляя стандартную ошибку _first_). –

+0

Редко записывается в стандартный ** выход **? И нет, у меня нет конкретного сценария, если честно, так как я не так разбираюсь в bash, я просто хотел скрыть любую ошибку «на всякий случай». – Stan

+0

Я имел в виду _стандарт ** ошибка ** _ ... –

1

решаемые

echo 1 > /proc/sys/net/ipv4/ip_forward ip_forward 2>/dev/null

echo 1 является стандартный вывод части, поэтому они не должны быть перенаправлены больше. Мне нужно было перенаправить stderr, добавив 2>/dev/null.

+1

Не разрешено.'ip_forward' уже перенаправляет свой стандартный вывод, поэтому он не выводит результат. То, что вы сделали, ничем не отличается от 'echo 1> .../ip_forward 2>/dev/null' – mob

+0

Возможно, вы правы в первой части. Но, используя функцию, 1 фактически получает эхо в '.../ip_forward'. При использовании файла 'echo 1> .../ip_forward 2>/dev/null 2> & 1' my' .../ip_forward' остается 0. Теперь это работает. Я не уверен, правильно ли он перенаправляет stdout и stderr. – Stan

Смежные вопросы