python - shell脚本,使用输入执行程序并在输出中保存输入与输出结合

标签 python linux bash shell

我正在开发一个作业服务器,学生可以在其中上传他们的程序解决方案。它应该适用于多种编程语言。为了测试程序,我正在执行一个 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 expectsudo 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/

相关文章:

python - 如何在 Centos 6.8 上安装 OpenCV 3?

c++ - 关于编译程序使用外部库的问题

linux - Mac OS X 上的 xcode 构建脚本无法工作,因为未找到 env 节点/登录也无法工作

linux - 使用别名激活 virtualenv

python - 更新表中数据的正确方法?

c++ - 将 Python 持久层嵌入到 C++ 应用程序中——好主意吗?

Python Lambda 函数使用

python - ggplot 中的 ggsave() for python 不保存

linux - 找到文件后如何复制

linux - 在Bash中,Kill后台函数不会杀死内部进程,为什么它们有不同的pid?