Monday, January 31, 2022

[SOLVED] Execute command in all immediate subdirectories

Issue

I'm trying to add a shell function (zsh) mexec to execute the same command in all immediate subdirectories e.g. with the following structure

~
-- folder1
-- folder2

mexec pwd would show for example

/home/me/folder1
/home/me/folder2

I'm using find to pull the immediate subdirectories. The problem is getting the passed in command to execute. Here's my first function defintion:

mexec() {
    find . -mindepth 1 -maxdepth 1 -type d | xargs -I'{}' \
    /bin/zsh -c "cd {} && $@;";
}

only executes the command itself but doesn't pass in the arguments i.e. mexec ls -al behaves exactly like ls

Changing the second line to /bin/zsh -c "(cd {} && $@);", mexec works for just mexec ls but shows this error for mexec ls -al:

zsh:1: parse error near `ls'

Going the exec route with find

find . -mindepth 1 -maxdepth 1 -type d -exec /bin/zsh -c "(cd {} && $@)" \;

Gives me the same thing which leads me to believe there's a problem with how I'm passing the arguments to zsh. This also seems to be a problem if I use bash: the error shown is:

-a);: -c: line 1: syntax error: unexpected end of file

What would be a good way to achieve this?


Solution

Can you try using this simple loop which loops in all sub-directories at one level deep and execute commands on it,

for d in ./*/ ; do (cd "$d" && ls -al); done

(cmd1 && cmd2) opens a sub-shell to run the commands. Since it is a child shell, the parent shell (the shell from which you're running this command) retains its current folder and other environment variables.

Wrap it around in a function in a proper zsh script as

#!/bin/zsh

function runCommand() {
    for d in ./*/ ; do /bin/zsh -c "(cd "$d" && "$@")"; done
}

runCommand "ls -al"

should work just fine for you.



Answered By - Inian
Answer Checked By - Senaida (WPSolving Volunteer)