BASH: how to pass a default argument if no arguments after the first were passed
Solution 1
I'd try to use bash variable substitution:
test)
shift
docker exec -it $(docker-compose ps -q web) python manage.py test "${@-apps}"
;;
Other way is to check $*
instead of $1
:
case $* in
bash)
...
test)
docker exec -it $(docker-compose ps -q web) python manage.py test apps
;;
test\ *)
docker exec -it $(docker-compose ps -q web) python manage.py test "${@:2}"
;;
Solution 2
You can just reset your args however you want using set ...
case "$1" in
#...
test)
[ $# -lt 2 ] && set test apps
docker exec -it $(docker-compose ps -q web) python manage.py $@
;;
esac
Solution 3
If arguments do not have spaces or newlines.
Transform the arguments into an string: "$*"
, and use that:
f(){ docker exec -it $(docker-compose ps -q web) "$@"; }
case "$*" in
bash) f /bin/bash ;;
shell) f python manage.py shell ;;
test) f python manage.py test apps ;;
test\ ?*) f python manage.py "$@" ;;
esac
Using a function to manage code (not a variable) and remove repetition.
Solution 4
something like this would work well
if [ -z "$2" ]
then
echo "No argument supplied"
fi
Solution 5
case $1:$# in
(test:1)
docker $(this is bad) python test apps;;
(test:$#)
docker $(still bad) python "$@";;
(bash:$#)
docker ...
esac
Related videos on Youtube
Chops
Updated on September 18, 2022Comments
-
Chops almost 2 years
I have a bash script with a
case
statement in it:case "$1" in bash) docker exec -it $(docker-compose ps -q web) /bin/bash ;; shell) docker exec -it $(docker-compose ps -q web) python manage.py shell ;; test) docker exec -it $(docker-compose ps -q web) python manage.py test "${@:2}" ;; esac
On the
test
command, I want to pass the default argument ofapps
, but only if the user didn't pass any arguments other thantest
to the bash script.So, if the user runs the script like this:
./do test
it should run the command
docker exec -it $(docker-compose ps -q web) python manage.py test apps
However, if they run the script like this:
./do test billing accounts
it should run the command
docker exec -it $(docker-compose ps -q web) python manage.py test billing accounts
How can I test for the existence of arguments after the first argument?
-
jasonwryan over 8 years
[[ $# -ne 1 ]]
... or, more correctly,(( $# != 1 ))
-
-
Chops over 8 yearsDid that edit mess it up? Should there be a
:
in"${@:-apps}"
? -
mikeserv over 8 years@synic - the : will default even for a null valued second argument, and so doesnt answer the question asked. Without the : it will default only if there is no second argument.
-
mikeserv over 8 yearsThe test of $@ doesnt test for two arguments (and the white space would need escaping in the pattern anyway).
-
Costas over 8 years@mikeserv Do you mean to change to
$*
? -
mikeserv over 8 yearsNot exactly. See the comments on BinaryZebra's answer. It still doesnt test for two arguments. It looks for a concatenation of argument(s) that starts with the pattern
test\
. And so if the first argument starts w/test\
it means nothing. Both of you guys should be using?
anyway. But it isnt a robist test regardless. -
mikeserv over 8 yearsTry like:
${#1}:$*
and a pattern like4:test?*
- basically you cannot affirm a second argument based only on a test of either of $* or $@. Its not enough information. -
Olivier Dulac over 8 yearsI'd rather say
[ "$#" -ne "2" ]
, as you could very well pass an empty 2nd argument :myscript foo "" bar baz
# has 4 args, and the arg $2 is empty -
mikeserv over 8 years@OliverDulac - i dont think
[ 2 -ne "$#" ]
is a very useful test here. It negates every number of args but 2. -
Olivier Dulac over 8 years@mikeserv: the poster tests only the 2nd arg, and say "no argument" (without s). If there can be more than 2, then
if [ "$#" -lt 2 ]; then echo "Not enough arguments supplied: you need at least 2"; fi
will be fine. The point of my comment being still the same: testing for the 2nd argument's length doesn't tell you how many arguments were supplied... -
mikeserv over 8 years@OliverDulac - true. The absence of a second argument does, though.
[ "${2+:}" ]
is probably the most simple way to robustly test for 2 or more arguments.