Shell脚本中括号扩展(Brace expansion)无法正常工作的问题
Shell脚本中括号扩展(Brace expansion)无法正常工作的问题
我完全懂你的困扰——直接在终端里用括号扩展创建目录能得到预期结果,但放到脚本里用sh运行就失效了,这其实是Shell环境的差异在搞鬼。
问题根源
括号扩展(比如{one,two,three}这种写法)是Bash专属的特性,而Ubuntu系统里默认的sh其实是Dash(一个轻量级Shell,主打兼容性和运行速度,但支持的特性比Bash少很多)。当你用sudo sh setup.sh运行脚本时,Dash不会解析括号扩展,而是把{one,two,three}-way当成一个完整的目录名来创建,所以才会出现你看到的奇怪结果。
解决办法
这里有几个可行的方案,你可以根据需求选择:
1. 让脚本明确使用Bash执行
在你的脚本第一行加上#!/bin/bash(指定脚本的解释器为Bash),然后用正确的方式运行脚本:
#!/bin/bash sudo mkdir -pv /opt/test/{one,two,three}-way
之后给脚本添加执行权限并运行:
chmod +x setup.sh sudo ./setup.sh
或者直接用Bash调用脚本:
sudo bash setup.sh
这样括号扩展就会被正常解析,和你直接在终端执行的效果完全一致。
2. 用循环替代括号扩展(兼容sh环境)
如果因为某些原因必须用sh运行脚本,可以手动用循环来实现相同的目录创建逻辑:
#!/bin/sh # 遍历目录前缀,逐个创建目标目录 for dir_prefix in one two three; do sudo mkdir -pv "/opt/test/${dir_prefix}-way" done
这种写法在Dash等轻量Shell里也能正常工作,而且逻辑更直观易懂。
验证效果
用第一种方法修改脚本后,运行脚本应该会和你直接在终端执行一样,依次创建/opt/test以及下面的one-way、two-way、three-way三个子目录。
备注:内容来源于stack exchange,提问作者Jonny Wright
相关产品推荐
相关产品推荐

