Improve a script to generally check status of several git repos
Yes there is a better way of filling an array. You can use globbing inside of array parens. Also I suggest being explicit about what you do in bash and use declare -a to declare arrays and later on declare for other variables

declare -a repos=(~/repos/* ~/.vim ~/dot_files ~/bin)


In case of adding stuff to an array, after it got created:

repos+=("more stuff" here)


Maybe you want to name you iterating variable more verbose, instead of d repodir or something.

Your first if contains a continue so you can emphasize on this one and just go on with no else. Also don't miss the double quotes in case of directory names with spaces in them. Also you should check for -d since you cd into it.

if [ -d "$d" ]; then
  echo "No repo at $d"
  continue
fi
cd "$d"


[ ! -z "`cmd`" ] is more verbose than it needs to be. You can just do [ "`cmd`" ].

Read the "Arrays" chapter in the bash manpage.

I attach my test file for this answer which also shows functions and some refactoring which allows to discard this ok variable.

#!/bin/bash
main() {
    local -a repos=(* /foo/bar)
    echo -e "repos: ${repos[@]}"
    for path in "${repos[@]}"; do
      check_repo "$path"
    done
}

check_repo() {
    local path="$1"
    local name="`basename "$path"`"
    local report=""
    if [ ! -d "$path" ]; then
      echo -e "$name\n not a directory: $path"
      return
    fi
    cd "$path"
    if [ "`echo foo 2&gt; /dev/null`" ]; then
        report+="\n oh oh"
    fi
    cd - &gt; /dev/null
    if [ -z "$report" ]; then
        report+="\n OK"
    fi
    echo -e "$name$report"
}

main