for
doesn't iterate over the contents of directories, it iterates over a series of "words" (basically, strings). Thus, this statement:
for var in alice bob "jimmy joe" /c/Projects/mainproject; do
...will run its contents four times, first with var
set to "alice", then "bob", then "jimmy joe", then "/c/Projects/mainproject". It doesn't treat any of those as file or directory names, because you didn't ask it to. On the other hand, the shell will expand /c/Projects/mainproject/*
to a list of files in the directory /c/Projects/mainproject/ (including the path prefix). Thus, you could use:
for repoFolder in "$SIMPROJS"/*; do
The wildcard string will expand to a series of words (corresponding to the files and directories under /c/Projects/mainproject/), and then for
will iterate over those.
Note the double-quotes around the variable reference? It's almost always a good idea to do this, otherwise the shell will split the variable's contents into separate words based on spaces (or whatever's in the IFS
variable), and expand wildcards in the variable's value, and you usually don't want that (and if it happens unexpectedly, it can cause trouble). On the other hand, the *
has to be outside the double-quotes so it'll expand to a list of files, not just be treated as a literal filename.
Also, note that this will iterate over files as well as subdirectories in /c/Projects/mainproject. If you want just subdirectories, use this:
for repoFolder in "$SIMPROJS"/*/; do
The added trailing slash will restrict it to just matching directories (because a slash at the end of a directory's path makes sense, but at the end of a plain file's path it doesn't). But note that the trailing slash will get included in the resulting paths as well.
Other notes: don't use "$SIMPROJS/$repoFolder"
etc -- the repoFolder
variable already includes the path prefix (because it was included in the wildcard string that got expanded), so adding it again will cause trouble. Just use "$repoFolder"
.
Also, when you use cd
in a script, you should always include error handling in case it fails for some reason. Otherwise, the script will continue running in the wrong place, probably leading to chaos. You use:
cd "$SIMPROJS/$repoFolder" && echo "Now inside $SIMPROJS/$repoFolder"
...if this fails (which it will because of the path-doubling problem), it will not print the "Now inside..." message, but will then continue on with everything else. What you should use is something more like this:
cd "$repoFolder" || {
echo "Couldn't cd into $repoFolder, cancelling..." >&2
return 1
}
...which will exit the function rather than blindly continuing in the wrong place.
BTW, shellcheck.net is good at spotting common problems like these; I recommend running your scripts through it, at least until you get more familiar with shell scripting.