2012-10-04 24 views
3

我在寫一個應該對用戶「透明」的bash腳本。它從用戶那裏讀取命令並攔截它們,只允許其中一些命令由bash執行,具體取決於某些標準。它(基本上)是這樣工作的:僅當命令失敗時才重定向stdout?

while true; do 
    read COMMAND 
    can_be_done $COMMAND 
    if [ $? == 0 ]; then 
     eval $COMMAND 
     if [ $? != 0 ]; then 
     echo "Error: command not found" 
     fi 
    fi 
done 

問題是,當命令失敗時,您還可以將東西打印到控制檯。但是,如果我保持在一個變量的結果,只打印它時,它不會失敗,就像這樣:

RESULT=$(eval $COMMAND) 

然後還有另外一個問題:在特殊格式丟失(例如,「LS --color 「不再顯示顏色)

我的問題是:如果成功,是否有一種方法可以將命令打印到標準輸出,但如果失敗則會將其打印到/ dev/null?

+0

顏色不會丟失對我來說。 RESULT = $(eval ls --color); echo「$ RESULT」 – dogbane

+0

@dogbane'ls --color'表示'ls --color = always'。通常'ls'被別名爲'ls --color = auto'或'ls --color = tty',即它只在stdout是終端('isatty')時纔打印顏色代碼。 –

+0

我剛剛意識到,你是對的!但由於某些原因,「ls --color = auto」(這是用於ls的別名)。我刪除了「= auto」,現在用這種方法顯示顏色。 –

回答

5

你真的需要第二部分,用錯誤信息替換命令的輸出嗎? Linux命令打印自己的錯誤消息,這不一定是「找不到命令」。您會隱藏真正的錯誤(權限被拒絕,文件未找到,內存不足,段錯誤等),並且經常出現錯誤信息(找不到命令)。

如果刪除檢查,可以簡化這樣循環的東西:

while true; do 
    read -e COMMAND 
    if can_be_done "$COMMAND"; then 
     eval "$COMMAND" 
    fi 
done 
  • read -e使用的readline獲取命令,使提示了很多殼狀(&箭頭更;例如,↓)。
  • command; if [ $? == 0 ]; then更習慣寫成if <command>; then
  • 引用確保特殊字符和空白處理正確。
+0

感謝您的建議。正如你可能知道的,我對bash腳本非常陌生! –

+0

或'can_be_done'$ COMMAND「&& $ COMMAND' – punund

-1

假設該命令不運行,你可以做到這一點非常昂貴:

test `ls /mooo 2>/dev/null` || echo moo not found 

測試將返回true只有在命令退出時0,在這種情況下,LS是命令。你可以在if語句中已經把這個太像這樣:

if [ `ls /moo 2>/dev/null` ];then 
    echo moo is a folder 
fi 
+1

'if ls;然後'檢查ls的退出代碼。 ''如果['ls']''等於''if [-n'ls']'';它檢查ls沒有輸出任何東西。 –

+0

我有點急躁的回答。這是完全錯誤的。 –

1

我強烈認爲,您應該做到這一點。如果您不想看到輸出,請將其重定向至/dev/null。如果您確實想要查看錯誤,請不要重定向stderr。如果您使用的是在stdout而不是stderr上打印錯誤消息的程序,請修復程序!錯誤消息屬於stderr。請注意,這意味着你的程序是破的,因爲它應該閱讀:

echo "Error: command not found" >&2 

我不知道這是否是第一條規則,但它肯定是屬於前10名,這可能是最經常違反規則:Error messages belong on stderr。在stdout上打印錯誤消息的程序已損壞。