Bash脚本仅能获取Python 2版本,无法获取Python 3版本求助
问题分析:Bash脚本中Python3 --version无输出但命令行执行正常
你的脚本如下:
#!/bin/bash for x in `find $(readlink -f /usr/local/folder/) -iregex ".*/python[23]"` do TORUN=$(echo "${x} --version") echo $TORUN TORUN2=$(eval $TORUN) done
执行后仅输出:
/usr/local/zz/AA_EXTERNAL/venv3/bin/python3 --version /usr/local/zz/AA_EXTERNAL_TEST/venv3/bin/python3 --version /usr/local/zz/API_PROXY/forapis/bin/python2 --version Python 2.7.5
但直接在命令行执行/usr/local/zz/AA_EXTERNAL/venv3/bin/python3 --version能正常得到Python 3.6.4,问题根源和解决方法如下:
核心原因
Python 2和Python 3的--version输出流向存在差异:
- Python 2将版本信息输出到标准输出(stdout)
- Python 3将版本信息输出到标准错误输出(stderr)
你的脚本中,TORUN2=$(eval $TORUN)只会捕获命令的stdout内容,而Python 3的版本信息通过stderr输出,既不会被存到变量中,也没有被显式打印到终端。另外你没有编写echo $TORUN2的逻辑,却能看到Python 2的版本,是因为Python 2的输出被存到TORUN2后,可能在你未粘贴的脚本部分被打印,或者你的环境中Python 2的--version同时输出到了stderr。
解决方案
1. 直接执行命令(最简洁可靠)
不需要用eval和变量存储命令,直接调用Python解释器打印版本,这样不管输出到stdout还是stderr,都会显示在终端:
#!/bin/bash target_dir=$(readlink -f /usr/local/folder/) for x in $(find "$target_dir" -iregex ".*/python[23]") do echo "$x --version" "$x" --version done
2. 重定向stderr到stdout(捕获输出到变量)
如果需要把版本信息存到变量中,可以将stderr重定向到stdout,让$(...)捕获所有输出:
#!/bin/bash target_dir=$(readlink -f /usr/local/folder/) for x in $(find "$target_dir" -iregex ".*/python[23]") do cmd="$x --version" echo "$cmd" version=$($cmd 2>&1) echo "$version" done
3. 处理含空格的路径(更安全的循环)
原脚本用for x in $(find ...)的方式,若路径包含空格会出错,建议用find -print0配合while read的方式:
#!/bin/bash target_dir=$(readlink -f /usr/local/folder/) while IFS= read -r -d '' x; do echo "$x --version" "$x" --version done < <(find "$target_dir" -iregex ".*/python[23]" -print0)
4. 用find的-exec直接执行
最简洁的写法是让find直接调用命令:
#!/bin/bash target_dir=$(readlink -f /usr/local/folder/) find "$target_dir" -iregex ".*/python[23]" -exec sh -c 'echo "$1 --version"; "$1" --version' _ {} \;
总结
- Python 2和3的
--version输出流差异是核心问题 - 避免使用
eval和不必要的变量存储,直接执行命令更可靠 - 处理路径时要考虑含空格的场景,用
-print0+while read的组合更安全
内容的提问来源于stack exchange,提问作者MW_DEVEL
相关产品推荐
相关产品推荐

