When bash is invoked as an interactive login shell, or as a non interactive shell with the --login option, it first reads and exe cutes commands from the file /etc/profile, if that file exists. After reading that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and exe cutes commands from the first one that exists and is readable. The --noprofile option may be used when the shell is started to inhibit this behavior.
When a login shell exits, bash reads and executes commands from the file ~/.bash_logout, if it exists. When an interactive shell that is not a login shell is started, bash reads and executes commands from /etc/bash.bashrc and ~/.bashrc, if these files exist. This may be inhibited by using the --norc option. The --rcfile file option will force bash to read and execute commands from file instead of /etc/bash.bashrc and ~/.bashrc.
# this is a comment # another comment export HISTSIZE=100 # another comment
One very convenient thing to note about bash: it has a full reference manual available online at:
http://www.gnu.org/software/bash/manual/bash.html
#!/bin/bash # #The first line is a comment to bash, but it isn't to the kernel.
Interpreter scripts An interpreter script is a text file that has execute permission enabled and whose first line is of the form: #! interpreter [optional-arg] The interpreter must be a valid pathname for an executable which is not itself a script. If the filename argument of execve() specifies an interpreter script, then interpreter will be invoked with the following arguments: interpreter [optional-arg] filename arg... where arg... is the series of words pointed to by the argv argu‐ ment of execve().
As listed on page 393 of your text, shells as scripting languages have the typical abilities of any programming language:
"Environment" variables instead are inherited by child processes. Indeed, environment variables are an explicit part of every process in a Unix system --- indeed, since these are explicit parts of every process on the system, you can see your current shell's environment variables (or any process, for that matter) through a kernel "window", the /proc interface:
% cat /proc/$$/environ # the $$ refers to the current process's process id
% cat /proc/$$/cmdlineInside of a shell, you can refer to these via $0, $1, $2, ... $9. Note that, just as shown /proc/$$/cmdline, $0 refers to the command, $1 refers to the command's first argument, and so forth. You can also refer to all of the arguments with $* (note that this does not include $0, the command.) You can refer to the number of arguments with $#.
Bash provides one-dimensional indexed and associative array vari- ables. Any variable may be used as an indexed array; the declare builtin will explicitly declare an array. There is no maximum limit on the size of an array, nor any requirement that members be indexed or assigned contiguously. Indexed arrays are referenced using integers (including arithmetic expressions) and are zero- based; associative arrays are referenced using arbitrary strings.
x=`uuidgen` # this sets the local (scalar) variable "x" export y=`uuidgen` # this sets the environmental variable "y" declare -a xx # create indexed array "xx" xx[7]=`uuidgen` # this sets the eighth element of indexed array "xx" declare -A yy # create associative array "yy" yy["2013-02-19"]=cloudy # this sets the value for element 2013-02-19 of the associative array y
echo $x # this prints the local (scalar) variable "x" echo $y # this prints the environmental variable "y" echo ${x[7]} # this prints the eighth element of indexed array "x" echo ${y["2013-02-19"]} # this prints the value for element 2013-02-19 of the associative array y
if [ "$x" -eq "string1" ] then echo $x is ready fi if [ "$x" -eq "string1" ] then echo $x is ready else echo $x is not ready fi
$x -eq $y # numerical equality test $x -ne $y # numerical inequality test $x -lt $y # numerical less than $x -gt $y # numerical greater than $x -le $y # numerical less than or equal to $x -ge $y # numerical greater than or equal to $x == $y # string equality $x != $y # string inequality $x < $y # string "less than" $x > $y # string "greater than"
In bash, repetition is easy enough to express. There are three main forms:
for name in *.tex do pdflatex $name done for name in *.pdf do lpr $name done
for (( x=0 ; x<10; x++ )) do echo $x done
while `true` # infinite loop do echo xyz done