942

In Bash, there appear to be several variables which hold special, consistently-meaning values. For instance,

./myprogram &; echo $!

will return the PID of the process which backgrounded myprogram. I know of others, such as $? which I think is the current TTY. Are there others?

Matthias Braun
  • 32,039
  • 22
  • 142
  • 171
Z Douglas
  • 9,531
  • 3
  • 16
  • 9
  • 24
    Several of them are not Bash-only. They're also used in other Bourne-related shells and in fact are specified by [POSIX](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_05_02). – Dennis Williamson Mar 02 '11 at 05:22
  • 1
    What about: IFS=$'\n' See: http://stackoverflow.com/questions/4128235/what-is-the-exact-meaning-of-ifs-n – sgu Apr 03 '17 at 22:20
  • 1
    @sgu That's not a parameter; that's a special type of quoting. `$'\n'` is a literal newline character that result from replacing the digraph `\n` with ASCII 10. – chepner Mar 25 '19 at 16:37
  • 3
    If you came here looking for `${1}`, `${*}`, etc, the braces are just for disambiguation, and often redundant. In isolation, `${x}` is exactly equivalent to `$x`. – tripleee Jul 21 '19 at 07:58
  • for `$IFS` see [What is the exact meaning of `IFS=$'\n'`](https://stackoverflow.com/questions/4128235/what-is-the-exact-meaning-of-ifs-n/66942306#66942306) – Peyman Mohamadpour Apr 04 '21 at 15:59
  • `$?` is not the `TTY` - it is the return value of the last executed command.`tty` is the simple command for it. – Timo Oct 16 '22 at 10:24

4 Answers4

1630
  • $1, $2, $3, ... are the positional parameters.
  • "$@" is an array-like construct of all positional parameters, {$1, $2, $3 ...}.
  • "$*" is the IFS expansion of all positional parameters, $1 $2 $3 ....
  • $# is the number of positional parameters.
  • $- current options set for the shell.
  • $$ pid of the current shell (not subshell).
  • $_ most recent parameter (or the abs path of the command to start the current shell immediately after startup).
  • $IFS is the (input) field separator.
  • $? is the most recent foreground pipeline exit status.
  • $! is the PID of the most recent background command.
  • $0 is the name of the shell or shell script.

Most of the above can be found under Special Parameters in the Bash Reference Manual. Here are all the environment variables set by the shell.

For a comprehensive index, please see the Reference Manual Variable Index.

Matthias Braun
  • 32,039
  • 22
  • 142
  • 171
kojiro
  • 74,557
  • 19
  • 143
  • 201
  • 5
    They are all documented in the `bash` man page. The only oddity is that `$_` is only mentioned in the context of its use in the `MAILPATH` variable. – chepner Jul 17 '12 at 01:41
  • 8
    @chepner look in `man(1) bash` under *Special Parameters* for the rest of the definition of `$_`. – kojiro Jul 17 '12 at 12:52
  • 10
    I use `!$` instead of `$_` in bash scripts, because the latter sometimes fails. –  Sep 03 '12 at 03:57
  • 3
    @amc: See https://unix.stackexchange.com/questions/271659/vs-last-argument-of-the-preceding-command-and-output-redirection for differences between `!$` and `$_`. – tricasse Apr 20 '17 at 17:54
  • see [this thread](https://stackoverflow.com/questions/17984958/what-does-it-mean-in-shell-when-we-put-a-command-inside-dollar-sign-and-parenthe) for a discussion on `$(...)` operations – Christiaan Herrewijn Aug 03 '20 at 10:24
  • What is the variable for the PID of the last command, not background? – Timo Sep 09 '20 at 15:50
  • 2
    @Timo how can you ask the shell for a pid if the command is not in the background? – kojiro Sep 09 '20 at 17:36
  • @kojiro, thanks, with history, used in [atop](https://unix.stackexchange.com/a/146314/72988). But it stores it in a file, so there is no `$..` variable. – Timo Sep 10 '20 at 07:33
  • `$$` doubles up as a good random number generator! Well, sort of random. – Sridhar Sarnobat Mar 17 '21 at 04:16
  • is there any difference where you used double inverted comas? I am referring to `"$@"` and `"$*"`. – M.Ionut Jun 18 '22 at 10:59
53
  • $_ last argument of last command
  • $# number of arguments passed to current script
  • $* / $@ list of arguments passed to script as string / delimited list

off the top of my head. Google for bash special variables.

Dan
  • 3,490
  • 2
  • 22
  • 27
  • 147
    "I did. They sent me here." -- Bookshop skit (official doc: http://www.gnu.org/software/bash/manual/bashref.html#Special-Parameters) – greggo Feb 05 '13 at 17:58
  • 1
    I think `$@` is the string and `$*` is the delimited list (according to the above accepted answer, anyways). – RastaJedi Aug 20 '16 at 19:02
  • 1
    @RastaJedi: `"$@"` expands to a list, `"$*"` expands to a single string. The special behavior of `$@` applies when it's within double quotes. – Keith Thompson Apr 05 '18 at 16:25
  • 17
    Downvoted because this is not a very complete or helpful answer. Saying "Google it" shows a lack of effort, especially considering that the vast majority of people end up here from Google search. I think the least you could do is add links to official documentation. TBH, the only reason I didn't flag it for deletion was because it is at least a _partial_ answer to the question. I know it's old, but please consider editing it to provide more detail. – Sean the Bean Sep 11 '18 at 20:17
27

To help understand what $#, $0 and $1, ..., $n do, I use this script:

#!/bin/bash

for ((i=0; i<=$#; i++)); do
  echo "parameter $i --> ${!i}"
done

Running it returns a representative output:

$ ./myparams.sh "hello" "how are you" "i am fine"
parameter 0 --> myparams.sh
parameter 1 --> hello
parameter 2 --> how are you
parameter 3 --> i am fine
Matthias Braun
  • 32,039
  • 22
  • 142
  • 171
fedorqui
  • 275,237
  • 103
  • 548
  • 598
  • 8
    What does the !i mean in your for loop? That's actually why I'm here and I can't find an answer anywhere because I don't know what to call it. – Anthony Oct 12 '16 at 19:47
  • 10
    @Anthony this is called [variable indirection](https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html). You can find a good explantion of his usage in [bash: indirect expansion, please explain?](http://stackoverflow.com/a/8515492/1983854). – fedorqui Oct 12 '16 at 21:35
4

Take care with some of the examples; $0 may include some leading path as well as the name of the program. Eg save this two line script as ./mytry.sh and the execute it.

#!/bin/bash

echo "parameter 0 --> $0" ; exit 0

Output:

parameter 0 --> ./mytry.sh

This is on a current (year 2016) version of Bash, via Slackware 14.2

asachet
  • 6,620
  • 2
  • 30
  • 74
  • 6
    Whether $0 does include a path or not depends on how you ran the script in the first place. If you executed "./mytry.sh" that's what you will see in $0. If you entered "~/mytry.sh" you will see the full path (because the shell will have expanded ~). If you did ". mytry.sh" you will see 'bash'. – Steve Folly Oct 30 '17 at 16:23