Reputation: 7
#!/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!
Upvotes: 0
Views: 103
Reputation: 246807
"That other guy" has the right answer. The reason it always looks at the current directory:
traverse
with no arguments$1
in the traverse function is empty, therefore $x
is empty[ -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 emptyUse [[ ... ]]
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
Upvotes: 0
Reputation: 785128
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
}
Upvotes: 3
Reputation: 123470
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"/* )
Upvotes: 3