[英]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.