簡體   English   中英

將標准錯誤發送到標准輸出不起作用

[英]Sending standard error to standard out not working

我在獲取將標准錯誤發送到標准輸出的命令時遇到了麻煩。 我打算將其放在cron中,但現在只是手動運行。

/home/backups/backup_scripts/backup.sh 2>&1 >> /var/log/backups/backup.log

我希望該日志文件包含任何已打印為標准輸出的消息,但是該日志文件僅顯示標准輸出,並且控制台輸出顯示了錯誤。

我在這里做錯了什么?

重定向的順序很重要。 您應該將其更改為:

/home/backups/backup_scripts/backup.sh >> /var/log/backups/backup.log 2>&1 

這會將stdout重定向到/var/log/backups/backup.log ,然后將stderr重定向到stdout(這將進入文件)。

您還可以使用以下簡短形式:

/home/backups/backup_scripts/backup.sh &>> /var/log/backups/backup.log

&>>file在語義上等效於>>file 2>&1

這是由於重定向的順序而發生的。 2>&1表示“將標准錯誤重定向到標准輸出的當前位置”。 它們從左到右進行處理,因此首先將標准錯誤重定向到當前標准輸出(仍然是終端),然后將標准輸出重定向到文件。 如果您將訂單切換為閱讀

/home/backups/backup_scripts/backup.sh >> /var/log/backups/backup.log 2>&1

它應該做你想要的。 如果您的shell是bash,則它具有一個可同時重定向標准輸出和標准錯誤的快捷方式: command &> file將它們都重定向到一個文件, command &>> file將它們都追加到一個文件。 bash手冊中也提到了這種順序依賴性

請注意,重定向的順序很重要。 例如,命令

 ls > dirlist 2>&1 

將標准輸出和標准錯誤都定向到文件目錄,同時命令

 ls 2>&1 > dirlist 

僅將標准輸出定向到文件dirlist,因為在將標准輸出重定向到dirlist之前,從標准輸出中復制了標准錯誤。

我認為對於文件描述符和重定向的工作方式存在一些誤解。 內核對系統上所有打開的文件都有一個大表,其中包含文件偏移量,狀態標志和文件本身的名稱。 然后,每個進程都有一個表,該表將文件描述符號映射到該全局表中的條目。

在進行任何重定向之前,全局表可能看起來像這樣

A: TERMINAL

進程表看起來像

0: A
1: A
2: A

因為描述符編號0、1和2分別是stdin,stdout和stderr。

然后處理2>&1重定向。 這將更改過程表,以使2包含指向與1相同的全局條目的點。但是,它們已經相同,因此沒有任何反應。

處理>> /var/log/backups/backup.log重定向時。 首先,在過程表中打開文件並將其分配給文件描述符3,使表看起來像

A: TERMINAL
B: /var/log/backups/backup.log

0: A
1: A
2: A
3: B

然后將標准輸出更改為指向新打開的文件(就像完成了1>&3一樣),因此過程表現在

0: A
1: B
2: A
3: B

請注意,2(stderr)仍指向終端。

當以其他順序進行重定向時, >> /var/log/backups/backup.log之后的表看起來相同。

0: A
1: B
2: A
3: B

然后2>&1重定向將2指向

0: A
1: B
2: B
3: B

所以現在stdout和stderr都轉到該文件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM