Bash special variables

This is more some kind of “note-to-self”, than a blog post.

All credit goes to the guys who answered this Stackoverflow question explaining different bash variables that we now and then need to look up again.

  • $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.
  • $_ last argument of last command
  • $* / $@ list of arguments passed to script as string / delimited list

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

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

Bash ‘help’

Some commands you type in the shell are actually not binaries but shell (bash for example) buitins. For example, “alias” is such an shell builtin.

~# type alias

alias is a shell builtin

~# man alias

No manual entry for alias

In order to obtain more information about the “alias” builtin, you should type “man bash” and search what you are looking for in the hundreds of pages long man.

However, there is a quicker way! “help” helps you:

~# help alias

alias: alias [-p] [name[=value] … ]

    Define or display aliases.

    Without arguments, `alias’ prints the list of aliases in the reusable

    form `alias NAME=VALUE’ on standard output.

    Otherwise, an alias is defined for each NAME whose VALUE is given.

    A trailing space in VALUE causes the next word to be checked for

    alias substitution when the alias is expanded.    


      -p Print all defined aliases in a reusable format

    Exit Status:

    alias returns true unless a NAME is supplied for which no alias has been



Execute sudo from a cron script

Recently I bumped into this problem, and I wanted to share it’s easy solution:

Say you want to execute:

0 6 * * * /home/oraias/cron/


PID=$(ps aux | grep tomcat8 | grep -v grep | tr -s ” ” | cut -d” ” -f2)
kill -9 $PID
sleep 5
sudo systemctl start tomcat8

Each day at 6AM cron launches this script. It looks up the PID of a Java process with “tomcat8” in it’s argument list. Kills the process and starts it again. Since this script is being launched as a non-root user, sudo is required for systemctl operation (assuming you configured the sudoers file).

It might happen that the last line of the script silently fails. If this is also your case, check the following options in /etc/sudoers (make sure to open it with sudoedit):

# Disable “ssh hostname sudo <cmd>”, because it will show the password in clear.
# You have to run “ssh -t hostname sudo <cmd>”.
Defaults requiretty

# Refuse to run if unable to disable echo on the tty. This setting should also be
# changed in order to be able to use sudo without a tty. See requiretty above.
Defaults !visiblepw

Since cron doesn’t launch any TTY, the above options cause sudo to fail silently.

Comment out both to change this behavior.


4 years later

4 years have passed since my last post here. Oh yeah, I hear you thinking…that’s a loooong time. True, it is.

I have been doing a lot of different stuff in these last 4 years, I changed jobs, ended up in different projects, started a webshop (, got into Adwords, Analytics, marketing online, cloud computing and in the meantime also had another lovely daughter. Quite busy to be honest 🙂

Today seems like the perfect day to get back behind my keyboard and continue writing down those volatile snapshots of my mind 🙂