Linux python Popen报错:FileNotFoundError: [Errno 2] No such file or directory & kill() 后进程仍然运行

遇到一个坑

   从 window 环境的 Popen 复制粘贴到 Linux 使用,竟然无法使用,报错 No such file or directory ,把我搞郁闷了,完全一样的 code,怎么 linux 上就找不到文件了?

   原来,linux 上 Popen 使用字符串命令,Popen 需要加上一个参数 shell=True

报错

Traceback (most recent call last):
  File "case.py", line 138, in <module>
    __tl.do_test()
  File "case.py", line 119, in do_test
    tp.start()
  File "case.py", line 65, in start
    self.__proc = Popen(self.__cmd)
  File "/usr/lib/python3.8/subprocess.py", line 854, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "/usr/lib/python3.8/subprocess.py", line 1702, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'python do_test.py 3'

官方文档

args is required for all calls and should be a string, or a sequence of program arguments. Providing a sequence of arguments is generally preferred, as it allows the module to take care of any required escaping and quoting of arguments (e.g. to permit spaces in file names). If passing a single string, either shell must be True (see below) or else the string must simply name the program to be executed without specifying any arguments.

If shell is True, the specified command will be executed through the shell. This can be useful if you are using Python primarily for the enhanced control flow it offers over most system shells and still want convenient access to other shell features such as shell pipes, filename wildcards, environment variable expansion, and expansion of ~ to a user’s home directory. However, note that Python itself offers implementations of many shell-like features (in particular, glob, fnmatch, os.walk(), os.path.expandvars(), os.path.expanduser(), and shutil).

第二个大坑

   如上面官方文档所述,如果 shell=True ,那么会通过 shell 来启动进程。这意味着,一次 Popen 会启动两个进程,一个 shell 进程,一个命令进程。然后 Popen 返回的 pid 是 shell 进程的 pid,这会导致 Popen.kill() 等函数不起作用,进程还在正常运行,所以一定要使用参数列表的形式启动,不要通过命令行的形式,不要使用 shell=True

第三个坑

   上面虽然解决了 kill() 不掉真实进程的问题,但是还有一坑。如何把一个命令行字符串转换成 list[str] ,使用 str.split() ?这是不行的,如果命令行里有引号之类的就会有问题。自己实现一个函数?可以,不过自己写的总是怕考虑不全的地方。好在 python 官方有词法分析器的库 shlex ,只需要 shlex.split() 就可以获得我们想要的格式了,Python Library - shlex

参考

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值