3

G'day,

I have tried to solve this problem all morning but have not had success. I would like to search for certain scripts in a particular folder and execute them all in parallel. The scripts have different names, but all end with "run.sh". Below what I have tried without success.

The first approach was to use find in combination with -execdir. This works, however, the scripts are executed in a sequantial fashion. I want all scripts to be executed simultaneously (parallel). There seems to be no option to achieve this with -execdir

find . -name "*run.sh" -type f -execdir 'nohup' {} '&' \;

Then, I tried using xargs because there is has a parallel option (-P). I have not tried the parallel option yet, because I am unable to get xargs to run the scripts in their respective subfolders. The commands below execute all scripts, but do that in the folder I am running the command in, therefore the scripts themselves do not work. The scripts have to be executed in their own subfolders. In the above example, -execdir is doing that as opposed to -exec. How do I achieve that with xargs?

nohup find . -name "*run.sh" -type f | xargs -0 -I{} bash -c f\ \{\}

or

nohup find . -name "*run.sh" -type f | xargs -0 -I{} bash -c "f {}"

or

nohup find . -name "*run.sh" -type f | xargs -0 -I{} bash -c "./{}" 

I am really frustrated and am hoping that there is somebody out there that can help. Thank you so much!

coder85
  • 31

2 Answers2

4

Inspired by choroba's answer:

find . -iname '*run.sh' -printf 'cd %h; ./%f\0' | xargs -L1 -0 -P0 bash -c

You can use -printf to build the command line. %h is the directory where the file is located, and %f is the name of the file without the path (the basename). The -P option enables parallelism in xargs, and -L1 -0 makes it use one null-terminated line of input per command.

muru
  • 197,895
  • 55
  • 485
  • 740
1

What about creating the command lines you want to run, then running them?

find . -name '*run.sh' -type f -exec \
    echo 'c={}; cd ${c%/*} && nohup "./${c##*/}" &' \;

If the output is what you want, just append | bash and run again.

choroba
  • 9,643