0

I have a script "/tmp/SampleScript.sh" with below content:

echo "First arg: $1"
echo "Second arg: $2"

If I run this script as below:

[oracle@xxxxx tmp]$ ./SampleScript.sh FirstParamPassed SecondParamPassed
Output Is:
First arg: FirstParamPassed
Second arg: SecondParamPassed

But if i run this as:

[oracle@xxxxx tmp]$ ./SampleScript.sh SecondParamPassed FirstParamPassed
Output Is:
First arg: SecondParamPassed
Second arg: FirstParamPassed

I want output like this:

echo "First arg: $FirstParamPassed"
echo "Second arg: $FirstParamPassed"
[oracle@xxxxx tmp]$ ./SampleScript.sh SecondParamPassed=2 FirstParamPassed=1
First arg: 1
Second arg: 2

How can I use this type of named variable in REHL shell script. I have gone through this answer Is there a way to avoid positional arguments in bash? but unable to understand how to implement in my case.

Rahul
  • 191
  • 1
  • 11
  • here is another, simpler answer to a similar SO question, which might be easier to adapt than the SO question you mentioned: https://stackoverflow.com/questions/5499472/specify-command-line-arguments-like-name-value-pairs-for-shell-script/43008569#43008569 – landru27 Aug 22 '18 at 13:32

2 Answers2

1

Use environment variables instead. Write your script as

echo "First arg: $FirstParamPassed"
echo "Second arg: $SecondParamPassed"

Then call it as

FirstParamPassed=1 SecondParamPassed=2 ./SampleScript.sh

or

SecondParamPassed=2 FirstParamPassed=1 ./SampleScript.sh

The order of the precommand assignments doesn't matter.

If you enable the -k option before calling the script, you can place the assignments after the script, mimicking your original attempt.

$ set -k
$ ./SampleScript.sh SecondParamPassed=2 FirstParamPassed=1
First arg: 1
Second arg: 2

Again, the order of the assignments does not matter.


You can modify the script to allow the values to be set via positional arguments as well. The positional argument will only be used if the environment variable isn't already set.

: ${FirstParamPassed:=$1}
: ${SecondParamPassed:=$2}
echo "First arg: $FirstParamPassed"
echo "Second arg: $SecondParamPassed"

For example,

$ SecondParamPassed=2 ./SampleScript.sh 6 notused
First arg: 6
Second arg: 2
chepner
  • 497,756
  • 71
  • 530
  • 681
0

Just a simple parser:

#!/bin/bash
for i; do  # this is shorter form of `for i in "$@"`

        case "${i%=*}" in
        a|b|c) ;;
        *) echo "ERROR: unknown variable name '${i%=*}' passed. Only 'a', 'b' and 'c' are supported." >&2; exit 1; ;;
        esac

        declare "$i"
done
echo a="$a"
echo b="$b"
echo c="$c"

Example:

> ./1.sh a=1 b=2 c='!! @@ ## $$ '\''$(echo 123)'\''$(echo 123)'3
a=1
b=2
c=!! @@ ## $$ '$(echo 123)'$(echo 123)3

@edit
I have added a simple check if variable name "${i%=*}" is one of desired variables. Also splitting ${i} on = was not needed.

KamilCuk
  • 120,984
  • 8
  • 59
  • 111
  • You probably want `"${i%%=*}"` instead of `"${i%=*}"` in order to match the longest pattern starting with `=`. – vdavid Aug 22 '18 at 13:58