Script parameters in Bash


Linux Problem Overview

I'm trying to make a shell script which should be used like this: -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:

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?

Linux Solutions

Solution 1 - Linux

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:

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

You'll get:

$0    #
$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: /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 - Linux

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} ;;

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: -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 - Linux

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 - Linux

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++)); 

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

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

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

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

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

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

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


Rationale: I included a 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 - Linux

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:

./ some_source_file.png destination_file.txt

Explanation on double quotes;

consider three scripts:

bash $1

# cat
bash "$1"

echo "1-$1" "2-$2"

Now invoke:

$ bash "a b"
1-a 2-b

$ bash "a b"
1-a b 2-

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


All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKristofferView Question on Stackoverflow
Solution 1 - LinuxgitaarikView Answer on Stackoverflow
Solution 2 - LinuxManny DView Answer on Stackoverflow
Solution 3 - LinuxStianEView Answer on Stackoverflow
Solution 4 - Linuxuser1628658View Answer on Stackoverflow
Solution 5 - LinuxJakub M.View Answer on Stackoverflow