I know that shell scripts just run commands as if they were executed in at the command prompt. I'd like to be able to run shell scripts as if they were functions... That is, taking an input value or string into the script. How do I approach doing this?

up vote 128 down vote accepted

The shell command and any arguments to that command appear as numbered shell variables: $0 has the string value of the command itself, something like script, ./script, /home/user/bin/script or whatever. Any arguments appear as "$1", "$2", "$3" and so on. The count of arguments is in the shell variable "$#".

Common ways of dealing with this involve shell commands getopts and shift. getopts is a lot like the C getopt() library function. shift moves the value of $2 to $1, $3 to $2, and so on; $# gets decremented. Code ends up looking at the value of "$1", doing things using a caseesac to decide on an action, and then doing a shift to move $1 to the next argument. It only ever has to examine $1, and maybe $#.

  • 6
    the C getopt() is an extremely established standard, but the getopt executable is not the same across distro/platform. I'm a now fully converted getopts user, as it is a POSIX standard. It works great with dash also, which is my preferred script shell – TechZilla Feb 10 '12 at 23:40

You can access passed arguments with $n where n is the argument number - 1, 2, 3, .... You pass the arguments just like you would with any other command.

$ cat myscript
echo "First arg: $1"
echo "Second arg: $2"
$ ./myscript hello world
First arg: hello
Second arg: world
$/shellscriptname.sh argument1 argument2 argument3 

You can also pass output of one shell script as an argument to another shell script.

$/shellscriptname.sh "$(secondshellscriptname.sh)"

Within shell script you can access arguments with numbers like $1 for first argument and $2 for second argument and so on so forth.

More on shell arguments

./myscript myargument

myargument becomes $1 inside myscript.

The form

$ ./script.sh "$@" 

is the most convenient for argv. The arg delimiter is whitespace, but can be changed. Don't remember how off-hand. Then use

 $1, $2, shift, if [ $# -ne 3 ] 

to control flow. I don't usually embrace getopts if a case ... esac will suffice.

In the shell script ; it becomes the variable name $1 . The second word becomes the variable name $2 and so on .

cat << 'EOF' > test
echo "First arg: $1"
echo "Second arg: $2"
echo "List of all arg: $@"
sh test hello world

More maybe found in the shell (sh) manual at http://heirloom.sourceforge.net/sh/sh.1.html

  • 2
    welcome to U&L, this hardly add anything to already given answer. – Archemar Sep 20 '17 at 13:26

If you're familiar with Python argparse, and don't mind calling python to parse bash arguments, use bash argparse (https://github.com/mattbryson/bash-arg-parse),

See same answer here: https://stackoverflow.com/questions/7069682/how-to-get-arguments-with-flags-in-bash-script/50181287#50181287

Your Answer


By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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