2010-06-02 86 views
153

今天我被一個命令幫了忙,但它似乎沒有工作。這是命令:找到:缺少參數到-exec

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

外殼返回

find: missing argument to `-exec' 

什麼我基本上是試圖做的是要經過一個目錄遞歸(如果有其他的目錄),然後運行FFmpeg的命令上.rm文件類型並將它們轉換爲.mp3文件類型。完成此操作後,請刪除剛剛轉換的.rm文件。

我欣賞這方面的任何幫助。

回答

45

我現在想通了。當你需要在exec中運行兩條命令時,你需要實際擁有兩個獨立的exec。這終於爲我工作。

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

不確定是否會得到要刪除的文件的變量?任何人都知道是否是這種情況? – Abs 2010-06-02 21:46:08

+4

要測試這樣的事情,只需在命令前面加一個'echo',看看它做了什麼。 – Marian 2010-06-02 22:22:36

1

你需要做一些轉義我認爲。

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

兩個{}和& &將導致由於通過在命令行正在擴大的問題。我會建議嘗試:

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

如果exec中的第一個命令成功執行並且exec中的第二個命令被執行,它是否仍然可以訪問變量{?}以刪除正確的文件? – Abs 2010-06-02 21:54:23

+0

thinik'{}'擴展到了什麼程度?除非它包含將保持原樣的兩個點或逗號。 – Marian 2010-06-02 22:21:54

258

一個-exec命令必須以;終止(所以你通常需要輸入\;或​​3210以避免由外殼解譯)或+。與;不同的是,該命令在每個文件中被調用一次,其中+被調用的次數儘可能少(通常只有一次,但命令行有最大長度,因此可能會被分割)所有文件名。看到這個例子:

$ 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.) 

你看$事情是由第一個例子中的殼評估。想象一下,有一個叫做$(rm -rf /) :-)文件

(邊注:-是不需要的,但該命令後的第一個變量賦值給變量$0,這通常是包含程序的名稱的特殊變量正在運行和設置,爲一個參數是有點不乾淨,但它不會在這裏造成任何傷害可能,所以我們設置只是-並開始$1。)

所以,你的命令可能是這樣的

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

但有一個更好的方法。找到支持andor,所以你可以做一些像find -name foo -or -name bar的東西。但是,這也適用於-exec,如果該命令成功退出,則計算結果爲true;如果不成功,則計算結果爲false。看到這個例子:

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

它只能運行打印命令是否成功,它沒有爲true而不是false

因此,您可以使用兩個與-and鏈接的exec語句,如果前者成功運行,它將僅執行後者。

+2

關鍵似乎是瑪麗安的「這是它自己的arg」這一行,這是對我,燈泡明智和我的代碼示例。謝謝。 – pjammer 2014-03-20 01:29:44

+1

這是關於我讀過的最好的描述--exec。 這是非常強大的,但我總是很難得到正確的語法。這使得一些事情更清晰。特別是將命令包裝在單獨的shell中。尼斯。謝謝。 – Eurospoofer 2016-01-27 10:10:09

+2

請注意'-and'和'-or'不可移植。 [POSIX指定'-a'和'-o'](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/find.html),實際上總是假定(-a)(因此不需要) 。 – 2016-10-02 12:38:31

35

嘗試在每個\之前放置一個空格;

作品:

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

不起作用:

find . -name "*.log" -exec echo {}\; 
+1

這讓我經常旅行。其中一天,我會默認添加一個空格。 – harperville 2015-04-22 20:48:56

+0

對我來說,它在Windows 7下的Cygwin中恰恰相反: \之前沒有空格;作品,與空間 - 不。 但是,如果我刪除\,之前的空間;它的工作原理,沒有空間;它不會,就像它在這裏描述的那樣。 – WebComer 2017-02-10 23:58:33

7

只是爲了您的信息:
使用 「查找-exec」 Cygwin的系統上的命令,我剛纔想(UNIX仿真在Windows上),並且看起來必須刪除分號前的反斜槓:
find ./ -name "blabla" -exec wc -l {} ;

+0

我真的很困惑。 'find/etc/nginx -name'* .conf'-exec echo {};''和'find /etc/nginx-name'* .conf'-exec echo {}'給出了相同的結果。 :( – Kirby 2016-03-14 22:19:03

+0

我正在運行Git for Windows附帶的Bash shell,而Dustin Cowles的答案適用於我。換句話說:沒有引號,反斜線以分號轉義,'{}'後面的空格。 – mamacdon 2018-01-09 20:10:23

2

爲了防止任何人在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 
3

此外,如果任何人有「查找:缺少參數-exec」這可能幫助:

在你不需要做一些逃逸彈,即你不需要「;」前面的「;」。

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

如果您仍然在「find:missing argument to -exec」中,請嘗試將引號中的execute參數包裹起來。

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