A -exec
命令必须以;
(所以你通常需要输入\;
or ';'
以避免 shell 的解释)或+
。不同的是,与;
,每个文件调用该命令一次,其中+
,它对所有文件名被调用的次数尽可能少(通常一次,但命令行有最大长度,因此它可能会被分割)。看这个例子:
$ cat /tmp/echoargs
#!/bin/sh
echo $1 - $2 - $3
$ find /tmp/foo -exec /tmp/echoargs {} \;
/tmp/foo - -
/tmp/foo/one - -
/tmp/foo/two - -
$ find /tmp/foo -exec /tmp/echoargs {} +
/tmp/foo - /tmp/foo/one - /tmp/foo/two
您的命令有两个错误:
首先,你使用{};
,但是;
必须是它自己的参数。
其次,命令结束于&&
。您指定“运行查找,如果成功,则删除名为{};
.“。如果你想在-exec
命令,您需要在 shell 中显式运行它,例如-exec sh -c 'ffmpeg ... && rm'
.
但是您不应该在 bash 命令中添加 {},当存在特殊字符时会产生问题。相反,您可以在之后将附加参数传递给 shell-c command_string
(see man sh
):
$ ls
$(echo damn.)
$ find * -exec sh -c 'echo "{}"' \;
damn.
$ find * -exec sh -c 'echo "$1"' - {} \;
$(echo damn.)
你看到$
在第一个示例中,thing 由 shell 进行评估。假设有一个文件名为$(rm -rf /)
:-)
(旁注:-
不需要,但将命令后的第一个变量赋值给该变量$0
,这是一个特殊变量,通常包含正在运行的程序的名称,将其设置为参数有点不干净,尽管它可能不会造成任何伤害,所以我们将其设置为-
并开始于$1
.)
所以你的命令可能是这样的
find -exec bash -c 'ffmpeg -i "$1" -sameq "$1".mp3 && rm "$1".mp3' - {} \;
但还有更好的方法。寻找支持and
and or
,所以你可以做类似的事情find -name foo -or -name bar
。但这也适用于-exec
,如果命令成功退出,则计算结果为 true,否则计算结果为 false。看这个例子:
$ ls
false true
$ find * -exec {} \; -and -print
true
它仅在命令成功时才运行打印,它是这样做的true
但不是为了false
.
所以你可以使用两个 exec 语句链接-and
,并且只有前者运行成功后才会执行后者。