在.bashrc定义变量供外部SH脚本调用的问题排查
问题
我在.bashrc中定义了如下函数来创建变量:
quick_amber(){ home=$(pwd) project="MDtest" ref_folder="${home}" # run script from USB stick which will use all of these variable chmod +x /media/user/KINGSTON/extra/test.sh /media/user/KINGSTON/extra/test.sh }
这些变量需要在test.sh脚本中按如下方式使用:
# find pdb filles in any current directory and print its names #!/bin/bash for ref_pdb in ${ref_folder}/*.pdb; do ref_title2=$(basename "$ref_pdb") ref_title3="${ref_title2/.pdb}" echo "let's test it" echo $project: $ref_title3 found in "$ref_folder" done
但运行后出现问题:仅打印一行,且无法识别.bashrc函数中定义的变量,输出如下:
let's test it : MD_BAK_0deg.pdb MD_BAK_300deg.pdb MD_BAK_360deg.pdb MD_BAK_60deg.pdb found in
我尝试将所有变量定义为全局或局部,但均无效果,请问该如何修正?
解决方案
核心问题拆解
- 子进程无法直接读取父shell的普通变量:
test.sh是被函数启动的独立子shell,默认不会继承父shell中未导出的变量。 - 文件匹配逻辑缺陷:当
${ref_folder}/*.pdb没有匹配到有效文件时,bash会把整个字符串作为单个循环项,导致一次性输出所有文件名。
具体修正步骤
1. 导出变量为环境变量
在.bashrc的函数中,用export声明需要传递给子脚本的变量,让子进程能读取到:
quick_amber(){ home=$(pwd) project="MDtest" ref_folder="${home}" # 导出变量到环境中 export home project ref_folder chmod +x /media/user/KINGSTON/extra/test.sh /media/user/KINGSTON/extra/test.sh }
2. 修复循环的文件匹配与变量引用问题
修改test.sh,启用nullglob处理空匹配,同时规范变量引用和后缀删除逻辑:
# find pdb filles in any current directory and print its names #!/bin/bash # 启用空匹配处理:无匹配时返回空而非原字符串 shopt -s nullglob for ref_pdb in "${ref_folder}"/*.pdb; do ref_title2=$(basename "$ref_pdb") # 用%.*可靠删除文件后缀,避免文件名含多个.pdb的情况 ref_title3="${ref_title2%.*}" echo "let's test it" # 给变量加引号,避免空格等特殊字符导致的格式问题 echo "${project}: ${ref_title3} found in \"${ref_folder}\"" done
3. 可选:用source方式运行脚本
如果不想用环境变量,可让脚本在当前shell进程中执行,直接复用父shell变量:
修改.bashrc函数中的执行命令:
# 替换原来的执行行 source /media/user/KINGSTON/extra/test.sh # 或者用简写形式 . /media/user/KINGSTON/extra/test.sh
注意:这种方式下,脚本中的所有环境修改会直接影响当前shell。
内容的提问来源于stack exchange,提问作者James Starlight
相关产品推荐
相关产品推荐

