1
find .git/svn/refs/remotes/git-svn/ -type f -name '.rev_map*' \
     -exec cp '{}' '/backup/'$currentRevision$(basename '{}') ';'

When $currentRevision is 1234, I expect the command to copy .git/svn/refs/remotes/git-svn/.rev_map.b750ebf6-c7df-ed4a-bdf3-f739ba673275 to /backup/1234.rev_map.b750ebf6-c7df-ed4a-bdf3-f739ba673275.

But it throws error:

cp: cannot create regular file '/backup/1234.git/svn/refs/remotes/git-svn/.rev_map.b750ebf6-c7df-ed4a-bdf3-f739ba673275': No such file or directory

$(basename '{}') doesn't seem to run.

What type of data does -exec accept, string or "raw bash commands"?

How do I fix it?

Gqqnbig
  • 5,845
  • 10
  • 45
  • 86
  • 1
    It doesn't invoke a shell *at all*; it directly calls an `exec`-family syscall. No string parsing, no shell operations. – Charles Duffy Jan 30 '18 at 00:25
  • `-exec sh -c 'cp $1 ....' -- {} \;` – jordanm Jan 30 '18 at 00:26
  • @jordanm, you mean `sh -c 'cp "$1" ....'` -- the quotes matter. That said, it's much more efficient to make it `-exec sh -c 'for arg; do cp "$arg" ...; done' _ {} +` -- that way you invoke only one `sh` instance per batch of files, not one per individual file. – Charles Duffy Jan 30 '18 at 00:28
  • 1
    BTW, `"$(basename "$arg")"` is considerably slower than `"${arg##*/}"` -- creating a FIFO, forking a subshell, and then launching an external command from same -- and for no benefit over the native [parameter expansion](http://wiki.bash-hackers.org/syntax/pe) syntax. – Charles Duffy Jan 30 '18 at 00:30
  • @CharlesDuffy Technically, you could do `sh -c 'cp "$@" ...' _ {} +` and reduce the number of calls to cp as well. – jordanm Jan 30 '18 at 00:31
  • @jordanm, yup, good point. (For a moment I thought that wouldn't work because of the OP's command substitution, but since they're just stripping the directory, that substitution is needless; can just provide a single destination directory argument and not bother going name-by-name at all). – Charles Duffy Jan 30 '18 at 00:32

0 Answers0