19

How can I assign a value to a positional parameter in Bash? I want to assign a value to a default parameter:

if [ -z "$4" ]; then
   4=$3
fi

Indicating that 4 is not a command.

Cyrus
  • 69,405
  • 13
  • 65
  • 117
Freeman
  • 5,246
  • 2
  • 41
  • 46

3 Answers3

33

The set built-in is the only way to set positional parameters

$ set -- this is a test
$ echo $1
this
$ echo $4
test

where the -- protects against things that look like options (e.g. -x).

In your case you might want:

if [ -z "$4" ]; then
   set -- "$1" "$2" "$3" "$3"
fi

but it would probably be more clear as

if [ -z "$4" ]; then
   # default the fourth option if it is null
   fourth="$3"
   set -- "$1" "$2" "$3" "$fourth"
fi

you might also want to look at the parameter count $# instead of testing for -z.

msw
  • 40,500
  • 8
  • 77
  • 106
3

You can do what you want by calling your script again with a fourth parameter:

if [ -z "$4" ]; then
   $0 "$1" "$2" "$3" "$3"
   exit $?
fi
echo $4

Calling above script like ./script.sh one two three will output:

three

Mr. Llama
  • 18,561
  • 2
  • 47
  • 99
Nelson
  • 43,933
  • 8
  • 62
  • 77
  • `./$0` will not work if the script is accessed via PATH, `$0` should be okay by itself which would work for `./script` and `/usr/local/bin/script`, etc. – msw Dec 07 '12 at 12:04
1

This can be done with an assignment directly into an auxiliary array with an export/import type mechanism:

set a b c "d e f" g h    
thisArray=( "$@" )
thisArray[3]=4
set -- "${thisArray[@]}"
echo "$@"

outputs 'a b c 4 g h'

Brian Chrisman
  • 2,732
  • 1
  • 12
  • 14