Is there a straightforward way to display the results of my PS1 for a given set of directories?

To avoid the XY Problem, I'll state up front: I want to rapidly check the status of every git repo within a directory. I can run git status in a for ... do ... done loop, but that is hard to read.

I have oh-my-git running beautifully as part of my command prompt and it displays the status I'd like to know at a glance. I'd like to see what it says for every sub-directory in my repos directory.

I can see what I need by manually calling cd ~/repos/first-repo followed by the next, but besides the repetitive typing, I also have to remember all of the repos without skipping one. I'd be happy to script out cding into each repo and displaying my customized prompt.

for rep in */; do
    printf '%s:\t' "$rep"
    ( cd "$rep" && git status --short --branch --untracked-files=no )

or, using short options,

for rep in */; do
    printf '%s:\t' "$rep"
    ( cd "$rep" && git status -sbuno )

This changes into each directory in the current directory and runs the given git status command. The output may look something like

gnomad_browser/:        ## master...origin/master
swefreq-browser/:       ## gnomad-remerge...origin/gnomad-remerge
swefreq-config/:        ## develop...origin/develop
swefreq/:       ## feature/schema-update...origin/feature/schema-update
 M sql/swefreq.sql

(I have an uncommitted file in the swefreq repository)

The options picked for git status here will show just the current branch and any modified files, but you could easily modify it to show untracked files as wull by removing -uno or --untracked-files=no.

See git status --help.

Your idea of using the prompt to show you info about each directory may work depending on how your prompt is set up. My prompt is a single-quoted string that must be evaluated:

for rep in */; do
    ( cd "$rep" && eval echo "$PS1" )

I do not think that this is a very nice solution, and it's also not very flexible in what it can do and tell you about each repository.

  • eval is something I wasn't thinking of, and seems to be what I'd like to use, but it chokes on my complex PS1. It's probably the font-awesome icons included, which is the point. – Dane Sep 25 '17 at 12:55
  • 1
    I'm glad I included my XY problem clarification because your solution provides 90% of the value I was looking for. I'm changing the string formatting to printf '%-28s' "$rep" for myself, but that's pretty nice. Thank you! – Dane Sep 25 '17 at 12:58

Looking at oh-my-git, it seems to need you to do something like this in a shell script:

source ~/.oh-my-git/prompt.sh
for d in dir1 dir2...
do cd "$d"
   bash_prompt      # recalculate PS1 value
   echo -en "$PS1"
  • Here's what I get when I try echo -en "$PS1": imagebin.ca/v/3bddQYqoj7Ik – Dane Sep 25 '17 at 19:40
  • I'm using the usual gnu echo command with option -e which interprets \e as the escape character. For example, echo -en '\e'|od -c yields octal code 033. Perhaps you have another echo command earlier in your PATH? If you cannot find a suitable echo you might try printf "$PS1", as it should interpret the \e when in the format arg, though if you have any % in the string that would be awkward, and you would need printf "${PS1//%/%%}". – meuh Sep 26 '17 at 6:49

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.