WorkingOnServers/BetterBashing
A collection of useful shell commands for the bash shell
A compilation on how to use the bash shell
- changing the login shell
chsh /bin/bash
- returning to the previous directory
cd -
- brace expansion
echo b{a,e}d -> bad bed echo 1{2..4} -> 12 13 14
- unix data filtering tools
cat copy input to output grep search for strings in the input sort sort lines in the input cut extract columns from the input sed perform editing operations on input tr translate characters in the input
- cut with options
echo worm:track | cut -d: -f1 (use delimiter :, field #1) -> worm
- backslash escape
echo \"2 \* 3 \> 5\" -> "2 * 3 > 5"
- find with options
find . -name '*.txt' (wildcard needs quote)
- line breaks
echo this is a very \ long line for echo
- control keys
CTRL-C stop current command CTRL-D end of input CTRL-\ force stop command (try CTRL-C first) CTRL-S halt screen output CTRL-Q restart screen output CTRL-? erase last character CTRL-U erase command line CTRL-Z suspend current comand
- command line editing (EMACS-mode)
set -o emacs
TAB attempt completion ESC-? list completion options ESC-TAB attempt completion from history CTRL-O execute command and go to next line in history CTRL-U kill line from beginning to current position ESC-U uppercase following words ESC-L lowercase following words ESC-. bring up last word from previous line in history
- command line editing (vi-mode)
set -o vi
moving, deleting as usual i insert at current position a append after current position I insert at beginning of line A append after end of line R overwrite k or - up in history j or + down in history nG position n in history /string search backward for string ?string search forward for string n/N search again in same/opposite direction f/F find character t/T find character, back one
- /, repeat character find in same/opposite direction
n| move to column n \ command completion
- command completion and list on command line
= command completion and list below
- setting the prompt
PS1 shell prompt variable \u user name \s shell name \! history number \# command number \w pwd \W basename of pwd \t time \h hostname
- setting the search path
CDPATH default search paths for cd PWD present working directory OLDPWD previous PWD
- ls with options
ls -F lists directories with /, links with @, and executables with *
- defining shell functions
function functname{
shell commands}
-or-
functname () { shell commands; }
- function arguments
$0 command name $1 argument 1 $@ all arguments, separated by double quotes $* all arguments separated by field separator IFS (default blank) $# number of arguments
- return value
function () { statement; return $var }
- string operators
${variable:-word} return word if variable is undefined ${variable:=word} use word as default for variable if variable is undefined ${variable:?message} print message and abort if variable does not exist ${variable:+word} return word if variable is defined, otherwise return 0 ${variable:offset:length} return substring between offset and length if offset omitted, use until the end of variable if offset < 0, start from end (mind space!) ${#variable} return length of variable value
- echo with options
echo -e -n "This is\n a \t poem" -e interprets \n as linefeed, \t as tabulator, -E to turn backslash escape interpretation off -n surpresses the newline at the end
- echo escape sequences
\a Alert (beep) \b Backspace \c no newline \e,\E escape character \f Formfeed \n newline \r return \t tab \v vertical tab \n ASCII character with code n \0nnn octal format \xHH hexadecimal format \\ single backslash
- variable pattern matching
${variable#pattern} delete shortest matching pattern from beginning ${variable##pattern} delete longest matching pattern from the end ${variable%pattern} delete shortest matching pattern from beginning ${variable%%pattern} delete longest matching pattern from the end ${variable/pattern/string} replace first longest matching pattern ${variable//pattern/string} replace all matching patterns
- replacing awk
awk -FC '{print $N}' filename
- is equivalent to -
cut -fN -dC filename
where C is a character and N is a number.
- flow control
if condition; then
statements
elif condition; then
statements
else
statements
fi
- using the unaliased command
command ls ~
- using the builtin function
builtin cd ~
- condition testing: strings
str1=str2 str1!=str2 str1<str2 str1>str2 -n str1 string is not null (zero length) -z str1 string is null (zero length)
- condition testing: file attributes
-a file file exists -e file file exists -d file file exists and is a directory -f file file exists and is a regular file -r file have read permission to file -s file file exists and is not empty -w file have write permission to file -x file have execute permission to file -N file file was modified since last read -O file own file -G file files group ID matches mine file1 -nt file2 file1 is newer than file2 file1 -ot file2 file1 is older than file2
Use && and || outside conditional expressions Use -a and -o inside conditional expressions
if [ -a live ] && [ \( -x live \) -a \( -w live \) ]; then
echo "OK"
else
echo "not OK"
fi
- condition testing: integers
-lt less than -le less or equal -eq equal -ge greater than -ge greater or equal -gt greater than -ne not equal
- for loops
for name [in list]; do
statements
done
- case statements
case expression in
pattern1 ) statements ;; pattern2 ) statements ;;
esac
- while/until loops
while/until condition; do
statements
done
- shift shell arguments
shift n shifts the contents of $m to $(m-n)
- handling shell script options
while [ -n "$(echo $1 | grep '-')" ]; do
case $1 in -a ) process option -a ;; -b ) process option -b $2 is always the option's argument shift ;; -c ) process option -c ;; * ) echo 'usage: script [-a] [-b barg] [-c] args...' exit 1 esac shift
done
- handling shell script options with getopts
while getopts ":ab:c" opt; do
case $opt in a ) process -a ;; b ) process option -b $OPTARG is the option's argument c ) process option -c ;; \? ) echo 'usage: script [-a] [-b barg] [-c] args...' exit 1 esac
done shift $(($OPTIND - 1))
- declare: typed variables
declare -a array declare -i integer declare -r read-only declare -x export
- command evaluation
output=$( command )
- integer arithmetic
output=$(( a + b )) (deprecated: $[ a + b ])
- arithmetic operators
++ increment -- decrement + plus - minus
- product
/ division % remainder
- exponent
== equality (note: different for strings)
- number base
16#ff hexadecimal 256 10#10 decimal 10
- arithmetic for loop
for (( initialisation ; ending condition ; update )) do
statements
done
- arrays
names[0]=hans names[1]=bob names[2]=jim
names=([2]=jim [0]=hans [1]=bob)
names=(jim hans bob)
echo ${names[2]} print array element echo ${names[@]} print array with double quotes echo ${names[*]} print array as single quoted string echo ${#names[2]} return length of array element echo ${#names[@]} return length of array
- I/O redirection
cmd1 | cmd2 pipe > file stdout to file (same as 1> file) < file stdin from file (same as 0< file) >> stdout to file - append >| file stdout to file - overwrite <> file stdout and stdin to file &> file stdout and stderr to file 2> file stderr to file 2>&1 stderr to same as stdout
tee file copy stdin to screen and file
- Here-documents
cat >> afile << EOF copy stdin to afile until EOF is encountered if EOF is surrounded by , no variable substitution will be performed on the input if EOF is prefixed with -, leading tabs (not spaces) are removed
- printf
printf "hi %s\n" harald formated string printf "%7.2G\n" -89.2 formated number printf "%*.*G\n" 7 2 ${lat} dynamical field width specifiers, variable as argument
additional formatters:
- left-justify value in the field ' ' prefix positive values with space, negative with minus + always prefix numbers 0 pad output with zeros %b interpret escape sequences in the input %q transform spaces etc in strings in a shell-argument compatible way
printf "%q\n" "hello world" hello\ world
- read
read var1 var2 ... breaks stdin into words and assigns it to the variables, using space (or IFS)
- reading lines from files (not always useful)
IFS=':' while read parameter value; do
echo $parameter $value | grep "model name"
done < /proc/cpuinfo
- float statement input redirection
aFunction() {
echo $i
} < logfile
while statement; do
something
done < inputfile
- ignore comment lines in input
if [ -z "$(echo $dev | grep ^#)" ]; then
statements
fi
- eval
eval "ls | more" perform command-line processing on "ls | more"