Firstly wanna thank you for creating such an awesome tool. It is very fast. My doubt was is there any functionality which is same like execdir in find.
What I want to do:
So I search for a folder named "dir1" and then I want to make a copy of it and name it "dir2" in same parent directroy. So for example if "dir1" is in ~/Documents/Test/dir1 then dir2 should be ~/Documents/Test/dir2 . There can be 4 - 5 "dir1" in my search results so would like to make a copy of all of them and name them "dir2" in the same parent directory.
What I do in find:
find . -type d -name "dir1" -execdir cp -r {} dir2 \;
What I do in fd:
fd -t d dir1 -X cp -r {} dir2
Result:
Find copies the folder in same parent directory as dir1 and name it dir2.
Fd copies the dir1 and name it as dir2. But it does it in working directory and not in the same parent directory. So it is ~/dir2 instead of ~/Documents/Test/dir2.
Hope this was clear enough. Thanks for the help in advance.
You can do something like
fd -t d dir1 -x cp -r {} {//}/dir2
(see the examples at https://github.com/sharkdp/fd#parallel-command-execution).
Thanks so much that was it. Didn't thought it can be used this way.
I'm not sure the examples in the OP explain the need for something like -execdir; the point is that execdir changes the current working directory (CWD) before running a command. Lots of commands assume a CWD, e.g. sha1sum.
For example, if you want to find all *sha1 files in a directory tree and check them, you can use this w/ GNU find:
find . -name '*sha1' -execdir sha1sum -c {} \;
and with GNU parallel:
parallel "cd {//} && sha1sum -c {/}" ::: **/*sha1
With fd, Since -x doesn't pass arguments through a shell, you can't do something like:
$ fd -e sha1 -x cd {//} && sha1sum -c {/}
[fd error]: Command not found: "cd" "..."
$ fd -e sha1 -x "cd {//} && sha1sum -c {/}"
[fd error]: Command not found: "cd ..."
Or is there some other workaround I'm not aware of? Can this issue be reopened, or should I open a new one?
You can pass it through a shell yourself:
$ fd -x sh -c 'cd "$1" && sha1sum $2' sh {//} {/}
The reasoning for GNU find's -execdir is to avoid races. E.g. find sees a/b/c, then goes to execute some_program a/b/c, but meanwhile someone else does mv a a.bak && mv malicious a. This can be important if there were other predicates that find checked on the way, since now they may not be true for the malicious directories. With -execdir the program will be executed in the original a/b directory even if it gets moved around.
Most helpful comment
You can pass it through a shell yourself:
The reasoning for GNU find's -execdir is to avoid races. E.g. find sees a/b/c, then goes to execute
some_program a/b/c, but meanwhile someone else doesmv a a.bak && mv malicious a. This can be important if there were other predicates that find checked on the way, since now they may not be true for the malicious directories. With-execdirthe program will be executed in the originala/bdirectory even if it gets moved around.