python3 subprocess.run报错:[Errno 2] No such file or directory:(shell=True,[bin, arg, arg, ...]传列表方式)
传列表的方式,函数就会直接把整个串当成一个命令(注意是命令,不是参数),比如根据上面示例,会把。传列表的方式,两个必须用一个,且只能用一个,两个一起加会冲突。)找这个命令的文件,发现找不到,就报错了。当成一个命令(可执行文件),去系统目录(比如。当成命令,去系统目录找这个可执行文件,而把。弄了个函数,去重启docker容器,执行。当作命令的参数,去执行。传列表的方式,即传个。
·
文章目录
- 问题复现
- 测试(Python 3.8.10)
- 测试不加shell=True参数,也不用[bin, arg, arg, ...]传列表的方式分别执行ls -l和ll -a和docker -v命令,发现都不能执行成功
- 测试加shell=True参数,不用[bin, arg, arg, ...]传列表的方式分别执行ls -l和ll -a和docker -v命令,发现只有ll提示找不到命令,其余都能执行成功
- 测试不加shell=True参数,用[bin, arg, arg, ...]传列表的方式分别执行ls -l和ll -a和docker -v命令,发现只有ll提示找不到命令,其余都能执行成功
- 测试加shell=True参数,并且用[bin, arg, arg, ...]传列表的方式分别执行ls -l和ll -a和docker -v命令,发现三者输出都不正常(说明shell=True和用[bin, arg, arg, ...]传列表的方式,只能二者取其一)
- 原因
- 解决办法
- 参考文章
问题复现
弄了个函数,去重启docker容器,执行docker restart xxx
,发现老不行,提示:No such file or directory: 'docker restart xxx'
:
后来发现加上shell=True
就可以了。。。
def execute_docker_restart(container_name):
"""
重启 container_name 容器
"""
try:
# 构建命令
command = f'docker restart {container_name}'
# command = f'/usr/bin/docker restart {container_name}' # 也不行
# 执行命令并获取输出
# 运行提示 No such file or directory: 'docker restart kyai_kykj'
# result = subprocess.run(
# command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
result = subprocess.run(
command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
# 打印脚本的输出
print(f"[{command}] 标准输出:", result.stdout)
# 打印脚本的错误输出
print(f"[{command}] 标准错误输出:", result.stderr)
# 执行成功,返回True,否则返回False
return result.returncode == 0
# except subprocess.CalledProcessError as e:
except Exception as e:
# 执行失败,返回False
print(f'[{command}]执行失败:[{e}]')
return False
测试(Python 3.8.10)
测试不加shell=True参数,也不用[bin, arg, arg, …]传列表的方式分别执行ls -l和ll -a和docker -v命令,发现都不能执行成功
import subprocess
def execute_command(command):
"""
执行命令
"""
print(f'\n+++ execute command: [{command}]')
try:
# 构建命令
result = subprocess.run(
command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
# 打印脚本的输出
print(f"[{command}] 标准输出:", result.stdout)
# 打印脚本的错误输出
print(f"[{command}] 标准错误输出:", result.stderr)
# 执行成功,返回True,否则返回False
return result.returncode == 0
# except subprocess.CalledProcessError as e:
except Exception as e:
# 执行失败,返回False
print(f'[{command}]执行失败:[{e}]')
return False
if __name__ == "__main__":
execute_command('ls -l')
execute_command('ll -a')
execute_command('docker -v')
运行结果:
测试加shell=True参数,不用[bin, arg, arg, …]传列表的方式分别执行ls -l和ll -a和docker -v命令,发现只有ll提示找不到命令,其余都能执行成功
import subprocess
def execute_command(command):
"""
执行命令
"""
print(f'\n+++ execute command: [{command}]')
try:
# 构建命令
result = subprocess.run(
command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
# 打印脚本的输出
print(f"[{command}] 标准输出:", result.stdout)
# 打印脚本的错误输出
print(f"[{command}] 标准错误输出:", result.stderr)
# 执行成功,返回True,否则返回False
return result.returncode == 0
# except subprocess.CalledProcessError as e:
except Exception as e:
# 执行失败,返回False
print(f'[{command}]执行失败:[{e}]')
return False
if __name__ == "__main__":
execute_command('ls -l')
execute_command('ll -a')
execute_command('docker -v')
测试不加shell=True参数,用[bin, arg, arg, …]传列表的方式分别执行ls -l和ll -a和docker -v命令,发现只有ll提示找不到命令,其余都能执行成功
import subprocess
def execute_command(command):
"""
执行命令
"""
print(f'\n+++ execute command: [{command}]')
try:
# 构建命令
result = subprocess.run(
command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
# 打印脚本的输出
print(f"[{command}] 标准输出:", result.stdout)
# 打印脚本的错误输出
print(f"[{command}] 标准错误输出:", result.stderr)
# 执行成功,返回True,否则返回False
return result.returncode == 0
# except subprocess.CalledProcessError as e:
except Exception as e:
# 执行失败,返回False
print(f'[{command}]执行失败:[{e}]')
return False
if __name__ == "__main__":
execute_command(['ls', '-l'])
execute_command(['ll', '-a'])
execute_command(['docker', '-v'])
测试加shell=True参数,并且用[bin, arg, arg, …]传列表的方式分别执行ls -l和ll -a和docker -v命令,发现三者输出都不正常(说明shell=True和用[bin, arg, arg, …]传列表的方式,只能二者取其一)
import subprocess
def execute_command(command):
"""
执行命令
"""
print(f'\n+++ execute command: [{command}]')
try:
# 构建命令
result = subprocess.run(
command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
# 打印脚本的输出
print(f"[{command}] 标准输出:", result.stdout)
# 打印脚本的错误输出
print(f"[{command}] 标准错误输出:", result.stderr)
# 执行成功,返回True,否则返回False
return result.returncode == 0
# except subprocess.CalledProcessError as e:
except Exception as e:
# 执行失败,返回False
print(f'[{command}]执行失败:[{e}]')
return False
if __name__ == "__main__":
execute_command(['ls', '-l'])
execute_command(['ll', '-a'])
execute_command(['docker', '-v'])
原因
如果不加shell=True
参数,也不用[bin, arg, arg, ...]
传列表的方式,函数就会直接把整个串当成一个命令(注意是命令,不是参数),比如根据上面示例,会把docker -v
当成一个命令(可执行文件),去系统目录(比如/usr/bin
)找这个命令的文件,发现找不到,就报错了。。。
如果加上shell=True
参数,或者用[bin, arg, arg, ...]
传列表的方式,即传个['docker', '-v']
,就会把docker
当成命令,去系统目录找这个可执行文件,而把-v
当作命令的参数,去执行。
解决办法
不能既不加shell=True
参数,也不用[bin, arg, arg, ...]
传列表的方式,两个必须用一个,且只能用一个,两个一起加会冲突。
参考文章
更多推荐
已为社区贡献14条内容
所有评论(0)