我正在开发一个作业服务器,学生可以在其中上传他们的程序解决方案。它应该适用于多种编程语言。为了测试程序,我正在执行一个 shell 脚本并将测试用例和文件作为参数传递:
printf '10\n3\n+\n' | ./eval_python steps.py
它的工作,这不是问题。对于输出,我得到类似的东西:
使用 shell 脚本运行 python 脚本:
$ How much steps? Step size? Counting up (+) or down (-) ? Step 0: 3
$ Step 1: 6
$ Step 2: 9
$ Step 3: 12
$ Step 4: 15
$ [..]
这种格式使评估变得非常困难,也可能让学生感到困惑,因为他们看不到输入(当您从 shell 运行 python 脚本时,输出如下例所示)。对于评估,困难在于,学生不能像在这个解决方案中那样命名他们的输入,如果他们只问 Steps?
而不是 How much steps?
也可以.
直接从 shell 运行 python 脚本:
$ How much steps? 10
$ Step size? 3
$ Counting up (+) or down (-)? +
$ Step 0: 3
$ Step 1: 6
$ Step 2: 9
$ Step 3: 12
$ Step 4: 15
$ [..]
有没有一种方法可以将输入组合到输出中?或者我可以解决这个问题的其他想法?
非常感谢!
最佳答案
自动处理用户提示比看起来更难,不幸的是 printf
还不足以完全模拟它。如果你不想接触 python 代码本身,你可能不得不使用 expect
,这是一种为处理交互式程序而编写的脚本语言。
如果它不在您的系统上(很可能),请使用 sudo apt install expect
或 sudo yum install expect
安装它。我在这里拼凑的这个粗糙的东西应该能够满足你的要求:
expect_script.exp
#!/usr/bin/expect -f
set steps [lindex $argv 0]
set size [lindex $argv 1]
set plus_or_minus [lindex $argv 2]
set script_name [lindex $argv 3]
spawn python3 ${script_name}
# Or `spawn eval_python ${script_name}`, as long as it is a python 3 interpreter as well
# If it is python 2, all `input` calls within need to be changed to `raw_input`
expect "steps"
send -- "${steps}\r"
expect "size"
send -- "${size}\r"
expect "Counting"
send -- "${plus_or_minus}\r"
expect eof
然后这样调用它:
./expect_script.exp 10 3 + steps.py
如果您对语法或语义有疑问,请随时提问。不过别抱太大希望(哈哈),我不太擅长奇怪的 Unix 工具。
使用可变数量的参数进行编辑:
expect_script.exp
#!/usr/bin/expect -f
spawn python3 [lindex $argv 0]
# Or `spawn eval_python [lindex $argv 0]`, as long as it is a python 3 interpreter as
# well. If it is python 2, all `input` calls within need to be changed to `raw_input`.
set sleep_time 0.1 # using `sleep` to wait for the next prompt is, usually,
# a very bad idea. Maybe you can control your input calls
# by including unique identifiers in them, such as 1, 2, 3..
# and using `except` to properly wait for them?
for {set i 1} {$i < [llength $argv]} {incr i 1} {
sleep $sleep_time
send -- [lindex $argv $i]\r
}
expect eof
调用顺序已经改变,因为我们需要在发送参数之前调用我们的 python 脚本:
./expect_script.exp test.py 10 3 +
或者,更改 python 脚本以接受命令行参数。如果您计划执行任务自动化,或重用代码,或只是一般 - 命令行参数几乎总是比用户提示更好的主意。原生python ArgParse
模块非常好,即使您不想重写当前代码,研究它并在将来尝试应用它仍然值得。
关于python - shell脚本,使用输入执行程序并在输出中保存输入与输出结合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47831176/