2011-07-21 49 views
1

我有一個小程序,讓我們稱之爲「程序」,它具有「正常」行爲。它從stdin獲取信息(通常由用戶在鍵盤中輸入)並通過stdout/stderr打印出來。我想自動化一個進程,因此將stdout/stderr重定向到「我的小bash腳本」(也可能是C/C++中的另一個程序)。它將它作爲標準輸入並對其進行過濾。這意味着刪除不重要的信息..並添加由bash腳本本身生成的更多信息。輸出顯示在屏幕上(由echo命令打印出來)。bash - 將第二個腳本的特定輸出重定向回第一個程序的stdin?

這是工作迄今:

program --verbose 2>&1 | ./mylittlebashscript.sh 

方案:

stdin  +---------------+    +---------------+ 
--------->|    |--stdout--+-->|  my  |-->screen 
      | program |   | | little  | 
      |    |--stderr--| | bash script | 
      +---------------+    +---------------+ 

現在我想更進一步: 程序期望從中我想通過自動給用戶輸入我的小bash腳本。例如,它會提示用戶輸入特定文件的路徑。路徑由我的小bash腳本知道,bash腳本知道程序何時等待輸入(因爲要打印的最後一行包含「greped」)。如何將一些信息從我的bash腳本中退出?我不想回退所有的stdout,因爲只需要在屏幕上顯示幾個信息,程序就不會喜歡這個輸出。

新方案:

(stdin?) +---------------+    +---------------+ (stdout?) 
-------+->|    |--stdout--+-->|  my  |-->screen 
     | | program |   | | little  | 
     | |    |--stderr--+ | bash script |----+(maybe 
     | +---------------+    +---------------+ | stderr?) 
     |              | 
     +------------------------------------------------------+ 

在我不是很熟悉Linux卻時刻。我想有可能與貓,fifos,發球臺和管道/重定向工作。不幸的是,到目前爲止我還沒有實現它。

我真的很高興有一個小例子! 非常感謝!

乾杯 馬蒂亞斯

PS:我覺得這個線程相關:how to redirect stdout of 2nd process back to stdin of 1st process?

編輯: 好,爲fruther解釋我把我的測試文件從我的測試機:

我用另一批文件替換「程序」input.sh

#!/bin/bash 
echo "input.sh: give me input, waiting for input 1" 
read x 
echo $x 
echo "input.sh: give me input, waiting for input 2" 
read x 
echo $x 

而且我得到的第二個( 「mylittlebashscript.sh」),現在叫inter.sh工藝:

#!/bin/bash 
echo "inter.sh: start" 
while read line ; do 
    echo "inter.sh: line>$line" 
    notfound=$(echo $line | grep "waiting") 
    if [[ "$notfound" ]]; then 
    echo "inter.sh: input sh seems to wait for input! putting something in the fifo" 
    #echo "banana" > testfile 
    #echo "I am the stderr" >&2 
    fi 

done 
echo "inter.sh: end" 
exit 

回答

2

另外一個expect式的軟件工具將empty

http://empty.sourceforge.net

+0

看起來很有趣。你用它嗎?不幸的是我找不到它的手冊頁。我想知道像f,w和s這樣的命令行參數。當您只輸入「空白」和「腳本」,「手動」或其他內容時,很難在搜索引擎上找到好的結果。但是,非常感謝! – matthias

+0

好吧,只需輸入「空白」即可打印使用情況 - 這對我來說仍然很神祕。我試圖爲自己的input.sh bash腳本編寫自己的空腳本,但它失敗了:'empty:數據流是空的。關鍵詞未找到。超時退出.'。我在哪裏嘗試「等待」,「輸入」等幾件事情。 – matthias

+0

取得了一些進展。我不知道我是否忘記了'chmod + x emptyscript.sh' ..另一個問題是,似乎我必須將'fifo_in和fifo_out'文件'rm -f'。 – matthias

3

你嘗試,作爲一個答案線程您鏈接狀態:

mkfifo fifo 
program --verbose < fifo 2>&1 | ./mylittlebashscript.sh | tee fifo 

也許,你應該讓你的腳本打印出一些文字,等待輸入,以避免陷入生活的等待循環之前..

+0

謝謝你的提示。不幸的是我沒有得到這個工作。我用我的兩個測試文件編輯了我的文章。我認爲在你的例子中,我還把所有我回顯給「程序」的標準輸入(如果它正在工作)。但事情是......我想在屏幕上帶些東西......以及其他東西回到「程序」的標準輸入。也許我可以在stderr中加入stdout和somethin?謝謝! – matthias

+0

我現在擁有的是:'./input.sh < fifo 2&> 1 | ./inter.sh 2> fifo' 我想我會更近! :D – matthias

+0

好吧,所以這也不適合我;只有在它的小例子中。看起來fifo只是在程序打印出行後立即讀取,並且需要一些舊的(??)內容或空的內容才能繼續。或者,也許有人稱我的批處理文件中的程序寫入stderr?我也試過這樣的東西:'./input.sh < fifo 2&> 1 | ./inter.sh 2>/dev/null'和'echo「foobar」>&fifo'在我的shell腳本中。這也是行不通的。事後'cat fifo'給了我正確的輸出。有沒有btw一個選項來手動刷新緩衝區?不會認爲這不是微不足道的... – matthias

2

這聽起來像expect工作!使用expect腳本,您可以從expect腳本啓動程序,該腳本充當一個封裝器,用於偵聽stdout中的某些模式,並將相應內容輸入到stdin中作爲響應。例如,可以回答您的input.sh腳本的摘錄:

#!/usr/bin/expect -f 

spawn input.sh 
expect ".+input 1" 
send "something cool\r" 
expect ".+input 2" 
send "also cool\r" 
expect eof 
+0

謝謝!這似乎是一個不錯的解決方案。仍然可以過濾程序的輸出嗎?我猜你可以添加另一個管道到另一個bash腳本。問題是我正在使用一個Linux live CD(systemrescuecd.org),我不想添加安裝過程。但我也在創建一個個性化的磁盤,所以這可能是一個選項。至少它似乎是一個偉大的工具。 – matthias

+0

我覺得我不夠先進。我下載了tcl和期望的源代碼,將它們解壓縮到/ usr/local/src中,然後運行.configure,make和make install。沒有錯誤,但我沒有得到它的運行。也許有一個非常簡單的解決方案,而不需要額外的軟件(我現在更喜歡這個軟件)。 – matthias

2

您可能還需要考慮這種類型任務的客戶端/服務器模型。

參見:BASH: Best architecture for reading from two input streams

在一般筆記,如果input.sh標準輸入不是終端(但是從FIFO而重定向),你必須從控制終端設備/dev/tty明確讀使能/獲取用戶輸入。

read x < /dev/tty # in input.sh 

./input.sh < fifo 2>&1 | ./inter.sh 2>fifo 
+0

好的,謝謝你的提示。 「程序」是不是可以從標準輸入讀取,而是直接從/ dev/tty讀取? – matthias

0

也許還玩弄下面的方法,如果您的自動用戶輸入的要求不是太複雜。

#!/bin/bash 
# input.sh 
echo "input.sh being busy ..." 
sleep 10 
echo "input.sh: give me input, waiting for input 1" 
read x #</dev/tty 
echo $x 
echo "input.sh: give me input, waiting for input 2" 
read x #</dev/tty 
echo $x 
echo "input.sh continuing ..." 


(
echo a 
sleep 1 
echo b 
sleep 1 
exec 1>/dev/tty # redirect anything that would go to stdout/pipe to the screen 
ls 
#./mylittlebashscript.sh 
#./inter.sh 
) | ./input.sh # do not read from /dev/tty in input.sh 
1

這裏是一個小片段empty在腳本猛砸簡單telnet會話。

# http://empty.sourceforge.net 
cd empty-0.6.18b && man ./empty.1 
empty -h 
empty -f -L >(tee empty.log) telnet 
empty -l 

empty -s <<EOF 
display 
status 
help 
quit 
EOF 

empty -k 
cat empty.log 
相關問題