find: missing argument to -exec

后端 未结 11 2126
心在旅途
心在旅途 2020-11-28 17:52

I was helped out today with a command, but it doesn\'t seem to be working. This is the command:

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


        
相关标签:
11条回答
  • 2020-11-28 18:25

    You have to put a space between {} and \;

    So the command will be like:

    find /home/me/download/ -type f -name "*.rm" -exec ffmpeg -i {} -sameq {}.mp3 && rm {} \;
    
    0 讨论(0)
  • 2020-11-28 18:26

    If you are still getting "find: missing argument to -exec" try wrapping the execute argument in quotes.

    find <file path> -type f -exec "chmod 664 {} \;"
    
    0 讨论(0)
  • 2020-11-28 18:27

    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.

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

    0 讨论(0)
  • 2020-11-28 18:28

    Try putting a space before each \;

    Works:

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

    Doesn't Work:

    find . -name "*.log" -exec echo {}\;
    
    0 讨论(0)
  • 2020-11-28 18:32

    For anyone else having issues when using GNU find binary in a Windows command prompt. The semicolon needs to be escaped with ^

    find.exe . -name "*.rm" -exec ffmpeg -i {} -sameq {}.mp3 ^;
    
    0 讨论(0)
提交回复
热议问题