- How to pass all arguments passed to my Bash script to a function of mine? [duplicate]
- 7 Answers 7
- Passing some arguments:
- Things you probably don’t want to do:
- Bash Beginner Series #3: Passing Arguments to Bash Scripts
- Passing argument to a bash shell script
- Passing multiple arguments to a bash shell script
- Getting creative with arguments in Bash shell
- Bonus Tip: Special variables in Bash shell
How to pass all arguments passed to my Bash script to a function of mine? [duplicate]
Let’s say I have a function abc() that will handle the logic related to analyzing the arguments passed to my script. How can I pass all arguments my Bash script has received to abc() ? The number of arguments is variable, so I can’t just hard-code the arguments passed like this:
Possible duplicate of Propagate all arguments in a bash shell script. (This question was actually posted before the one linked here. But the one in the link has more detailed answers and a more informative title and may be best as the reference question)
7 Answers 7
The $@ variable expands to all command-line parameters separated by spaces. Here is an example.
When using $@ , you should (almost) always put it in double-quotes to avoid misparsing of arguments containing spaces or wildcards (see below). This works for multiple arguments. It is also portable to all POSIX-compliant shells.
It is also worth noting that $0 (generally the script’s name or path) is not in $@ .
The Bash Reference Manual Special Parameters Section says that $@ expands to the positional parameters starting from one. When the expansion occurs within double quotes, each parameter expands to a separate word. That is «$@» is equivalent to «$1» «$2» «$3». .
Passing some arguments:
If you want to pass all but the first arguments, you can first use shift to «consume» the first argument and then pass «$@» to pass the remaining arguments to another command. In Bash (and zsh and ksh, but not in plain POSIX shells like dash), you can do this without messing with the argument list using a variant of array slicing: «$» will get you the arguments starting with «$3» . «$» will get you up to four arguments starting at «$3» (i.e. «$3» «$4» «$5» «$6» ), if that many arguments were passed.
Things you probably don’t want to do:
«$*» gives all of the arguments stuck together into a single string (separated by spaces, or whatever the first character of $IFS is). This looses the distinction between spaces within arguments and the spaces between arguments, so is generally a bad idea. Although it might be ok for printing the arguments, e.g. echo «$*» , provided you don’t care about preserving the space within/between distinction.
Assigning the arguments to a regular variable (as in args=»$@» ) mashes all the arguments together like «$*» does. If you want to store the arguments in a variable, use an array with args=(«$@») (the parentheses make it an array), and then reference them as e.g. «$» etc. Note that in Bash and ksh, array indexes start at 0, so $1 will be in args[0] , etc. zsh, on the other hand, starts array indexes at 1, so $1 will be in args[1] . And more basic shells like dash don’t have arrays at all.
Leaving off the double-quotes, with either $@ or $* , will try to split each argument up into separate words (based on whitespace or whatever’s in $IFS ), and also try to expand anything that looks like a filename wildcard into a list of matching filenames. This can have really weird effects, and should almost always be avoided. (Except in zsh, where this expansion doesn’t take place by default.)
Bash Beginner Series #3: Passing Arguments to Bash Scripts
In the third part of the Bash Beginner Series, you’ll learn to pass arguments to a bash shell script. You’ll also learn about special bash shell variables.
Arguments can be useful, especially with Bash!
So far, you have learned how to use variables to make your bash scripts dynamic and generic, so it is responsive to various data and different user input.
In this tutorial, you will learn how you can pass variables to a bash scripts from the command line.
Passing argument to a bash shell script
The following script count_lines.sh will output the total number of lines that exist in whatever file the user enters:
#!/bin/bash echo -n "Please enter a filename: " read filename nlines=$(wc -l < $filename) echo "There are $nlines lines in $filename"
For example, the user can enter the file /etc/passwd and the script will spit out the number of lines as a result:
This script works fine; however, there is a much better alternative!
Instead of prompting the user for the filename, we can make the user simply pass the filename as a command line argument while running the script as follows:
The first bash argument (also known as a positional parameter) can be accessed within your bash script using the $1 variable.
So in the count_lines.sh script, you can replace the filename variable with $1 as follows:
Notice that I also got rid of the read and first echo command as they are no longer needed!
Finally, you can run the script and pass any file as an argument:
./count_lines.sh /etc/group There are 73 lines in /etc/group
Passing multiple arguments to a bash shell script
You can pass more than one argument to your bash script. In general, here is the syntax of passing multiple arguments to any bash script:
The second argument will be referenced by the $2 variable, the third argument is referenced by $3 , .. etc.
The $0 variable contains the name of your bash script in case you were wondering!
Now we can edit our count_lines.sh bash script so that it can count the lines of more than one file:
You can now run the script and pass three files as arguments to the bash script:
As you can see, the script outputs the number of lines of each of the three files; and needless to say that the ordering of the arguments matters, of course.
Getting creative with arguments in Bash shell
Some of them are a bit complicated as they may have long syntax or a long array of options that you can use.
Fortunately, you can use bash arguments to turn a hard command into a pretty easy task!
To demonstrate, take a look at the following find.sh bash script:
#!/bin/bash find / -iname $1 2> /dev/null
It’s a very simple script that yet can prove very useful! You can supply any filename as an argument to the script and it will display the location of your file:
You see how this is now much easier than typing the whole find command! This is a proof that you can use arguments to turn any long complicated command in Linux to a simple bash script.
If you are wondering about the 2> /dev/null , it means that any error message (like file cannot be accessed) won't be displayed on the screen. I suggest reading about stderr redirection in Linux to get more knowledge on this topic.
Bonus Tip: Special variables in Bash shell
Bash has a lot of built-in special variables that are quite handy and are available at your disposal.
The table below highlights the most common special built-in bash variables:
Special Variable | Description |
---|---|
$0 | The name of the bash script. |
$1, $2. $n | The bash script arguments. |
$$ | The process id of the current shell. |
$# | The total number of arguments passed to the script. |
[email protected] | The value of all the arguments passed to the script. |
$? | The exit status of the last executed command. |
$! | The process id of the last executed command. |
To see these special variables in action; take a look at the following variables.sh bash script:
You can now pass any arguments you want and run the script:
Alright, this brings us to the end of this chapter. I hope you now realize how powerful and useful bash arguments can be.
Need some practice, download this PDF and practice passing arguments to bash scripts with simple scripting challenges. Their solutions are also included.