所以我试图创建一个脚本来自动化我的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程序?
答案 0 :(得分:1)
tee
的stdout(到foo
的stdin)和重复的写入(到你的tty
字符开发)不会及时同步。你的tty比foo
更快地消耗输入,并且libc的缓冲使它更糟糕。如果您正在寻找交互式自动化,请查看expect
程序。
答案 1 :(得分:0)
如何简单地
cat input.txt ; cat input.txt | foo ;
第一部分打印输入,第二部分打印输出。
您可以选择将print语句放在代码中,以便在每次迭代时在相关输出之前打印正在处理的输入的子部分。
答案 2 :(得分:0)
以下脚本在检测到标准输入上的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
答案 3 :(得分:0)
如果您的目标程序(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')