![](/img/trans.png)
[英]How do I run a terminal command at the same time as executing a C program from terminal
[英]How do I pipe to terminal and to program at the same time in bash
所以我試圖制作一個腳本來自動化我的C程序的測試(進出),我試圖讓輸入留在屏幕上,所以我知道發生了什么。
到目前為止我只嘗試過管道:
foo < input.txt
和
cat input.txt | tee dev/tty |foo
這還沒有為我工作。
所以假設輸入文件看起來像:
123
321
理想情況下,IO看起來像:
Input: 123
Echo: 123
Input: 321
Echo: 321
但它變成了
123
321
Input:
Echo: 123
Input:
Echo: 321
我可以使用其他方法來測試我的C程序嗎? 我可以在哪里開球可以達到這樣的效果? 我是否可以編寫另一個可以實現類似功能的C程序?
tee
的stdout(對foo
標准輸入)和重復的寫入(對你的tty
字符開發)不及時同步。 你的tty比foo
更快地消耗輸入,並且libc的緩沖使它更糟糕。 如果您正在尋求交互式自動化,請查看expect
計划。
怎么樣簡單
cat input.txt ; cat input.txt | foo ;
第一部分打印輸入,第二部分打印輸出。
您可以選擇將print語句放在代碼中,以便在每次迭代時在相關輸出之前打印正在處理的輸入的子部分。
當以下腳本檢測到它在標准輸入的read()
系統調用中被阻塞時,會向程序輸入輸入,並在標准輸出上打印相同的文本。 結果,程序的輸出和標准輸入的內容被適當地交錯。
用法:
$ simulate_user_input
program args ...
例:
$ cat > test_script <<'END'
#!/usr/bin/env bash
echo -n "First name: "
read -r first_name
echo -n "Second name: "
read -r second_name
echo "Hello $first_name $second_name"
END
$ chmod +x test_script
$ ./simulate_user_input ./test_script <<< $'John\nSmith'
First name: John
Second name: Smith
Hello John Smith
simulate_user_input
#!/usr/bin/env bash
if [ $# -eq 0 ]
then
cat<<END
Usage:
$(basename "$0") command args ...
END
exit 1
fi
#set -x
if [ "$1" == "-simulate" ]
then
app_stdin="$2/app_stdin"
user_stdin="$2/user_stdin"
user_stdout="$2/user_stdout"
exec > "$app_stdin" 3< "$user_stdin" 4> "$user_stdout"
while read -r -n 6 -t 0.1 line
do
if [[ $line == 'read(0' ]]
then
read -u 3 -r line || { cat > /dev/null; exit 0; }
echo "$line" >&4
echo "$line"
fi
done
exit 0
fi
cleanup()
{
rm -rf "$tmpdir"
if [ "$(jobs -r|wc -l)" -ne 0 ]
then
kill %1 %2
fi
}
tmpdir="$(mktemp -d)"
trap "cleanup" EXIT
app_stdin="$tmpdir/app_stdin"
user_stdin="$tmpdir/user_stdin"
user_stdout="$tmpdir/user_stdout"
mkfifo "$app_stdin"
mkfifo "$user_stdin"
mkfifo "$user_stdout"
cat "$app_stdin"|strace -e read -o "|$0 -simulate '$tmpdir'" "$@" &
cat < "$user_stdout" &
cat > "$user_stdin"
wait
如果您的目標程序( foo
)保證為每行輸入輸出一行,這是一個可以執行此操作的Python 2程序:
#!/usr/bin/env python
import sys, subprocess
sp = subprocess.Popen(sys.argv[1:], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
for input_line in sys.stdin:
print('Input: ' + input_line.rstrip('\r\n'))
sp.stdin.write(input_line)
sp.stdin.flush()
output_line = sp.stdout.readline()
print('Output: ' + output_line.rstrip('\r\n'))
如果將其保存為tee.py
,則可以使用它進行測試
echo -e '123\n321' | tee.py cat -
對於通用的可重復測試,或
echo -e '123\n321' | tee.py foo
為您的具體例子。
PS:如果你想在Python 3中使用它,你必須改變兩行:
sp.stdin.write(input_line.encode('utf-8'))
和
output_line = sp.stdout.readline().decode('utf-8')
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.