在任何符合 POSIX 标准的 shell(包括 ksh)中,与 Python 的 input() 等效的是 read。
因此,在 Python 方面:
p = subprocess.Popen(['yourscript'], stdin=subprocess.PIPE)
p.communicate(arg1 + '\n' + arg2 + '\n')
...在外壳方面:
IFS= read -r arg1
IFS= read -r arg2
清除IFS 并传递-r 使解释更接近字面意思,因此在Python 端包含两个字符\n 的字符串不会被解释为仅包含一个换行符,并避免在事务的 shell 端自动去除尾随空格。
如果您的字符串可以包含换行符等,那么您需要从 Python 程序中使用尾随 NUL 字符发出它:
p = subprocess.Popen(['yourscript'], stdin=subprocess.PIPE)
p.communicate(arg1 + '\0' + arg2 + '\0')
...从 shell 端读取它:
IFS= read -r -d '' arg1
IFS= read -r -d '' arg2
这比您要求的 input() 更强大,因为它可以处理任意 C 字符串。 (Python 的原生字符串是 Pascal 风格的,因此可以包含文字 NUL;ksh 和任何其他现有的 POSIX 风格的 shell 都不能在不使用非常不愉快的技巧的情况下处理这些字符串的所有值)。
也就是说,在命令行或通过环境传递参数通常会更好,而不是按照您的建议从标准输入中读取。因此:
subprocess.Popen(['yourscript', arg1, arg2], shell=False)
...其中arg1 和arg2 是您希望传递的内容的变量,然后可以在脚本中引用$1 和$2。或者,变量可以通过环境传递:
subprocess.Popen(['yourscript'], shell=False, env={
'arg1': arg1,
'arg2': arg2,
})
...在这种情况下,ksh 脚本可以直接引用 "$arg1" 和 "$arg2" 的值。
考虑查找您的脚本当前运行的位置:
read arg1
并将其替换为
[[ $arg1 ]] || read arg1
...只有在没有提供其他值的情况下(如通过环境),它才会从标准输入中读取来自arg1 的值。这使得您的脚本仍然像往常一样通过命令行提示用户以交互方式使用,但也提供了直接从环境中读取内容的替代行为。