2015-09-19 33 views
2

我試着寫,每一個命令,通過使用該行評估命令函數傳遞一個bash腳本:與STDERR/STDOUT重定向導致問題的eval命令

eval $1 2>&1 >>~/max.log | tee --append ~/max.log 

的情況下的一個例子它不起作用是當試圖評估一個cd命令:

eval cd /usr/local/src 2>&1 >>~/max.log | tee --append ~/max.log 

導致問題的部分是| tee --append〜/ max.log部分。任何想法爲什麼我遇到問題?

+0

什麼不行?它沒有cd到目錄中? – edi9999

+0

cd不能很好地處理管道,'cd folder |例如ls'不會將您置於「文件夾」 – edi9999

+0

您可以將main函數移動到一個函數中並使用'tee'作爲函數輸出嗎?像'function mymain {...}'和'mymain 2>&1 | tee -append〜/ max.log'?或者使用'script'之類的東西? –

回答

4

bash(1)手冊頁:

管道中的每個命令被作爲一個單獨的處理中執行(即,在一個子shell)。

因此,cd不能在管道使用時改變當前shell的工作目錄。要解決這個限制,通常的做法是與其他命令組cd和重定向組命令的輸出:

{ 
    cd /usr/local/src 
    command1 
    command2 
} | tee --append ~/max.log 

沒有破壞你現有的設計,你可以代替你的過濾函數處理cd專門:

# eval all commands (will catch any cd output, but will not change directory): 
eval $1 2>&1 >>~/max.log | tee --append ~/max.log 
# if command starts with "cd ", execute it once more, but in the current shell: 
[[ "$1" == cd\ * ]] && $1 

根據您的情況,這可能是不夠的:您可能必須處理修改環境或shell變量,如sethistoryulimit其他命令,readpushdpopd。在這種情況下,重新考慮該程序的設計可能是一個好主意。

+0

+1。如果使用這些設置,還需要特殊情況設置或聲明envvar或shell變量。包括'read'等,''*''和/或shell選項的'set'。或者改變'ulimit'設置。或「歷史」。也許我錯過了更多。更容易正確重定向。 –

+0

@ dave_thompson_085:謝謝,我已經使各自的陳述更一般,包括修改環境或shell變量的所有內容。 –