我今天得到了一个命令的帮助,但它似乎没有工作。命令如下:
find /home/me/download/ -type f -name "*.rm" -exec ffmpeg -i {} -sameq {}.mp3 && rm {}\;
shell返回
find: missing argument to `-exec'
我基本上要做的是递归地遍历一个目录(如果它有其他目录),并在.rm文件类型上运行ffmpeg命令,并将它们转换为.mp3文件类型。完成此操作后,删除刚刚转换的.rm文件。
-exec命令必须以;(所以你通常需要输入\;或者';'以避免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的东西,你需要显式地在shell中运行它,例如-exec sh -c 'ffmpeg…& & rm”。
但是,您不应该在bash命令中添加{},当有特殊字符时,它会产生问题。相反,你可以在-c command_string(参见man sh)之后向shell传递额外的参数:
$ ls
$(echo damn.)
$ find * -exec sh -c 'echo "{}"' \;
damn.
$ find * -exec sh -c 'echo "$1"' - {} \;
$(echo damn.)
在第一个示例中,可以看到shell对$进行了计算。假设有一个文件叫做$(rm -rf /):-)
(旁注:-是不需要的,但命令后的第一个变量被赋值为变量$0,这是一个特殊变量,通常包含正在运行的程序的名称,将其设置为参数有点不整洁,尽管在这里可能不会造成任何伤害,所以我们将其设置为just -,并从$1开始。)
你的命令可以是这样的
find -exec bash -c 'ffmpeg -i "$1" -sameq "$1".mp3 && rm "$1".mp3' - {} \;
但是有一个更好的办法。查找支持,或者,你可以执行查找-name foo -或name bar。但这也适用于-exec,如果命令成功退出,则返回true,否则返回false。请看这个例子:
$ ls
false true
$ find * -exec {} \; -and -print
true
它只在命令成功的情况下运行打印,它对true执行,但对false不执行。
因此,您可以使用两个用-连接的exec语句,如果前者成功运行,它只会执行后者。