2016-06-21 9 views
2

bashスクリプトでは、私は次のコマンドを使用して、IPフォワーディングを有効にしています:私も、私は標準出力をリダイレクトする必要があるので、私自身のエラーメッセージを含めるただしリダイレクトstdoutとstderr

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

をそして、stderrのように見える/dev/null、次へ:

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

これはexamplのために、その中にリダイレクト記号を持っていないコマンドのために働きますE:

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

私は彼らにリダイレクトを持っていないコマンドのためにこの作業を行うことができます方法はありますか?このための回避策はありますか?私はこれをより良くすることができる他の方法ですか?

+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します。 /dev/nullから
  2. リダイレクトecho場合、ファイルディスクリプタ1点、すなわち標準誤差Sのecho/dev/null
  3. リダイレクトする標準出力 '、。

したがって、グローバルにリダイレクト2はリダイレクトをキャンセルします1:何も/proc/sys/net/ipv4/ip_forwardにはなりません!

の標準出力を/proc/sys/net/ipv4/ip_forwardに、echoを標準エラー/dev/nullにリダイレクトしたいと思います。これは次のように達成されます:

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

しかし、私はそれがあなたが探している答えではないと信じています!


は、なぜあなたは/dev/nullechoの標準エラーをリダイレクトするようにしたいですか? 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の標準出力をリダイレクトする:

    $ 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年代に標準出力をリダイレクトする

  • :同上

    $ 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は何も解決しません。

コマンドがあっても実行され、リダイレクションが実行される前にエラーが、バッシュのレベルで起こるので、それはbashはエラーが発生したリダイレクションの瞬間だから前ケースは、2>/dev/nullによって固定されていない:それ書き込みのためにストリームを開くことができず、エラーメッセージを標準出力に出力します。 †

今、私はあなたが次のシナリオを修正しようとしていると思います:ユーザーが/proc/sys/net/ipv4/ip_forwardに書き込むための十分な権限を持っていないとき:

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

標準エラーにエラーメッセージがリダイレクトすることができません単純なリダイレクトで‡

$ 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のみリダイレクションの一部に役立ちます。実際には、あなたのコードは、と完全に同等である:(あなたが機能をしたいので、あなただけが-ない望んでいたものを達成するための方法として、関数構文を使用しているため)、その後

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 

(後者が好ましいです)。

この長いポストにごめんなさい!


; リダイレクションの順序に注意する必要があることがあります。彼らはBashがそれらを読むように、左から右に実行されます。最初に標準エラーをリダイレクトしてから、標準出力を存在しない/書き込めないストリームにリダイレクトする方法はありますか?

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

そうです。

‡ まあ、缶、前の脚注理解している場合:標準エラーに

$ 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

私は_standard **エラー** _を意味しました... ... –

1

が、これはもはやリダイレクトする必要はありませんので、標準出力の一部である

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

echo 1を解決しました。私は2>/dev/nullを追加してstderrをリダイレクトするだけでした。

+1

解決されていません。'ip_forward'は既に標準出力をリダイレクトしているので、出力は生成されません。あなたがしたことは、 'echo 1> .../ip_forward 2>/dev/null'と全く同じです。 – mob

+0

最初の部分について正しいかもしれません。しかし関数を使うと、1は実際には '.../ip_forward'にエコーされます。 'echo 1> .../ip_forward 2>/dev/null 2>&1'を使うとき、私の' .../ip_forward'ファイルは0のままです。私はそれが正しくstdoutとstderrをリダイレクトするかどうかはわかりません。 – Stan

関連する問題