Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Given a program that requires some parameters, e.g. program -in file.in -out file.out, what would be the simple-most approach to write a bash script that could be called with or without any of these parameters and use default values for each?

script -in otherfile would run program -in otherfile -out file.out,
script -out otherout -furtherswitch would run program -in file.in -out otherout -furtherswitch etc.

share|improve this question
up vote 5 down vote accepted

A default value is easy to define in Bash:

foo="${bar-default}" # Sets foo to the value of $bar if defined, "default" otherwise
foo="${bar:-default}" # Sets foo to the value of $bar if defined or empty, "default" otherwise

To process your parameters, you can use a simple loop:

while true
    case "${1-}" in
            shift 2
            shift 2

program -in "${infile-otherfile}" -out "${outfile-otherout}" "$@"

Useful reads:

I also recommend using getopt instead, because it is able to handle many special cases which would very quickly complicate and clutter your code (Non-trivial example).

share|improve this answer
Thanks! A while $# -gt 0 (or similar) and *) others="${others-} $1"; shift 1 ;; would survive other parameters before the default-able ones. But maybe I should learn getopt instead... – Tobias Kienzler Feb 7 '13 at 11:12
Of course I could also simply write a python script... – Tobias Kienzler Feb 7 '13 at 11:24

l0b0's answer shows how to set a default value through assignment and checking another variable's state (although, of course, you can also do this operating on the same variable you are assigning to), but there is a more concise way to do the same thing:

: "${foo=bar}" # $foo = bar if $foo is unset
: "${foo:=bar}" # $foo = bar if $foo is unset or empty
share|improve this answer
  • Pass all parameters ($*) passed to script to program too
  • Check each parameter you interested, if it's already in parameters passed, then ignore it. otherwise use default parameter value

Sample code

interested_parameter_names=(-in -out)
default_parameter_values=(file.in file.out)

cmd="$program $*"

for ((index=0; index<${#interested_parameter_names[*]}; index++))
    if [ "${*#*$param}" == "$*" ]   # if $* not contains $param
        cmd="$cmd $param $default_value"

echo "command line will be:"
echo "$cmd"

echo "execute result:"

You can easily add more default parameters/values by add more array element in $interested_parameter_names and $default_parameter_values

Sample output

$ ./wrapper.sh -in non-default.txt -other-params
command line will be:
echo -in non-default.txt -other-params -out file.out

execute result:
-in non-default.txt -other-params -out file.out


When passing parameters which contains space, it should be escaped by \, not just quoted them. Example:

./script -in new\ document.txt
share|improve this answer
Neat! I think the quotes issue can be solved by using $@ instead of $*. What does ${*#*$param} do? – Tobias Kienzler Feb 7 '13 at 11:23
@TobiasKienzler, "${*#*$param}" == "$*" is used to check if $* NOT contains $param, it's Remove Smallest Prefix Pattern parameter expansion. – LiuYan 刘研 Feb 7 '13 at 11:28
./script -in new\ document.txt would not work, and there's not way to make it work with that flawed approach. By concatenating the arguments into a string, you're losing the information about how those arguments are separated. – Stéphane Chazelas Feb 7 '13 at 13:02

You have two ways, as usual, simple and hard. Simple is to use inner variables, for example

program -in otherfile -out file.out

Here variable are

$0 = The script name
$1 = -in
$2 = otherfile, etc.

The Hard way is to use getopt, more information you can find here.

share|improve this answer
Using $1 etc will fail if I omit parameters, and manually parsing them would be annoying. Is there no midway between that and getopt? – Tobias Kienzler Feb 7 '13 at 10:23

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.