【问题标题】:Python does not execute scriptPython不执行脚本
【发布时间】:2019-06-11 04:13:12
【问题描述】:

我已经编写了一个 Python 代码来生成一个 shell 脚本,然后使用子进程运行该脚本。

脚本文件已创建,但是当我尝试从代码中运行时,它什么也没做。如果我尝试使用在脚本之外创建的文件运行相同的脚本,它会按预期工作。

这是我的代码:

import subprocess
import os

cwd = os.getcwd()
file_name = cwd + "/cmd_file_from_python"
fd = open(file_name,"w")
fd.write("#!/usr/local/bin/tcsh -f\n")
fd.write("echo 'PRINT FROM CMD_FILE_FROM_PYTHON'\n")
fd.close

os.chmod(file_name, 0o777)

cmd=file_name
p = subprocess.Popen(cmd,executable='/bin/ksh', shell=True, stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
(stdout,stderr) = p.communicate()
p_status = p.wait()
print "Command output : ", stdout
print "Command outerr : ", stderr
print "Command exit status/return code : ", p_status
print "================================================================"

file_name = cwd + "/cmd_file"
cmd = file_name
p = subprocess.Popen(cmd,executable='/bin/ksh', shell=True, stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
(stdout,stderr) = p.communicate()
p_status = p.wait()
print "Command output : ", stdout
print "Command outerr : ", stderr
print "Command exit status/return code : ", p_status

和输出:

Command output :
Command outerr :
Command exit status/return code :  0
================================================================
Command output :  PRINT FROM CMD_FILE

Command outerr :
Command exit status/return code :  0

这是我在代码之外创建的脚本代码:

$ cat cmd_file
#!/usr/local/bin/tcsh -f
echo 'PRINT FROM CMD_FILE'

如果我检查这两个文件,它们唯一的区别是打印:

$ diff cmd_file_from_python cmd_file
2c2
< echo 'PRINT FROM CMD_FILE_FROM_PYTHON'
---
> echo 'PRINT FROM CMD_FILE'

【问题讨论】:

  • 旁注:当您运行带有指定tcsh 的shebang 行的脚本时,为什么要明确指定executable='/bin/ksh'。当默认可执行文件启动tcsh 脚​​本时,这似乎毫无意义。似乎也没有任何理由在此处使用 shell=True,因为您没有传递带有参数的字符串,也没有在命令中执行任何与 shell 相关的操作。 shell=True 无缘无故打开安全/稳定性漏洞。
  • 对于ShadowRanger 的评论,我只能投一票,我很遗憾。叹。对于为什么要这样做,我唯一的想法是因为这样做是为了准备犯下更大的错误。只需直接调用您创建的脚本,而不是调用代理来为您运行它。

标签: python


【解决方案1】:

程序运行时您的文件为空:

fd = open(file_name,"w")
fd.write("#!/usr/local/bin/tcsh -f\n")
fd.write("echo 'PRINT FROM CMD_FILE_FROM_PYTHON'\n")
fd.close

注意fd.close 缺少调用括号;您实际上从未关闭过文件,因此文件的全部内容可能都位于 Python 的缓冲区中,并且在程序结束之前永远不会进入磁盘(当 CPython 参考解释器作为实现细节时,通过并清理全局变量,关闭副作用为您打开的文件;它可能永远不会到达另一个解释器中的磁盘)。

要修复,实际调用close。或者更好的是,切换到更安全的 with statement 方法,其中 close 是隐式的,并且是自动的,即使异常或 return 导致您提前退出代码也会发生:

with open(file_name, "w") as fd:
    fd.write("#!/usr/local/bin/tcsh -f\n")
    fd.write("echo 'PRINT FROM CMD_FILE_FROM_PYTHON'\n")
# No need to call close; file is guaranteed closed when you exit with block

【讨论】:

  • 我很困惑...为什么您提出的答案不包括修复您在评论中提到的外壳废话?
  • @EdGrimm:因为 shell 的废话根本不是 OP 问题的原因。没有意义和bad code,但与问题无关;有足够多的来源说明为什么会出现问题以及如何解决问题。
猜你喜欢
  • 2019-10-28
  • 2020-03-16
  • 2021-01-22
  • 1970-01-01
  • 1970-01-01
  • 2017-06-29
  • 1970-01-01
  • 2016-06-05
相关资源
最近更新 更多