2017-04-06 89 views
0

是否可以在bash中重新定義文件描述符(例如stderr)?如何在bash中重新定義stdout/stderr?

我想默認發送所有輸出到文件,同時仍然能夠使用原始stderrstdout

#!/bin/bash 
echo "Error: foo bar" 1>2 
REAL_STDERR=2 
REAL_STDOUT=1 
2=open("/tmp/stderr.log") 
1=open("/tmp/stdout.log") 
echo "This goes to stdout.log" 
if ! curl doesntexist.yet; then 
    echo "Error: Unable to reach host. See stderr.log for details" 1>REAL_STDERR 
fi 
+1

由於旁邊 - 全部大寫的名字是爲操作系統或shell本身具有含義的變量指定的,而小寫名稱是爲應用程序使用而保留的。請參閱http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html,請記住,環境變量和shell變量共享一個名稱空間(分配給與現有環境變量名稱重疊的shell變量將覆蓋後者),所以命名約定必然適用於這兩者。 –

+0

謝謝,我不知道。 –

回答

3

exec這個exec當沒有給出一個命令運行的名字時會這樣做。

exec 3>&1 4>&2 2>/tmp/stderr.log >/tmp/stdout.log 

echo "This goes to stdout.log" 
echo "This goes to stderr.log" >&2 

echo "This goes directly to real stderr" >&4 

請注意,重定向是按照它們在命令行上從左到右的順序處理的。因此,&1&2被解釋爲由相同命令上的任何先前重定向修改。

請參閱the relevant POSIX spec


如果你想使用的變量名稱爲您的文件描述符(帶有自動分配的數字),你需要的bash 4.1或更高版本。在那裏,你可以這樣做:

exec {real_stderr}>&2 {real_stdout}>&1 >stdout.log 2>stderr.log 
echo "This goes stdout.log" 
echo "This goes to stderr.log" >&2 
echo "This goes to real stderr" >&$real_stderr 
+0

您需要添加有關保留舊stdout/stderr的位... – psmears

+0

@psmears,正確修改;謝謝。 –