我对bash脚本很新。我正在尝试编写一行搜索具有特定名称的所有文件,并重命名它们,但当前正在运行的脚本除外。
这是我到目前为止所做的:
find $1 -name thescript.sh -exec /bin/bash -c 'test \'"$(readlink -f "$0")" = {}\' || mv {} \$\(dirname {}\)/thescript0.sh' \; || true
以下简要介绍了我的工作原理:
readlink
{}
的所有文件thescript.sh
以及$1
的某个子目录:
{}
{}
{}
移至同一目录下的文件,但名称为thescript0.sh
一些注意事项:
$1
脚本的第一个参数是重命名的基本目录||
)在exec
子句中,我跟随this question的一些答案并启动了一个带引号命令的新shell,在其中我可以使用||
,以便shell并不认为这个运算符是父命令的一部分。引用的命令从test
开始,以thescript0.sh
readlink
位于子shell中,因为readlink
的结果已传递给test
test
的转义引号,否则我认为shell会认为第一个引号实际上是前一个单引号的终结符(它启动了引用的命令)find
的原因最后我得到的错误是:
|| true
我目前找不到任何不匹配的引号;只有一对未转义的引号。
答案 0 :(得分:1)
单引号不接受任何转义序列,甚至不接受\'
。要在单个带引号的字符串中包含单引号,您必须离开并重新输入:
echo 'What'"'"'s wrong?'
echo 'Oh, it'\''s nothing.'
附加说明:
$0
不会在单引号内展开。
find
的退出代码与-exec
的结果无关,因此不需要|| true
。
为了最大限度地提高安全性,最好将{}
作为参数传递给bash,而不是将其嵌入脚本中。通过这种方式,空白和其他特殊角色不会绊倒。
在包含空格或通配符的情况下,始终引用变量扩展。
考虑到以上所有因素的建议更新:
find "$1" -name thescript.sh -exec bash -c 'test "$1" == "$2" || mv "$2" "$(dirname "$2")"/thescript0.sh' bash "$(readlink -f "$0")" {} \;
(我还没有对它进行过测试,所以即使我做了一些拼写错误,也希望你得到主旨。)