Bash scripting


Her er nogle eksempler på hvordan man bruger bash mange stærke sider. Liste er meget lang og har taget mig en del tid at lave.

Bash scripting oversigt

#!/usr/bin/env bash
NAME="John"
echo "Hello $NAME!"

Variabler

NAME="John"
echo $NAME
echo "$NAME"
echo "${NAME}!"

Strenge i bash

NAME="John"
echo "Hej $NAME"  #=> Hej John
echo 'Hej $NAME'  #=> Hej $NAME

Shell udførelse af kommando

echo "I'm in $(pwd)"
echo "I'm in `pwd`"
# Her betyder $(kommando) og `kommando` det samme.

Betinget udførelse

git commit && git push
git commit || echo "Commit failed"

Funktioner

get_name() {
  echo "John"
}
echo "You are $(get_name)"

Betingelser

if [[ -z "$string" ]]; then
  echo "String is empty"
elif [[ -n "$string" ]]; then
  echo "String is not empty"
fi

Brace ekspansion

echo {A,B}.js
{A,B}Samme som A B
{A,B}.jsSamme som A.js B.js
{1..5}Samme som 1 2 3 4 5

Parametre expansions

Basics

name="John"
echo ${name}
echo ${name/J/j}    #=> "john" (Erstat tegn)
echo ${name:0:2}    #=> "Jo" (Udskriver 2 tegn fra position 0)
echo ${name::2}     #=> "hn" (Udskriver de første 2 tegn)
echo ${name::-1}    #=> "Joh"
echo ${name:(-1)}   #=> "n" (fra højre)
echo ${name:(-2):1} #=> "h" 
echo ${food:-Cake}  #=> "Cake"
length=2
echo ${name:0:length}  #=> "Jo"

Se: Parameter expansion

STR="/path/to/foo.cpp"
echo ${STR%.cpp}    # /path/to/foo
echo ${STR%.cpp}.o  # /path/to/foo.o
echo ${STR##*.}     # cpp (extension)
echo ${STR##*/}     # foo.cpp (basepath)
echo ${STR#*/}      # path/to/foo.cpp
echo ${STR##*/}     # foo.cpp
echo ${STR/foo/bar} # /path/to/bar.cpp
STR="Hello world"
echo ${STR:6:5}   # "world"
echo ${STR:-5:5}  # "world"
SRC="/path/to/foo.cpp"
BASE=${SRC##*/}   #=> "foo.cpp" (basepath)
DIR=${SRC%$BASE}  #=> "/path/to/" (dirpath)

Substitution

${FOO%suffix}Fjern suffix
${FOO#prefix}Fjern prefix
${FOO%%suffix}Fjern langt suffix
${FOO##prefix}Fjern langt prefix
${FOO/from/to}Erstat første match
${FOO//from/to}Erstat alt
${FOO/%from/to}Erstat suffix
${FOO/#from/to}Erstat prefix

Kommentarer

# Enkelt linje kommentar
: '
Flere linje
kommentar
'

Substrings

${FOO:0:3}Substring (position, længde)
${FOO:-3:3}Substring fra højre

Længde

${#FOO}Længte af $FOO

Default værdi

${FOO:-val}$FOO, or val Hvis ikke sat
${FOO:=val}Set $FOO to val Hvis ikke sat
${FOO:+val}val if $FOO Hvis sat
${FOO:?message}Vis fejl medelse og exit hvis $FOO ikke er sat

Tegnet  : er valgfri (Eks, ${FOO=word} virker også)

Løkker

Basis for løkker

for i in /etc/rc.*; do
  echo $i
done

Områder

for i in {1..5}; do
    echo "Welcome $i"
done

Løkker med step størrelser

for i in {5..50..5}; do
    echo "Welcome $i"
done

Læs linjer

< file.txt | while read line; do
  echo $line
done

For evigt

while true; do
  ···
done

Funktioner

Definere en funktion.

myfunc() {
    echo "hello $1"
}
# Samme som ovenfor (med alternativ syntax)
function myfunc() {
    echo "hello $1"
}
myfunc 
"John"

Retur værdier

myfunc() {
    local myresult='some value'
    echo $myresult
}

Her bliver result lig med resultatet som returneres fra kaldet af myfunc.

result="$(myfunc)"

Returnere fejl.

myfunc() {
  return 1
}
if myfunc; then
  echo "success"
else
  echo "failure"
fi

Argumenter

$#Number af argumenter
$*Alle argumenter
$@Alle argumenter, start fra start
$1Første argument

See Special parameters.

Betingede

Noter dig venlist af  [[ faktisk et program som returnere enten  0 (true) eller 1 (false) set fra shell fejl kode. Alle programmer har samme logik  (så som alle base kommandoer, som eks. grep(1) eller ping(1)) kan blive brugt, se eksempler.

[[ -z STRING ]]Tom streng
[[ -n STRING ]]Ikke tom streng
[[ STRING == STRING ]]Ligmed
[[ STRING != STRING ]]Ikke ligmed
[[ NUM -eq NUM ]]Ligmed
[[ NUM -ne NUM ]]Ikke ligmed
[[ NUM -lt NUM ]]Mindre
[[ NUM -le NUM ]]Mindre eller samme
[[ NUM -gt NUM ]]Støre en
[[ NUM -ge NUM ]]Støre eller samme
[[ STRING =~ STRING ]]Regexp
(( NUM < NUM ))Numerisk test
[[ -o noclobber ]]If OPTIONNAME er aktiv
[[ ! EXPR ]]Not
[[ X ]] && [[ Y ]]And
[[ X ]] || [[ Y ]]Or

Fil betingelser

[[ -e FILE ]]Findes
[[ -r FILE ]]Kan læses
[[ -h FILE ]]Symlink fil
[[ -d FILE ]]Bibliotek på disk
[[ -w FILE ]]Skrivebar
[[ -s FILE ]]Størrelse er > 0 bytes
[[ -f FILE ]]En Fil
[[ -x FILE ]]Kan startes
[[ FILE1 -nt FILE2 ]]1 er nyere en fil 2
[[ FILE1 -ot FILE2 ]]2 er nyere en fil  1
[[ FILE1 -ef FILE2 ]]Samme filer

Eksempler

if ping -c 1 google.com; then
  echo "Din internet virker ping google ok."
fi
if grep -q 'foo' ~/.bash_history; then
  echo "Du har skrevet 'foo' tidligere"
fi
# String
if [[ -z "$string" ]]; then
  echo "Streng er tom"
elif [[ -n "$string" ]]; then
  echo "Streng er ikke tom"
fi
# Combinations
if [[ X ]] && [[ Y ]]; then
  ...
fi
# Equal
if [[ "$A" == "$B" ]]
# Regex
if [[ "A" =~ "." ]]
if (( $a < $b )); then
   echo "$a er mindre en $b"
fi
if [[ -e "file.txt" ]]; then
  echo "fil findes"
fi

Arrays

Definere arrays

Fruits=('Apple' 'Banana' 'Orange')
Fruits[0]="Apple"
Fruits[1]="Banana"
Fruits[2]="Orange"

Arbejde med arrays

echo ${Fruits[0]}           # Element #0
echo ${Fruits[@]}           # Alle elementer, space-separated
echo ${#Fruits[@]}          # Antal af elementer
echo ${#Fruits}             # Længe på tekst på første element
echo ${#Fruits[2]}          # Længe på tekst på N element 
echo ${Fruits[@]:1:2}       # (fra position 1, elementer 2)

Operations

Fruits=("${Fruits[@]}" "Watermelon")    # Push
Fruits+=('Watermelon')                  # Igen Push
Fruits=( ${Fruits[@]/Ap*/} )            # Fjern med regex mash
unset Fruits[2]                         # Fjern et element
Fruits=("${Fruits[@]}")                 # Duplikere
lines=(`cat "logfile"`)                 # Læs fra program output

Iteration

for i in "${arrayName[@]}"; do
  echo $i
done

Kommander

historyViser historien over de sidst kommandoer udført
shopt -s histverifyUdfør ikke udvidet resultat straks

Expansions

!$Expand last parameter of most recent command
!*Expand all parameters of most recent command
!-nExpand nth most recent command
!nExpand nth command in history
!Expand most recent invocation of command

Operations

!!Viser kommandoen og udføre sidste kommando igen.
!!:s///Replace first occurrence of to in most recent command
!!:gs///Replace all occurrences of to in most recent command
!$:tExpand only basename from last parameter of most recent command
!$:hExpand only directory from last parameter of most recent command

!! and !$ can be replaced with any valid expansion.

Slices

!!:nExpand only nth token from most recent command (command is 0; first argument is 1)
!^Expand first argument from most recent command
!$Expand last token from most recent command
!!:n-mExpand range of tokens from most recent command
!!:n-$Expand nth token to last from most recent command

!! can be replaced with any valid expansion i.e. !cat, !-2, !42, etc.

Andre diverse muligheder.

Numeriske beregninger

$((a + 200))      # Addere 200 til $a
$((RANDOM%=200))  # Random nummer mellem 0..200

Shell i shells

Her udføres et cd til dirsted men står stadig i det bibliotek som du startede med at stå i.

(cd dirsted; echo "Vi er nu i $PWD biblioteket")
pwd # still in first directory

Omdirigering af output.

python hello.py > output.txt   # stdout til (file)
python hello.py >> output.txt  # stdout til (file), tilføj til filen.
python hello.py 2> error.log   # stderr til (file)
python hello.py 2>&1           # stderr til stdout
python hello.py 2>/dev/null    # stderr til (null)
python hello.py &>/dev/null    # stdout og stderr til (null)
python hello.py < foo.txt      # feed foo.txt til stdin for python

Inspektion af kommandoer.

command -V cd
#=> "cd is a function/alias/whatever"

Fang fejl.

trap 'echo Error at about $LINENO' ERR

eller

traperr() {
  echo "ERROR: ${BASH_SOURCE[1]} at about ${BASH_LINENO[0]}"
}
set -o errtrace
trap traperr ERR

Case/switch

case "$1" in
  start | up)
    vagrant up
    ;;
  *)
    echo "Usage: $0 {start|stop|ssh}"
    ;;
esac

Kilde relativ

source "${0%/*}/../share/foo.sh"

printf

printf "Hello %s," Jeg er Olga
#=> "Hello Sven, Jeg er Olga

Directory i script

DIR="${0%/*}"

Getting options

while [[ "$1" =~ ^- && ! "$1" == "--" ]]; do case $1 in
  -V | --version )
    echo $version
    exit
    ;;
  -s | --string )
    shift; string=$1
    ;;
  -f | --flag )
    flag=1
    ;;
esac; shift; done
if [[ "$1" == '--' ]]; then shift; fi

Heredoc

cat <

Reading input

echo -n "Proceed? [y/n]: "
read ans
echo $ans
read -n 1 ans    # Just one character

Special variables

$?Exit status fra sidste task
$!PID fra sidste backgrounds task
$PID nr på shell

Se også Special parameters.

Gå til sidste bibliotek

pwd # /home/user/foo
cd bar/
pwd # /home/user/foo/bar
cd -
pwd # /home/user/foo

Her er flere links til guider om bash. Men de er på engelsk.

Loading