aarelovich
aarelovich

Reputation: 5566

Bash script not working as expected. Wrong file listing behaviour

I've been following this tutorial (the idea can also be found in other posts of SO)

http://www.cyberciti.biz/faq/bash-loop-over-file/

This is my test script:

function getAllTests {

   allfiles=$TEST_SCRIPTS/*

   # Getting all stests in the 
   if [[ $1 == "s" ]]; then
      for f in $allfiles 
      do
         echo $f
      done
   fi
}

The idea is to print all files (one per line) in the directory found in TEST_SCRIPTS.

Instead of that this is what I get as an output:

/path/to/dir/*

(The actual path obviously, but this is to convey the idea).

I have tried the followign experiment on bash. Doing this

a=(./*)

And this read me all files in the current directory into a as an array. However if anything other than ./ is used then it does not work.

How can I use this procedure with a directory other than ./?

Upvotes: 1

Views: 142

Answers (1)

tripleee
tripleee

Reputation: 189507

When there are no matches, the wildcard is not expanded.

I speculate that TESTSCRIPTS contains a path which does not exist; but without access to your code, there is obviously no way to diagnose this properly.

Common solutions include shopt -s nullglob which causes the shell to replace the wildcard with nothing when there are no matches; and explicitly checking for the expanded value being equal to the wildcard (in theory, this could misfire if there is a single file named literally * so this is not completely bulletproof!)

By the by, the allfiles variable appears to be superfluous, and you should generally be much more meticulous about quoting. See When to wrap quotes around a shell variable? for details.

function getAllTests {
   local nullglob
   shopt -q nullglob || nullglob=reset
   shopt -s nullglob
   # Getting all stests in the         # fix sentence fragment?
   if [[ $1 == "s" ]]; then
      for f in "$TEST_SCRIPTS"/*; do   # notice quotes
         echo "$f"                     # ditto
      done
   fi
   # Unset if it wasn't set originally
   case $nullglob in 'reset') shopt -u nullglob;; esac
}

Setting and unsetting nullglob inside a single function is probably excessive; most commonly, you would set it once at the beginning of your script, and then write the script accordingly.

Upvotes: 3

Related Questions