SSH环境下Python使用Popen执行含INPUTS变量的ls命令问题
正确使用subprocess.Popen执行ls命令检查目录文件状态
先帮你梳理下代码里的几个关键问题:
- 当设置
shell=True时,如果你传的是列表形式的参数(比如['ls', '-lh', INPUTS]),shell会把整个列表当成一个完整的命令字符串去执行——这相当于在终端输入带引号的"ls -lh /home/...",shell根本找不到这个命令,自然拿不到正确结果。 - 你后来尝试的
cmd = 'ls -lh INPUTS'没有把变量INPUTS的值替换进去,shell会把INPUTS当成一个字面量的目录名,而不是你定义的那个绝对路径。
下面给你两种正确的实现方式:
方式一:不使用shell=True(推荐,更安全)
这种方式不需要启动shell,直接把命令和参数拆成列表传入,避免shell注入风险,也更符合subprocess的最佳实践:
import subprocess INPUTS = '/home/username/WinterResearch/Inputs' # 直接传入命令+参数的列表,同时捕获stdout和stderr方便排查问题 process = subprocess.Popen( ['ls', '-lh', INPUTS], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True # 直接返回字符串,无需手动decode字节流 ) stdout, stderr = process.communicate() # 打印目录内容 print("目录文件状态:") print(stdout) # 检查命令是否执行成功 if process.returncode != 0: print(f"执行出错:{stderr}")
方式二:使用shell=True(不推荐,除非必须)
如果你因为某些原因一定要用shell=True,需要把命令写成完整的字符串,并且把变量INPUTS的值代入进去(记得给路径加引号,避免路径含空格时出错):
import subprocess INPUTS = '/home/username/WinterResearch/Inputs' # 用f-string把变量替换到命令字符串里 cmd = f'ls -lh "{INPUTS}"' process = subprocess.Popen( cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True ) stdout, stderr = process.communicate() print("目录文件状态:") print(stdout) if process.returncode != 0: print(f"执行出错:{stderr}")
额外建议:用Python内置模块替代ls命令
其实用Python自带的pathlib或者os模块来检查文件状态更符合Python风格,不需要调用外部命令,灵活性也更高:
from pathlib import Path INPUTS = Path('/home/username/WinterResearch/Inputs') # 先检查目录是否合法 if not INPUTS.exists() or not INPUTS.is_dir(): print(f"错误:目录 {INPUTS} 不存在或不是目录") else: print("目录文件状态:") for item in INPUTS.iterdir(): # 获取文件的详细状态信息 stat_info = item.stat() # 格式化输出:文件名、大小(KB)、修改时间 size_kb = stat_info.st_size / 1024 print(f"{item.name:<20} {size_kb:.2f}KB 修改时间:{stat_info.st_mtime}")
内容的提问来源于stack exchange,提问作者rc341
相关产品推荐
相关产品推荐

