Python 3脚本无法识别命令行重定向符号,不改脚本怎么解决?
为什么
python3 app.py < input.txt无法让脚本获取到文件名?以及不修改脚本的解决办法 首先得搞清楚一个核心点:<是Shell的输入重定向操作符,不是传给Python脚本的命令行参数。当你运行python3 app.py < input.txt时,Shell会先偷偷完成这些操作:
- 打开
input.txt文件 - 将Python脚本的标准输入(stdin)绑定到这个文件
- 才启动Python进程,把
app.py作为参数传给它
所以Python脚本根本看不到<和input.txt——这俩早被Shell处理掉了,sys.argv自然只有['app.py']。
接下来是你要的「不修改脚本」的解决方案:
方法1:用Shell函数包装(一劳永逸)
如果你经常需要这么运行,可以在Shell的配置文件(比如~/.bashrc或~/.zshrc)里加个包装函数:
run_app() { # 判断标准输入是否来自一个真实文件 if [[ -f /proc/self/fd/0 ]]; then # 通过/proc文件系统拿到stdin对应的文件路径 local input_file=$(readlink -f /proc/self/fd/0) # 把文件路径作为参数传给脚本 python3 app.py "$input_file" else # 如果stdin不是文件(比如管道输入),就按原参数调用脚本 python3 app.py "$@" fi }
保存后执行source ~/.bashrc让配置生效,之后你只要运行:
run_app < input.txt
脚本就会输出['app.py', 'input.txt'],和你第一条命令的效果完全一样。
方法2:单次临时命令(无需修改配置)
如果只是偶尔用一次,直接用这条命令就行:
python3 app.py "$(readlink -f /proc/self/fd/0)" < input.txt
它会先通过readlink获取当前stdin对应的文件路径,再把路径作为参数传给脚本,本质和方法1是一样的。
跨平台注意事项
上面的方法依赖Linux的/proc文件系统,如果是在macOS上,可以用lsof替代:
python3 app.py "$(lsof -p $$ -Fn | grep ^n | head -1 | cut -c2-)" < input.txt
另外要提醒一句:如果你的输入不是来自普通文件(比如echo "test" | run_app这种管道输入),这些方法都拿不到文件名——因为本来就没有对应的文件。这种场景下如果要处理输入内容,还是得修改脚本读取stdin,但这不符合你「不修改脚本」的要求。
内容的提问来源于stack exchange,提问作者marshallslee
相关产品推荐
相关产品推荐

