Bash

From LQWiki
Jump to: navigation, search

bash (the bourne-again shell) - is the default shell for Linux users. It is compatible with the traditional Bourne shell (sh) in that Bourne shell scripts will work in bash, though there are some bash-specific features that will not work on older Bourne shells.

Shell initialization

The place to put aliases and simple environment variable settings that you want every time you open a shell is in .bashrc in your home directory. Example .bashrc file:

if [ -f /etc/bashrc ]; then . /etc/bashrc ; fi # Load system-wide bashrc
export PAGER=less
alias md='mkdir'
alias rd='rmdir'
alias ll='ls -lh'
alias la='ls -lah'
alias df='df -h'
alias du='du -h'
alias du1='du --max-depth=1'
alias ping='ping -c 5'

Appending text to environment variables like your PATH should not be done in the .bashrc, because it gets run often when subshells are started. Place lines like this in your ~/.bash_profile:

PATH=$HOME/bin:$PATH  # Adds to path, only in .bash_profile

When started as a login shell, bash first reads /etc/profile, then the first of ~/.bash_profile, ~/.bash_login, or ~/.profile that it finds. It doesn't automatically read the ~/.bashrc file in login shells. For consistency, the following line shold probably be in your .bash_profile:

if [ -f ~/.bashrc ]; then . ~/.bashrc ; fi

Features

User features

  • Typing <Esc>. repeats the last argument of the previous command.
  • Typing <Esc><BackSpace> backspaces a whole "word" at a time.
  • Readline - a GNU-created library for line-by-line text input. It allows a searchable command history and easy editing of the current command line, among other things.
  • <ctrl> + <r> invokes reverse-i-search for the command buffer (history of what you've typed). Then just type a part, any part, not necessarily from the begining, of a command you've typed in before and it'll give you the chronologically closest match
  • The use of $( command ) for command substitution (backquotes are traditional)
  • Numerical for loops
    for (( i=0; i<10; i++ )) ; do echo $i ; done

or in a script file, somewhat more readable and without semicolons

    for (( i=0; i<10; i++ ))
    do 
      echo $i
    done

Be sure to check out the Advanced Bash Scripting Guide, which has (most of) the info you need to start with bash scripting.

See Control keys for a list of control keys and which part of the system (the shell or the terminal) is responsible for it.

Variables and Parameters

Note: the bash man page documents shell variables in the segment titled PARAMETERS

The difference between variables and parameters is slight. They use the same syntax, but you are generally not able to change the value of a parameter.

Using

The examples use the echo command to report the variable's value. Variables are actually used anywhere in a command including as the command name itself or the entire command-line.

You can use variables and parameters by naming them, complete with the "$" that introduces a reference.

 % echo $SHELL
 /bin/bash

will show your default shell's name. A great many other variables, usually in all caps, are defined for you.

Variables can be interpolated into strings:

 % echo " *** my shell is $SHELL"
  *** my shell is /bin/bash

where the quotation marks prevent the shell from interpreting the asterisks (*) but not the variable.

Single quotes additionally prevent the variable from being recognized

 % echo ' *** my $SHELL is' $SHELL
  *** my $SHELL is /bin/bash

You can do a number of things to modify the value while using it: Supply a default value

 % echo $PAGER
 % echo ${PAGER:-less}        # comment: note the curly braces
 less

Change a portion of the value (exact matches, not regular expressions

 % echo $LANG
 en_US:UTF-8
 % echo ${LANG/UTF-8/en}
 en_US:en

There's lots more...

Setting

Note: the bash man page documents shell variables in the segment titled PARAMETERS

You can set a variable in bash without the leading "$" like this:

$ myvar="hello world"
$ echo $myvar
hello world

You can also use the "export" command to put the value in the environment that is inherited by commands you invoke later:

$ export nextvar="hello world"
$ echo $nextvar
hello world

You can also set a variable only for one command:

PAGER=less /bin/bash

You can not use an executable file to set the variable:

$ chmod 777 myfile
$ variable=23
$ echo $variable
23
$ ./myfile
$ echo $variable
23

This is because the executable file gets its own context instance when being executed. It can only change variables within this context. Common mistake is to use too many "$"s:

$ $hello=$world
bash: =: command not found

must be

$ hello=$world

otherwise, the value stored in $hello will be the name of the variable that is assigned the value of $world.

What is the difference between

$ export first="hello"

and

$ first="hello"

The difference is that "export" sets an environment variable that you can show with the command

env

And that will be available to sub-contexts, so, to programs that will be called from this shell. As an example, let's write a file output.sh

echo $first
echo $second

now we set $first different from $second:

$ chmod 777 output.sh
$ first=hello
$ export second=world
$ ./output.sh

world

You see, the (assigned) value of $first is not available to output.sh, but the (exported) value of $second is.


Custom Prompt

A custom prompt is taken from the value of $PS1. This is manipulated like any other variable, but is recognized specially by the shell. There are a number of such special names; see the manual for a list.

Set it

The PS1 variable stores the command-line prompt that bash prints. For a colorful bash prompt that looks like:

username@hostname/pwd $

use the following:

export PS1='\[\e[32m\]\u@\h/\[\e[1;31m\]\w\[\e[1;34m\]\$\[\e[0m\] '

For one without colors:

username@hostname:pwd$
export PS1='\u@\h:\w\$ '         # Single quotes with single backslashes

For more examples and options, see bash prompt.

Make it permanent

If you restart your computer, you still want the same login prompt. That means, you must set $PS1 permanentely. You must set it specifically for the bash as well as other shells like zsh, csh and ksh. You have to set it for logIn-shells, and for non-login-shells. You can set it for all users or for a specific user. Here are the files you will need to set it in:

for login-shells for non-login-shells
for all users /etc/profile /etc/bashrc
for a specific user ~/.bash_profile ~/.bashrc

Invoke other scripts

You can also write a file (myfile in this example) and invoke it with the command source:

$ cat >myfile<<EOF
> variable="hello world"
> EOF
$ source myfile
$ echo $variable
hello world

And you can source it with the command source (usage of "." is traditional but a bit cryptic)

$ variable=23
$ echo $variable
23
$ . myfile
$ echo $variable
hello world

See also

External links