0
#!/bin/bash

traverse() {
local x=$1
if [ -d $x ]
then
lst=(`ls $x`)
for((i=${#lst[@]}; --i;)); do
    echo "${lst[i]}"
    done
else echo "not a directory"
fi
}

traverse

I want to pass a parameter such as "/path/to/this/directory/" when executing program but only works if I'm running the program in the same directory as my bash script file and any other parameter I pass is completely ignored.

the script is supposed to take a parameter and check if it's a directory and if it's a directory then list all the files/folders in descending order. If not display error message.

What is wrong with code, thanks!

3 Answers 3

3

This happens because $1 in the function refers to traverse's parameters, not your script's parameters.

To run your function once with each argument, use

for arg in "$@"   # "$@" is also the default, so you can drop the 'in ..'
do
  traverse "$arg"
done

If you in the future want to pass all the script's parameters to a function, use

myfunc "$@"

This is just the problem at hand, though. Other problems include not quoting your variables and using command expansion of ls, lst=(`ls $x`), instead of globs, lst=( "$x"/* )

Sign up to request clarification or add additional context in comments.

1 Comment

@[that other guy] thanks very helpful information! now runs as I expected!
3

You don't need to call ls for that. You can use this code:

traverse() {
    local x="$1"
    if [ -d "$x" ]; then
        arr=( "$x/"* )
        for ((i=${#arr[@]}; i>0; i--)); do
           echo "${arr[$i]}"
        done
    else
        echo "not a directory"
    fi
}

Comments

0

"That other guy" has the right answer. The reason it always looks at the current directory:

  1. you invoke traverse with no arguments
  2. the $1 in the traverse function is empty, therefore $x is empty
  3. the test is therefore [ -d ], and when [ is given 1 argument, it returns success if the argument is not empty. Your if command always executes the "true" block and ls $x is just ls when x is empty

Use [[ ... ]] with bash: it is smarter about empty arguments. Otherwise, quote your variables:

$ x=; [ -d $x ] && echo always true || echo not a directory
always true
$ x=; [[ -d $x ]] && echo always true || echo not a directory
not a directory
$ x=; [ -d "$x" ] && echo always true || echo not a directory
not a directory

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.