2010-06-28 125 views
34

我在寫腳本來備份數據庫。我有以下行:Bash腳本 - 在變量中存儲stderr

mysqldump --user=$dbuser --password=$dbpswd \ 
    --host=$host $mysqldb | gzip > $filename 

我想標準錯誤分配給一個變量,這樣它會發送一封電子郵件給我,讓我知道發生了什麼,如果出現錯誤。我找到了將stderr重定向到stdout的解決方案,但是我不能這麼做,因爲stdout已經被髮送(通過gzip)到一個文件中。我怎樣才能單獨將stderr存儲在變量$ result中?

回答

57

嘗試將stderr重定向到標準輸出,並使用$()來捕獲它。換句話說:

VAR=$((your-command-including-redirect) 2>&1) 

由於您的命令將stdout重定向的地方,它不應該有標準錯誤干擾。可能有更清晰的方式來編寫它,但這應該起作用。

編輯:

這確實工作。我測試過它:

#!/bin/bash                                           
BLAH=$((
(
echo out >&1 
echo err >&2 
) 1>log 
) 2>&1) 

echo "BLAH=$BLAH" 

將打印BLAH=err和文件log包含out

+0

我不認爲這有效。 stderr被重定向到stdout,然後被重定向到一個文件。你不能將命令的stdout重定向到一個文件,然後用stderr替換顯示的stdout – 2010-06-28 06:23:59

+0

@Michael:看我的編輯。 – 2010-06-28 06:30:04

+0

完美的作品。謝謝! – thornate 2010-06-28 08:02:26

0

dd寫到標準輸出和標準錯誤:

$ dd if=/dev/zero count=50 > /dev/null 
50+0 records in 
50+0 records out 

兩個流是獨立的,分別重定向:

$ dd if=/dev/zero count=50 2> countfile | wc -c 
25600 
$ cat countfile 
50+0 records in 
50+0 records out 
$ mail -s "countfile for you" thornate < countfile 

如果你真的需要一個變量:

$ variable=`cat countfile` 
4

你可以將stdout引用從另一個f中重定向之前保存ile數字(例如3),然後重定向標準錯誤到:

result=$(mysqldump --user=$dbuser --password=$dbpswd \ 
    --host=$host $mysqldb 3>&1 2>&3 | gzip > $filename) 

所以3>&1將文件編號3重定向到標準輸出(注意,這是之前標準輸出與管道重定向)。然後2>&3將stderr重定向到文件號3,現在它與stdout相同。最後stdout被重定向到一個管道中,但是這不會影響文件編號2和3(請注意,重定向標準輸出與gzip無關,與mysqldump命令的輸出無關)。

編輯:更新命令重定向stderr從mysqldump命令而不是gzip,我的第一個答案太快了。

8

對於猛砸任何通用的命令,你可以做這樣的事情:

{ error=$(command 2>&1 1>&$out); } {out}>&1 

常規輸出顯示正常,什麼標準錯誤用它來當$錯誤捕獲(引號,如「$錯誤」保留換行符)。要捕獲標準輸出到一個文件,只是在末尾添加一個重定向,例如:

{ error=$(ls /etc/passwd /etc/bad 2>&1 1>&$out); } {out}>&1 >output 

其分解,從課外閱讀,它:

  • 用於創建一個文件描述$出整個塊,複製標準輸出
  • 捕獲$錯誤整個命令的標準輸出(但是參見下文)
  • 命令本身標準錯誤重定向到標準輸出(其被上述捕獲),然後從塊外部標準輸出到原來的標準輸出,所以只有stderr才能獲得captu紅色
+1

在bash v3.2中不起作用:''意外的令牌'{out}'''。這個語法是否需要Bash 4? – 2013-06-18 17:58:16

+0

它在bash 4.2和4.1中運行良好,我甚至嘗試過shopts:compat32,compat31,它也可以在那裏工作,也許它是3.2中的一個bug,因爲bash在兼容模式下工作,除非兼容性只包含項目那會不會因爲4.2而破裂,而不是4.2的一部分功能......(我想大多數人使用4.2這幾天是對的?)無論如何,這是一箇舊帖子,但只是爲了清除它,它確實有效,正是我需要在屏幕上顯示正常文本時將錯誤分配給變量... :) – osirisgothra 2014-04-03 16:25:53