2016-06-21 137 views
2

在bash腳本我使用下面的命令啓用IP轉發:重定向輸出和錯誤重定向命令後

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

不過,我也想包括我自己的錯誤信息,所以我必須重定向標準輸出和stderr到/dev/null,它看起來像以下:

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

這適用於沒有在它重定向符號命令,爲例E:

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_forwardecho的標準錯誤爲/dev/null。這是通過:

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

但閱讀,我相信這不是你要找的答案!


你爲什麼要echo的標準錯誤重定向到/dev/nullecho很少寫入標準錯誤。實際上,只有當寫入錯誤時,寫入標準錯誤的唯一時間是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不能解決任何事情。

前面的情況下不被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只有有用的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 

(後者是優選的)。

對不起,這篇文章很長!


† 我們應該注意的是:重定向的順序。當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