Bash环境变量中如何将两行字符串处理命令合并为单行?
Bash环境变量中如何将两行字符串处理命令合并为单行?
没问题,这当然能合并成单行!先帮你理清楚你原来那两行命令在做什么:
- 第一行
FNAME="$(basename $LD_PRELOAD)":把LD_PRELOAD指向的文件路径剥掉前面的路径部分,只留下纯文件名 - 第二行
FNAME="${FNAME%.*}":把这个纯文件名最后一个点及后面的后缀部分去掉
你之前的两次尝试没成功,问题出在Bash的语法规则上:
- 第一次写的
${$(basename LD_PRELOAD)%.*}:既没给LD_PRELOAD加$来引用变量,而且旧版本的Bash不支持这种直接嵌套的参数展开写法 - 第二次的
${$(basename $LD_PRELOAD)%.*}:用反引号嵌套命令替换是错误的,反引号嵌套必须转义,而且这种写法本身就不符合Bash的参数展开语法
下面给你几种可行的单行方案:
1. 全版本兼容的写法(不依赖Bash版本)
这种写法用echo加sed完成后缀剥离,不管你的Bash是新是旧都能正常运行:
FNAME="$(echo "$(basename "$LD_PRELOAD")" | sed 's/\.[^.]*$//')"
(记得给LD_PRELOAD加双引号哦,不然文件名里有空格或者特殊字符的时候会出问题)
2. Bash 4.3及以上专属的简洁写法
如果你的Bash版本是4.3或更新的,它支持嵌套参数展开,直接这么写就搞定:
FNAME="${$(basename "$LD_PRELOAD")%.*}"
3. 更巧妙的纯Bash写法(无需外部命令)
其实完全可以跳过basename,直接用Bash自带的参数展开同时完成“剥路径”和“去后缀”:
原来的分步写法是:
FNAME="${LD_PRELOAD##*/}" # 这行等价于执行basename $LD_PRELOAD FNAME="${FNAME%.*}" # 去掉文件名后缀
合并成单行就是:
FNAME="${${LD_PRELOAD##*/}%.*}"
这个写法同样需要Bash 4.3+支持,优点是完全不调用外部命令,执行效率更高。
备注:内容来源于stack exchange,提问作者John-L_.
相关产品推荐
相关产品推荐

