Script parameters in Bash

183,498

Solution 1

The arguments that you provide to a bashscript will appear in the variables $1 and $2 and $3 where the number refers to the argument. $0 is the command itself.

The arguments are seperated by spaces, so if you would provide the -from and -to in the command, they will end up in these variables too, so for this:

./ocrscript.sh -from /home/kristoffer/test.png -to /home/kristoffer/test.txt

You'll get:

$0    # ocrscript.sh
$1    # -from
$2    # /home/kristoffer/test.png
$3    # -to
$4    # /home/kristoffer/test.txt

It might be easier to omit the -from and the -to, like:

ocrscript.sh /home/kristoffer/test.png /home/kristoffer/test.txt

Then you'll have:

$1    # /home/kristoffer/test.png
$2    # /home/kristoffer/test.txt

The downside is that you'll have to supply it in the right order. There are libraries that can make it easier to parse named arguments on the command line, but usually for simple shell scripts you should just use the easy way, if it's no problem.

Then you can do:

/usr/local/bin/abbyyocr9 -rl Swedish -if "$1" -of "$2" 2>&1

The double quotes around the $1 and the $2 are not always necessary but are adviced, because some strings won't work if you don't put them between double quotes.

Solution 2

If you're not completely attached to using "from" and "to" as your option names, it's fairly easy to implement this using getopts:

while getopts f:t: opts; do
   case ${opts} in
      f) FROM_VAL=${OPTARG} ;;
      t) TO_VAL=${OPTARG} ;;
   esac
done

getopts is a program that processes command line arguments and conveniently parses them for you.

f:t: specifies that you're expecting 2 parameters that contain values (indicated by the colon). Something like f:t:v says that -v will only be interpreted as a flag.

opts is where the current parameter is stored. The case statement is where you will process this.

${OPTARG} contains the value following the parameter. ${FROM_VAL} for example will get the value /home/kristoffer/test.png if you ran your script like:

ocrscript.sh -f /home/kristoffer/test.png -t /home/kristoffer/test.txt

As the others are suggesting, if this is your first time writing bash scripts you should really read up on some basics. This was just a quick tutorial on how getopts works.

Solution 3

Use the variables "$1", "$2", "$3" and so on to access arguments. To access all of them you can use "$@", or to get the count of arguments $# (might be useful to check for too few or too many arguments).

Solution 4

I needed to make sure that my scripts are entirely portable between various machines, shells and even cygwin versions. Further, my colleagues who were the ones I had to write the scripts for, are programmers, so I ended up using this:

for ((i=1;i<=$#;i++)); 
do

    if [ ${!i} = "-s" ] 
    then ((i++)) 
        var1=${!i};

    elif [ ${!i} = "-log" ];
    then ((i++)) 
        logFile=${!i};  

    elif [ ${!i} = "-x" ];
    then ((i++)) 
        var2=${!i};    

    elif [ ${!i} = "-p" ]; 
    then ((i++)) 
        var3=${!i};

    elif [ ${!i} = "-b" ];
    then ((i++)) 
        var4=${!i};

    elif [ ${!i} = "-l" ];
    then ((i++)) 
        var5=${!i}; 

    elif [ ${!i} = "-a" ];
    then ((i++)) 
        var6=${!i};
    fi

done;

Rationale: I included a launcher.sh script as well, since the whole operation had several steps which were quasi independent on each other (I'm saying "quasi", because even though each script could be run on its own, they were usually all run together), and in two days I found out, that about half of my colleagues, being programmers and all, were too good to be using the launcher file, follow the "usage", or read the HELP which was displayed every time they did something wrong and they were making a mess of the whole thing, running scripts with arguments in the wrong order and complaining that the scripts didn't work properly. Being the choleric I am I decided to overhaul all my scripts to make sure that they are colleague-proof. The code segment above was the first thing.

Solution 5

In bash $1 is the first argument passed to the script, $2 second and so on

/usr/local/bin/abbyyocr9 -rl Swedish -if "$1" -of "$2" 2>&1

So you can use:

./your_script.sh some_source_file.png destination_file.txt

Explanation on double quotes;

consider three scripts:

# foo.sh
bash bar.sh $1

# cat foo2.sh
bash bar.sh "$1"

# bar.sh
echo "1-$1" "2-$2"

Now invoke:

$ bash foo.sh "a b"
1-a 2-b

$ bash foo2.sh "a b"
1-a b 2-

When you invoke foo.sh "a b" then it invokes bar.sh a b (two arguments), and with foo2.sh "a b" it invokes bar.sh "a b" (1 argument). Always have in mind how parameters are passed and expaned in bash, it will save you a lot of headache.

Share:
183,498
Kristoffer
Author by

Kristoffer

Updated on July 16, 2022

Comments

  • Kristoffer
    Kristoffer almost 2 years

    I'm trying to make a shell script which should be used like this:

    ocrscript.sh -from /home/kristoffer/test.png -to /home/kristoffer/test.txt
    

    The script will then ocr convert the image file to a text file. Here is what I have come up with so far:

    #!/bin/bash
    export HOME=/home/kristoffer
    /usr/local/bin/abbyyocr9 -rl Swedish -if ???fromvalue??? -of ???tovalue??? 2>&1
    

    But I don't know how to get the -from and -to values. Any ideas on how to do it?

  • CJBS
    CJBS over 9 years
    I like this. I'm adding a section at the end ` else echo "Invalid argument: ${!i}" ((i++)) fi `
  • Zelphir Kaltstahl
    Zelphir Kaltstahl about 8 years
    This seems to be a readable solution. How would you specify two flags then?
  • h_s
    h_s almost 7 years
    @Zelphir, you can specify two or more flags simply ommiting the ":" after the flag. For instance f:t:vs will be -f some_f -t some_t -v -s