为什么 Solaris 10 查找 / -exec sh -c "echo {}" \;打印“{}”而不是文件名?

为什么 Solaris 10 查找 / -exec sh -c "echo {}" \;打印“{}”而不是文件名?

我一般不使用 Solaris,但今天我需要编写一个 find 命令来使用 shell 对已识别的文件执行操作。我发现这些{}角色没有被替换,也找不到替代品。

例如:

 bash-3.2# find / -exec sh -c "echo {}" \;

这会导致它打印{}每个文件而不是文件名。

答案1

唯一标准的使用方法是作为单独的参数find -exec …传递。{}参数包含时的行为{}不是标准化的。看来您已经习惯了{}在子字符串中替换的 GNU 行为。findSolaris 上的命令仅当{}参数仅包含 时才进行替换{}

GNU 行为并不是特别有用,有时甚至很烦人,因为在参数中替换文件名很脆弱。除非您知道文件名的限制,否则无法知道文件名的开始和结束位置。例如,使用 GNU find,find / -exec sh -c "echo {}" \;确实不是一般打印文件名。它仅在文件名不包含任何 shell 特殊字符时打印文件名。如果您在包含名为 的文件的目录中运行它;rm -r ~,请与您的文件说再见。

调用 shell 的可靠(且可移植)方法find -exec是将文件名作为参数传递给 shell。

find … -exec sh -c 'echo "$0"' {} \;

在大多数情况下,您可以批量传递参数并在 shell 中迭代参数。速度有点快了。请注意,shell 代码后面的第一个参数是$0which 不包含在"$@".

find … -exec sh -c 'for x; do echo "$x"; done' _ {} +

也可以看看为什么我的 shell 脚本会因为空格或其他特殊字符而卡住?

答案2

正如手册页和标准中所写,{}必须位于单独的参数中。

find / -exec sh -c 'echo $1' dummy '{}' \;

按预期工作。

请注意,该参数dummy是必需的,因为 shell 会在命令参数sh -c cmd变为 to之后分配第一个参数$0,而下一个参数则变为$1

相关内容