使用subprocess Popen(shell=False)执行tar命令报错求助
*.py文件的问题 Hey there! I spot the problem right away—let's break this down.
问题原因
When you use shell=False (the default and generally safer setting), the subprocess module doesn't expand wildcard characters like *. That means the tar command is receiving the literal string *.py instead of a list of all Python files in your directory. Tar can't find a file named exactly *.py, hence the "Cannot stat" error you're seeing.
解决方案1:启用Shell解析通配符
If you're working with fully trusted input (no untrusted user-provided paths or filenames), you can set shell=True to let the system shell handle the wildcard expansion. Modify your Popen call like this:
p = subprocess.Popen("/usr/bin/tar -czvf x002.tgz *.py", cwd=base_dir, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
With shell=True, the shell will first expand *.py to all matching .py files in base_dir before passing them to the tar command.
解决方案2:手动解析通配符(更安全)
For better security (to avoid shell injection risks) and more control over file matching, use the glob module to expand the wildcard yourself. This way you don't need to enable shell=True:
import subprocess import glob base_dir = "/home/workspace/x002" tar_file = "x002.tgz" # Expand the wildcard to get actual .py file paths py_files = glob.glob(f"{base_dir}/*.py") # Check if any files were found to avoid empty tar commands if not py_files: print("No .py files found in the target directory!") else: # Pass the list of files directly to tar as separate arguments p = subprocess.Popen( ["/usr/bin/tar", "-czvf", tar_file] + py_files, cwd=base_dir, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=False ) results = [] while True: line = p.stdout.readline().decode('utf8').strip() if line == '' and p.poll() is not None: break else: results.append(line) print(results)
This approach is safer because it avoids executing arbitrary shell commands, and it handles filenames with special characters (like spaces or quotes) correctly—each file path is passed as a separate, properly escaped argument to tar.
内容的提问来源于stack exchange,提问作者Tom

