为什么这个 bash 函数不能像直接 运行 那样工作?
Why won't this bash function work the same as when running directly?
我在/etc/bashrc
写了一个函数,因为我经常使用它,但现在它似乎不起作用:
function replaceall() {
find "" -type f -exec sed -i "s|||g" {} \;
}
当 运行 直接执行时,我会做类似的事情:
find ./*/conf/production/*.conf -type f -exec sed -i "s|/home/user/sites|/var/www/vhosts|g" {} \;
效果很好。但是当用 replaceall
函数调用时它不起作用:
replaceall ./*/conf/production/*.conf "/home/user/sites" "/var/www/vhosts"
注意: 当我使用 replaceall . [...]
时它确实有效,这让我想知道,我是否遗漏了一些关键语法?
看起来你根本没有依赖find
的遍历能力,所以我建议你只是使用循环扩展:
replaceall() {
for file in ; do
sed -i.bak "s|||g" "$file"
done
}
然后调用脚本,引用每个参数:
replaceall "./*/conf/production/*.conf" "/home/user/sites" "/var/www/vhosts"
引用每个参数可确保路径扩展发生在函数内。我还为 -i
开关添加了一个后缀,以便对受影响的每个文件进行备份,否则您的脚本非常危险!
如评论中所述,这种方法仍然存在潜在问题。如果你想传递包含 spaces 的路径,那么这些将必须转义以防止分词。例如,像 "./*/conf/production files/*.conf"
这样的路径需要在 space "./*/conf/production\ files/*.conf"
.
前面加一个反斜杠
我会这样写:
function replaceall() {
local search=
local replace=
shift 2
for i in "$@"
find "$i" -type f -exec sed -i "s|$search|$replace|g" {} \;
done
}
replaceall "/home/user/sites" "/var/www/vhosts" ./*/conf/production/*.conf
我在/etc/bashrc
写了一个函数,因为我经常使用它,但现在它似乎不起作用:
function replaceall() {
find "" -type f -exec sed -i "s|||g" {} \;
}
当 运行 直接执行时,我会做类似的事情:
find ./*/conf/production/*.conf -type f -exec sed -i "s|/home/user/sites|/var/www/vhosts|g" {} \;
效果很好。但是当用 replaceall
函数调用时它不起作用:
replaceall ./*/conf/production/*.conf "/home/user/sites" "/var/www/vhosts"
注意: 当我使用 replaceall . [...]
时它确实有效,这让我想知道,我是否遗漏了一些关键语法?
看起来你根本没有依赖find
的遍历能力,所以我建议你只是使用循环扩展:
replaceall() {
for file in ; do
sed -i.bak "s|||g" "$file"
done
}
然后调用脚本,引用每个参数:
replaceall "./*/conf/production/*.conf" "/home/user/sites" "/var/www/vhosts"
引用每个参数可确保路径扩展发生在函数内。我还为 -i
开关添加了一个后缀,以便对受影响的每个文件进行备份,否则您的脚本非常危险!
如评论中所述,这种方法仍然存在潜在问题。如果你想传递包含 spaces 的路径,那么这些将必须转义以防止分词。例如,像 "./*/conf/production files/*.conf"
这样的路径需要在 space "./*/conf/production\ files/*.conf"
.
我会这样写:
function replaceall() {
local search=
local replace=
shift 2
for i in "$@"
find "$i" -type f -exec sed -i "s|$search|$replace|g" {} \;
done
}
replaceall "/home/user/sites" "/var/www/vhosts" ./*/conf/production/*.conf