2014-07-19 53 views
1

只是爲了好玩,我想將終端中的所有輸出文本管到espeak。例如,在設置完成後,我應該能夠輸入echo hi,並聽到「hi」說話,或者ls,並聽取我列出的目錄內容。鉤住bash中的所有命令輸出

唯一有前途的方法來捕獲輸出到目前爲止,我發現就是從這裏開始:http://www.linuxjournal.com/content/bash-redirections-using-exec

這是我到目前爲止有:

npipe=/tmp/$$.tmp 
mknod $npipe p 
tee /dev/tty <$npipe | espeak & 
espeakpid=$! 
exec 1>&- 
exec 1>$npipe 
trap "rm -f $npipe; kill $espeakpid" EXIT 

它的工作原理(也打印了一堆「完成「工作),但創建命名管道,刪除陷阱和打印輸出tee都顯得有點混亂。有一種更簡單的方法嗎?

+1

只有掛鉤所有命令輸出很容易與'exec>>(tee bash.log)'。但是正確處理終端,IPC(無需填寫文件)等。以上是正確的方法。 – jm666

+0

@ jm666謝謝,有沒有辦法用管道而不是文件重定向? – jozxyqk

回答

2

這是一種方式:

exec > >(exec tee >(exec xargs -n 1 -d '\n' espeak -- &>/dev/null)) 

如果你希望能夠恢復回原來的輸出流:

exec 3>&1 ## Store original stdout to fd 3. 
exec 4> >(exec tee >(exec xargs -n 1 -d '\n' espeak -- &>/dev/null)) ## Open "espeak" as fd 4. 
exec >&4 ## Redirect stdout to "espeak". 
exec >&3 ## Redirect back to normal. 
  • 我用xargs -n 1因爲espeak達到EOF直到沒有做任何事情,所以我們召喚它每行一個實例。這當然可以定製,但你的答案是。當然,while read循環也可以作爲此選項。
  • 我也使用exec進行過程替換,以確保我們擺脫不必要的子殼體。
0

好像它比這樣更容易 - 我只是測試這一點,它的工作原理:

$ echo "these are not the droids you are looking for" | espeak --stdin 

--stdin標誌是關鍵。從espeak的手冊頁:

--stdin 
      Read text input from stdin instead of a file 

如果你想聽到的是一個很長的輸出,我想你可以使用xargs如果碰上參數列表太長錯誤.. 。

+0

我很舒服地管道espeak(如我已經在我的例子)。問題我讓它捕獲bash shell中任何命令的輸出,也不會干擾輸出本身。例如'bash | tee/dev/tty | espeak',不幸的是這創造了一個我更喜歡避免的新殼。 – jozxyqk