1
\$\begingroup\$

The idea is simple, most people have some one directory containing all their projects as subdirectories. When you are in the top directory and you run this script like so for-each-git.sh git status it will run the command git status in each of the folders. I have another script called git-ffwd that fetches all remotes and fast forward updates them which I usually run each morning with this script.

#!/bin/bash
for dir in $(find . -maxdepth 1 -type d); do
    (
        cd ${dir}
        if [ -d ".git" ]; then
            pwd
            "$@"
            echo
        fi
    )
done

Some explanation:

  • The parenthesis is so we are able to easily go back to the project directory in case the commands you push in run cd or something. (It makes a subshell.)
  • pwd is so we know for sure which directory is being worked on and the echo is just so a new line separates everything a little more.

I know this is a small script but I am new-ish to writing Bash scripts and want to learn.

The lines pwd; "$@"; echo seem a little ugly, though they do work. Also I can't pass multiple commands in with a ; like echo hey; echo bye because the ; ends the statement in the "$@" line, so I am wondering if there's a better way to write that line (or pass them in).

\$\endgroup\$
2
\$\begingroup\$

Instead of using find and testing whether .git is a directory, you could make a simplification:

for git_dir in */.git ; do
(
    cd "$git_dir/.." &&
    pwd &&
    $@
    echo
)
done

Admittedly, this causes an error when .git exists but is not a directory:

-bash: cd: blah/.git/..: Not a directory

… instead of silently skipping that entry as your script does. But I would consider the error message to be a feature, not a bug. =) Note my use of && after cd to ensure that the command is not executed if the cd fails. (That could happen if the directory lacks the executable bit.)

If you wanted to support compound commands like echo hey; echo bye, you could use eval $@. Using eval feels a bit risky, but it's OK if the script is for your own personal use and won't be attacked.

\$\endgroup\$
  • \$\begingroup\$ Why is eval risky? I understand what you mean about personal use but I don't get why $@ is less dangerous than eval $@. \$\endgroup\$ – Captain Man Nov 14 '16 at 20:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.