Linux find exec отсутствует аргумент

find: missing argument to -exec

What I am basically trying to do is go through a directory recursively (if it has other directories) and run the ffmpeg command on the .rm file types and convert them to .mp3 file types. Once this is done, remove the .rm file that has just been converted.

I found that when I copy a similar command from the browser into a terminal the \ dissappears, so I had to manually type it in front of ;

13 Answers 13

A -exec command must be terminated with a ; (so you usually need to type \; or ‘;’ to avoid interpretion by the shell) or a + . The difference is that with ; , the command is called once per file, with + , it is called just as few times as possible (usually once, but there is a maximum length for a command line, so it might be split up) with all filenames. See this example:

$ 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 

Your command has two errors:

First, you use <>; , but the ; must be a parameter of its own.

Second, the command ends at the && . You specified “run find, and if that was successful, remove the file named <>; .“. If you want to use shell stuff in the -exec command, you need to explicitly run it in a shell, such as -exec sh -c ‘ffmpeg . && rm’ .

However you should not add the <> inside the bash command, it will produce problems when there are special characters. Instead, you can pass additional parameters to the shell after -c command_string (see man sh ):

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

You see the $ thing is evaluated by the shell in the first example. Imagine there was a file called $(rm -rf /) 🙂

(Side note: The — is not needed, but the first variable after the command is assigned to the variable $0 , which is a special variable normally containing the name of the program being run and setting that to a parameter is a little unclean, though it won’t cause any harm here probably, so we set that to just — and start with $1 .)

So your command could be something like

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

But there is a better way. find supports and and or , so you may do stuff like find -name foo -or -name bar . But that also works with -exec , which evaluates to true if the command exits successfully, and to false if not. See this example:

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

It only runs the print if the command was successfully, which it did for true but not for false .

Читайте также:  Топ популярности дистрибутивов linux

So you can use two exec statements chained with an -and , and it will only execute the latter if the former was run successfully.

Источник

Linux find exec отсутствует аргумент

Друзья! Подскажите пожалуйста дилетанту. Запускаю в терминале: find /var/www/html/report/ -mtime +7 -exec rm -f {} \; Все отлично, работает. Создаю файл test.sh с содержимым: #!/bin/sh find /var/www/html/report/ -mtime +7 -exec rm -f {} \; Запускаю в терминале созданный файл, выдает ошибку:
find: отсутствует аргумент у `-exec’

  • Ошибка: find: отсутствует аргумент у `-exec’, erera22, 20:17 , 14-Янв-16, ( 1 )
  • Ошибка: find: отсутствует аргумент у `-exec’, asavah, 22:02 , 14-Янв-16, ( 2 )
    • Ошибка: find: отсутствует аргумент у `-exec’, phizikpro, 22:03 , 14-Янв-16, ( 3 )
      • Ошибка: find: отсутствует аргумент у `-exec’, Сергей, 23:00 , 14-Янв-16, ( 4 )
        • Ошибка: find: отсутствует аргумент у `-exec’, phizikpro, 23:14 , 14-Янв-16, ( 5 )

        > открой для себя экранирование

        Что это такое?

        >> открой для себя экранирование
        > Что это такое?

        find /var/www/html/report/ -mtime +7 -exec rm -f {} \;
        обратный слеш — спец.символ шелла, грубо говоря запускается
        find /var/www/html/report/ -mtime +7 -exec rm -f {}

        >>> открой для себя экранирование
        >> Что это такое?
        > find /var/www/html/report/ -mtime +7 -exec rm -f {} \;
        > обратный слеш — спец.символ шелла, грубо говоря запускается
        > find /var/www/html/report/ -mtime +7 -exec rm -f {}

        -exec command {} \; — выполняет над найденным файлом указанную команду; обратите внимание на синтаксис.

        Всем большое спасибо, проблема была в лени.
        Тупо копировал часть кода из браузера и подставлял свои данные
        по этой причине в код закрались вместе с переносом строки «левые» символы.
        Открыв файл с помощью mcedit увидел вместе с переносами строк (‘M)

        Источник

        find: missing argument to -exec

        -exec command <> + This variant of the -exec option runs the specified command on the selected files, but the command line is built by appending each selected file name at the end; the total number of invoca- tions of the command will be much less than the number of matched files. The command line is built in much the same way that xargs builds its command lines. Only one instance of ‘<>‘ is allowed within the command. The command is executed in the starting directory.

        find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar <> + find a/folder b/folder -name *.c -o -name *.h -exec 'grep -I foobar' <> + find a/folder b/folder -name *.c -o -name *.h -exec 'grep -I foobar' '<>' + find a/folder b/folder -name "*.c" -o -name "*.h" -exec grep -I foobar '<>' + find a/folder b/folder \( -name *.c -o -name *.h \) -exec grep -I foobar '<>' + find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar '<>' \+ 

        Have you tried escaping the + at the end? find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar ‘<>‘ \+

        You may be using an old version of GNU find . Though the -exec cmd <> + variant is POSIX and has been available since the 80s, GNU find only added it (relatively) recently (2005). What does find —version tell you?

        @Koveras, that would be it then. -exec <> + was added in 4.2.12 in 2005. In older GNU finds, you can use the (non-POSIX) -print0 | xargs -r0 to get something similar. 4.1 is from 1994.

        JRFerguson pointed out (in an answer that has been deleted) that the -name pattern arguments should be quoted: -name «*.c» -o -name «*.h» . This is true, although it’s unrelated to the -exec error. You’ll notice that all the other answers put the wildcards into quotes, although only Gilles mentions it. … (Cont’d)

        (Cont’d) … jlliagre’s answer collapses the name expression to -name «*.[ch]» without explanation. This has the benefits of simplifying the command line and, specifically, eliminating the -o . Find expressions involving -o are hard to get right. Yours is wrong; if your command is fixed so that it doesn’t error out (as in Gilles’s answer), it will run grep only on the .h files. You need to do ‘(‘ -name ‘*.c’ -o -name ‘*.h’ ‘)’ .

        5 Answers 5

        There was several issues with your attempts, including backticks used instead of quotes (removed in later edits to the question), missing quotes where they are required, extra quotes where they are useless, missing parentheses to group -o clauses, and different implementations of find used (see the comments and chat for details).

        Anyway, the command can be simplified like this:

        find a/folder b/folder -name "*.[ch]" -exec grep -I foobar <> + 

        or, should you use an archaic GNU find version, this should always work:

        find a/folder b/folder -name "*.[ch]" -exec grep -I foobar <> \; 

        From find man pages: «The string ‘<>‘ is replaced by the current file name being processed everywhere it occurs in the arguments to the command, not just in arguments where it is alone, as in some versions of find. Both of these constructions might need to be escaped (with a ‘\’) or quoted to protect them from expansion by the shell.»

        I indeed read that in the manual page but the fact is there is no shell I’m aware of that requires quoting the curly braces. What shell are you using ?

        “missing argument to -exec ” usually means that the argument to — exec is missing its terminator. The terminator must either be an argument containing just the character ; (which needs to be quoted in a shell command, so it’s typically written \; or ‘;’ ), or two successive arguments containing <> and + .

        Stephane Chazelas has identified that you’re using an older version of GNU find which doesn’t support -exec … <> + , only -exec <> \; . Although GNU was a late adopter of -exec … <> + , I do recommend that you get a less antique tool suite (such as Cygwin, which includes git and a whole lot more, or GNUwin32, which lacks git but doesn’t have the bad-employee-trying-to-use-linux-but-we-impose-windows vibe that Cygwin gives). This feature was added in version 4.2.12, over 9 years ago (it was the last identified feature to make GNU find POSIX-compliant).

        If you want to stick to an older GNU find, you can use -print0 with xargs -0 to get a similar functionality: grouped command execution, supporting arbitrary file names.

        find a/folder b/folder -name '*.c' -o -name '*.h' -print0 | xargs -0 grep -I foobar /dev/null 

        Always quote the wildcards on the find command line. Otherwise, if you happen to run this command from a directory containing .c files, the unquoted *.c would be expanded to the list of .c files in the current directory.

        Adding /dev/null to the grep command line is a trick to ensure that grep will always print the file name, even if find happens to find a single match. With GNU find, another method is to pass the option -H .

        Источник

        missing argument to find -exec [duplicate]

        I want to remove certain files using find and -exec. But unlikely bash tells me, that I’m «missing» some argument.

        find . -name ic_launcher.png -exec mv <> other_name.png /; 

        Backslash and slash are not the same thing at all. Backslashes lean backwards: \\ , Forward slashes, or just slashes, lean forwards: / . In Unix, slashes are generally path separators, while backslashes are generally used for quoting / escaping.

        @jw013 sorry about that! I was actually misreading it, most likely because I found so many examples that use the slash instead of the backslash. In fact the manpage is right!

        Wherever you found those examples that used the wrong slash must not be a very good resource. I would recommend not going there for examples anymore.

        2 Answers 2

        The semicolon at the end needs to be quoted or escaped so that it is passed to find instead of being interpreted by the shell.

        find . -name ic_launcher.png -exec mv '<>' other_name.png ';' 
        find . -name ic_launcher.png -exec mv '<>' other_name.png \; 

        should do what you’re trying to do.

        It’s almost never necessary to quote <> . There was actually an entire question about that, but I can’t find it because the site can’t search for <> . The issue is the /; typo in the original question.

        @jw013 That is a very fair point. I guess I usually tend to go for something that will definitely work. And after having experienced issues with no quoting, I usually quote the braces. Possibly a bit too much for my own good.

        Yup, no harm in over-quoting. It’s definitely better to err that way than the other way, but leaving out redundant quotes does save some keystrokes :). Normally I don’t point out redundant quotes but in this case I just wanted to make sure the questioner understood where the real issue was, i.e. the misquoted ; character.

        Источник

Оцените статью
Adblock
detector