查找:-exec 缺少参数

Posted

技术标签:

【中文标题】查找:-exec 缺少参数【英文标题】:find: missing argument to -exec 【发布时间】:2011-02-27 01:09:00 【问题描述】:

我今天得到了一个命令的帮助,但它似乎不起作用。这是命令:

find /home/me/download/ -type f -name "*.rm" -exec ffmpeg -i  -sameq .mp3 && rm \;

外壳返回

find: missing argument to `-exec'

我基本上想要做的是递归地遍历一个目录(如果它有其他目录)并在.rm文件类型上运行ffmpeg命令并将它们转换为.mp3文件类型。完成后,删除刚刚转换的.rm 文件。

感谢您对此提供的任何帮助。

【问题讨论】:

【参考方案1】:

我认为你需要做一些转义。

find /home/me/download/ -type f -name "*.rm" -exec ffmpeg -i  \-sameq .mp3 \&\& rm \;

【讨论】:

【参考方案2】:

我现在想通了。当您需要在 exec 中运行两个命令时,您实际上需要有两个单独的 exec。这终于对我有用了。

find . -type f -name "*.rm" -exec ffmpeg -i  -sameq .mp3 \; -exec rm  \;

【讨论】:

不确定是否会获取要删除的文件的变量?有人知道是不是这样吗? 要测试这些东西,只需在命令前添加echo 看看它的作用。 @Marian, echo 非常不可靠——你无法分辨echo "one argument"echo one argument 之间的区别(后者的输出为假,因为它实际上完全通过了echo 两个单独的论点)。最好执行-exec bash -c 'printf "%q " "$@"' _ ffmpeg -i -sameq .mp3 \; -printf '\n' 之类的操作,它将以一种使不可打印字符可见的方式打印输出,以便您可以检测 DOS 换行符和其他奇怪的东西。【参考方案3】:

和 && 都会因为被命令行展开而出现问题。我建议尝试:

find /home/me/download/ -type f -name "*.rm" -exec ffmpeg -i \ -sameq \.mp3 \; -exec rm \ \;

【讨论】:

如果exec中的第一个命令成功,exec中的第二个命令被执行,它是否仍然可以访问变量来删除正确的文件? 你认为 扩展成什么?除非它包含两个将保持原样的点或逗号。【参考方案4】:

-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 之后将其他参数传递给shell(请参阅man sh):

$ ls
$(echo damn.)
$ find * -exec sh -c 'echo ""' \;
damn.
$ find * -exec sh -c 'echo "$1"' -  \;
$(echo damn.)

您看到$ 在第一个示例中由shell 评估。想象一下有一个名为$(rm -rf /) 的文件:-)

(旁注:- 不是必需的,但命令后的第一个变量分配给变量$0,这是一个特殊变量,通常包含正在运行的程序的名称并将其设置为参数有点不干净,虽然在这里可能不会造成任何伤害,所以我们将其设置为 - 并以 $1 开头。)

所以你的命令可能是这样的

find -exec bash -c 'ffmpeg -i "$1" -sameq "$1".mp3 && rm "$1".mp3' -  \;

但是有更好的方法。 find支持andor,所以你可以做find -name foo -or -name bar之类的东西。但这也适用于-exec,如果命令成功退出,则计算结果为 true,否则返回 false。看这个例子:

$ ls
false  true
$ find * -exec  \; -and -print
true

它仅在命令成功时才运行打印,它对true 执行此操作,但对false 执行此操作。

因此,您可以使用两个与-and 链接的 exec 语句,并且只有在前者运行成功时才会执行后者。

【讨论】:

关键似乎是 Marian 的“the ; is an arg on it's own”的行,这对我来说是这样做的,灯泡明智和我的代码示例。谢谢。 这是我在 -exec 上读到的最好的描述。它非常强大,但我总是发现很难为它找到正确的语法。这让一些事情变得更加清晰。特别是将命令包装在单独的外壳中。好的。谢谢。 请注意 -and-or 不可移植。 POSIX specifies -a and -o,事实上-a 总是被假定的(因此不需要)。 在终止符前也必须有一个空格。例如 "\;" 不起作用,但 " \;" 起作用 为了将来遇到 ssh 错误的读者的利益,在 -exec 解决问题后将终止的转义分号括起来(Ubuntu 18.04.2 LTS): $ ssh remuser@remhost find Documents -执行回声 '\;'【参考方案5】:

尝试在每个 \ 之前放置一个空格;

作品:

find . -name "*.log" -exec echo  \;

不起作用:

find . -name "*.log" -exec echo \;

【讨论】:

这经常让我绊倒。这几天,我会默认添加一个空格。 对我来说,它在 Windows 7 下的 Cygwin 中正好相反:之前没有空格\;有效,有空间 - 不。但是如果我删除\,前面有空格;它可以工作,并且之前没有空格;它没有,就像这里描述的那样。【参考方案6】:

仅供参考: 我刚刚尝试在 Cygwin 系统(在 Windows 上模拟 UNIX)上使用“find -exec”命令,似乎必须删除分号前的反斜杠:find ./ -name "blabla" -exec wc -l ;

【讨论】:

我真的很困惑。 find /etc/nginx -name '*.conf' -exec echo ;find /etc/nginx -name '*.conf' -exec echo \; 给出了相同的结果。 :( 我正在运行 Git for Windows 附带的 Bash shell,Dustin Cowles 的回答对我有用。换句话说:没有引号,反斜杠用分号转义, 后面有空格。 意思上没有区别,但是有些情况下需要放反斜杠,有些情况下不能放反斜杠,再有其他情况下可以选择。【参考方案7】:

以防万一有人在 Amazon Opsworks Chef bash 脚本中看到类似的“缺少 -exec args”,我需要添加另一个反斜杠来转义 \;

bash 'remove_wars' do
  user 'ubuntu'
  cwd '/'
  code <<-EOH
    find /home/ubuntu/wars -type f -name "*.war" -exec rm  \\;
  EOH
  ignore_failure true
end

【讨论】:

【参考方案8】:

另外,如果其他人有“find:missing argument to -exec”这可能会有所帮助:

在某些 shell 中,您不需要进行转义,即您不需要“;”前面的“\”。

find <file path> -name "myFile.*" -exec rm - f  ;

【讨论】:

; 在这里没有被引用或转义意味着它可以被 shell 使用,不能被find 读取。另外,-f- f 是两个不同的东西。【参考方案9】:

如果您仍然收到“查找:缺少 -exec 的参数”,请尝试将执行参数用引号括起来。

find <file path> -type f -exec "chmod 664  \;"

【讨论】:

find: In ‘-exec ... +’ the ‘’ must appear by itself, but you specified ‘... ...’【参考方案10】:

你必须在\;之间加一个空格

所以命令会是这样的:

find /home/me/download/ -type f -name "*.rm" -exec ffmpeg -i  -sameq .mp3 && rm  \;

【讨论】:

【参考方案11】:

对于其他在使用 GNU 时遇到问题的人,请在 Windows 命令提示符下查找二进制文件。分号需要用^转义

find.exe . -name "*.rm" -exec ffmpeg -i  -sameq .mp3 ^;

【讨论】:

非常感谢,这正是我的问题。

以上是关于查找:-exec 缺少参数的主要内容,如果未能解决你的问题,请参考以下文章

find exec 学习

如何将 exec 参数中的管道用于查找命令?

每天一个linux命令:find命令之exec

Linux之find exec

linux find查找并拷贝 exec xargs区别

[转]find命令之exec