bash: -exec in find command and & - bash

I want to run:
./my_script.py a_file &
... on all files in the current folder that end with .my_format, so I do:
find . -type f -name "*.my_format" -exec ./my_script {} & \;
but it doesn't work. How should I include & in the -exec parameter?

Try this:
$ find . -type f -name "*.my_format" -exec sh -c './my_script {} &' \;
The mostly likely reason your attempt didn't work is because find executes the command using one of the exec(3) family of standard c library calls which don't understand job control - the & symbol. The shell does understand the "run this command in the background" hence the -exec sh ... invocation

Try this find command:
find . -type f -name "*.my_format" -exec bash -c './my_script "$1" &' - '{}' \;

Related

Executing `make` inside multiple directories

I am trying to run make command inside multiple folders which start with g-. How can I do so?
I was wondering if I could use "find" command to solve it. Can you help me to understand it better?
I tried:
find . -type d -name "g-*" -exec make {}\;
You need to invoke make with the -C option.
find . -type d -name 'g-*' -exec make -C {} \;
From your attempt, I conclude that each g- directory contains a suitable Makefile. Hence you can do a
find . -type d -name 'g-*' -exec sh -c 'cd {}; make' \;

Find and rename files by pattern works in Debian, but not in CentOS7

I need to find and rename files with question mark in names.
Example: "style.css?ver=111" should become "style.css"
I use this command
find . -type f -name "*\?*" -exec rename 's/\?.*//' '{}' \;
In Debian all works fine, but in CentOS7 I get and error that "rename: not enough arguments
"
Any ideas why?
For a reliable option that should work in any POSIX-compliant system, you may use
find . -type f -name "*\?*" -exec sh -c 'mv -- "$1" "${1%%\?*}"' findshell {} \;
$1 is the name of each file found and ${1%%\?*} is a construct that strips the substring starting from the question mark.
That should be enough if you have a few matching files. If you need it, a more efficient alternative is
find . -type f -name "*\?*" -exec sh -c '
for file in "$#"; do
mv -- "$file" "${file%%\?*}"
done
' findshell {} +

find -exec cant find local function "find: Log: No such file or directory"

i have a piece of code that should print all files in specific dir. i use find exec for this:
find ${_di} -type f -print -exec Log "$(stat -c%y {}) - {}" \;
Where log is function of mine defines in same file.
But id does not work and i get error message:
"find: Log: No such file or directory".
Why? What is wrong in this piece of code?
Function can't be used in -exec however bash -c can be used as command.
Slightly modified to using + as -exec command terminator and {} last to allow to reduce the number of bash processes spawned.
find ${_di} -type f -print -exec bash -c "$(typeset -f Log)"$'\n''for arg; do Log "$(stat -c%y "$arg") - $arg"; done' -- {} +
the argument -- can be replaced by anything else it is used for $0 argument of shell.
bash -c 'echo $0' hello
Maybe -printf "%TY-%Tm-%Td %TT - %p\n" option could achieve the same result, more efficiently without launching other process.
Also using echo may be less safe than using find -print option, considering the following use case.
touch file.$'\e#8'
find . -type d ! -name . -prune -o -name file'*' -print
find . -type d ! -name . -prune -o -name file'*' -exec echo {} \;
You need to export the function, and then, as Nahuel says, run bash in the -exec:
$ export -f Log
$ find ${_di} -type f -exec bash -c 'Log "$(stat -c%y {}) - {}"' bash \;

Using + instead of \; in find -exec

I understand that using + rather than \; in a find command with -exec can speed things up because with \; the target of -exec is executed once for each result of the find command, whereas with + the target of -exec is executed "as needed."
This code works as expected and processes all subdirectories:
find "${directory}" -iname "*.jpg" -type d -prune -exec bash -c 'myscript "{}"' \;
But this code does NOT work:
find "${directory}" -iname "*.jpg" -type d -prune -exec bash -c 'myscript "$#"' bash {} +
It processes only one directory rather than all of them.
I'm obviously missing something about the proper syntax of using + when calling a function.

Performance difference in find command

Is there any performance difference in the below shell commands:
find . -type f -empty -exec rm '{}' \;
find . -type f -empty -exec sh -c "/bin/rm {}" \;
Your 2nd command is going to be slower since it will spawn a sub shell for each entry found by find command.
However at the same time 2nd command will be more flexible in nature if you want to do some variable assignment etc like this:
find . -type f -empty -exec sh -c "x=1; /bin/rm {}" \;

Resources