Cos'è la shell

In un sistema operativo, una shell (o terminale) è un programma che permette agli utenti di comunicare con il sistema e di avviare altri programmi. È una delle componenti principali di un sistema operativo, insieme al kernel.



  • La shell è un interprete di comandi
  • Linguaggio di programmazione semplice e completo
  • Ideale per automatizzare i lavori ripetitivi e di routine
  • Portabilità degli script su dufferenti sistemi UNIX
  • Personalizzabile; permette agli utenti di modificare l'ambiente

Bourne-Again SHell




Scritta da Bourne per rimpiazzare Bourne Shell (conosciuta come sh), integra caratteristiche di sh, csh e ksh.


Bash è lo standard de facto dello scripting di shell su ogni variante UNIX (OS X, Cygwin e Linux).

Cos'è uno script

Nel caso più semplice uno script non è altro che una lista di comandi da eseguire in sequenza.


      #!/bin/bash

      cd /var/log
      cat /dev/null > btmp
      cat /dev/null > wtmp
      echo "Log cancellati"
      

Eseguire uno script

È possibile eseguire uno script invocandolo tramite:

  • $ sh nome-file-script
  • $ bash nome-file-script
  • Oppure, è possibile assegnare i permessi di esecuzione a tale script:

    $ chmod +x nome-file-script
    $ ./nome-file-script
  • È anche possibile spostare tale script in /usr/local/bin e invocarlo scrivendo

    $ nome-file-script

Variabili

Le variabili possono essere dichiarate in qualsiasi parte dello script. Si accede al valore di una variabile anteponendo il simbolo $ al suo nome.

$ variabile='sono una variabile'
$ echo variabile
variabile
$ echo $variabile
sono una variabile

È possibile includere il valore di una variabile all'interno di un'altra utilizzando i doppi apici (quoting debole).

$ quoting_debole="$variabile"
$ echo $quoting_debole
sono una variabile
$ quoting_forte='$variabile'
$ echo $quoting_forte
$variabile

Variabili (continua)

In Bash le variabili non sono tipizzate; possono cioè contenere sia solo caratteri, sia solo numeri, sia entrambi.

È possibile eseguire delle operazioni artimetiche nel caso in cui contengano solo numeri.

$ mista="1a"
$ let "mista += 1"
$ echo $mista
1
$ solo_numeri="1"
$ let "solo_numeri += 1"
$ echo $solo_numeri
2

Array

Bash supporta gli array e offre gli operatori più comuni per manipolarli.

$ array=(primo secondo terzo)
  • $ echo $array
    primo secondo terzo
  • $ echo ${array[1]}
    primo
  • $ echo ${#array[@]}
    3
  • $ echo ${#array[1]}
    5

Array (continua)

  • $ echo ${array:1}
    secondo terzo
  • $ echo ${array:1:1}
    secondo
  • $ array2="quattro cinque"
    $ concat=(${array[@]} ${array2[@]})
    $ echo $concat
    uno due tre quattro cinque
        

Operazioni sulle stringhe

$ stringa="1 stringa"
  • $ echo ${#stringa}
    9
  • $ echo ${stringa:2:6}
    string
  • $ echo ${stringa%[a-z]*}
    1 string
    $ echo ${stringa%%[a-z]*}
    1
  • $ echo ${stringa#[1-9]*}
     stringa
    

Operazioni sulle stringhe (continua)

  • $ echo ${stringa/1/2}
    2 stringa
  • $ echo ${${stringa/1/2}/a/he}
    2 stringhe
  • $ echo $(expr index "$var" str)
    3

Costrutti di test

I costrutti di tipo if sono supportati e controllano l'exit status di un comando UNIX.

if [ $var1 = $var2 ]
then
  echo "sono uguali"
else
  echo "non sono uguali"
fi

Bash mette a disposizione degli operatori per le operazioni più comuni:

  • if [ -e file ]
  • if [ ! -d file ]

Cicli

Bash supporta cicli for, while e until.

for elemento in ${array}
do
  echo $elemento
done
while [ "${array[2]" = "secondo" ]
do
  array[2]="era secondo"
done
until [ "${array[2]" = "era secondo" ]
do
  array[2]="secondo"
done

Cicli (continua)

Sono supportati anche break e continue. Questi hanno lo stesso effetto che hanno nei comuni linguaggi di programmazione, ma accettano anche un parametro numerico che estende il loro effetto ad altri possibili N cicli padri.

for numero in 1 2 3
do
  echo $numero
  for numero_figlio in 4 5 6
  do
    echo $numero_figlio
    if [ $numero_figlio = 5 ]
    then
      break 2
    fi
  done
done

Funzioni

È possibile dichiarare delle funzioni per non duplicare il codice.

Non bisogna specificare nella firma il numero di parametri che prende in input tale funzione.

function funzione {
  echo "Parametro uno: $1"
  echo "Parametro due: $2"
  echo "Parametro tre: $3"
}

Una chiamata di una funzione è equivalente a quella di un comando.

Input e Output

Esistono 3 flussi di dati: stdin, stdout e stderr. In Bash sono gestiti rispettivamente dai descrittori 0, 1 e 2.

I caratteri <, <<, >, >> possono essere combinati con i descrittori per reindirizzare l'input, l'output o i messaggi d'errore ad un file.

Il carattere & reindirizza sia stdout che stderr ad un file, ma può anche reindirizzare l'output di un descrittore ad un altro.

while [ true ]
do
  uptime 2> errori.log
  sleep 60
done
$ date &> input_e_output.log
$ date 2>&1

I fondamentali

Per realizzare uno script è necessario conoscere comandi indispensabili come:

  • sed - stream editor for filtering and transforming text
  • awk - pattern scanning and processing language
  • grep, egrep, fgrep - print lines matching a pattern
  • cat - concatenate files and print on the standard output
  • cut - remove sections from each line of files
  • tail - output the last part of files
  • head - output the first part of files
  • xargs - build and execute command lines from standard input
  • sort - sort lines of text files

In ambienti UNIX ogni comando offre una lista dei parametri disponibili che permettono di modificare il suo comportamento. È possibile esplorare tale lista invocando un comando seguito dal termine --help oppure è possibile visualizzare la documentazione di tale comando anteponendo il termine man.

I fondamentali (continua)

Ci sono poi comandi che permettono l'interazione col sistema operativo come:

  • cd - change the working directory
  • ls - list directory contents
  • pwd - print name of current/working directory
  • pushd, popd, dirs - bookmarking working directories
  • date - print or set the system date and time
  • uptime - tell how long the system has been running
  • w - show who is logged on and what they are doing
  • whoami - print effective userid
  • find - search for files in a directory hierarchy
  • wget - the non-interactive network downloader
  • rm - remove files or directories
  • tar - manipulate tape archives
  • ...

Backup di una cartella

  • #!/bin/bash
    
    tar -acf Documenti-backup.tar.gz Documenti/
  • #!/bin/bash
    
    rm Documenti-backup.tar.gz
    tar -acf Documenti-backup.tar.gz Documenti/
  • #!/bin/bash
    
    rm Documenti-backup 2> /dev/null
    tar -acf Documenti-backup.tar.gz Documenti/

Backup di una cartella (continua)

  • #!/bin/bash
    
    if [ -f Documenti-backup.tar.gz ]; then
      rm Documenti-backup.tar.gz
    fi
    if [ -d Documenti ]; then
      tar -acf Documenti-backup.tar.gz Documenti/
    fi
  • #!/bin/bash
    
    backup="${1}.tar.gz"
    dir="${1}"
    if [ -f "$backup" ]; then
      rm "$backup"
    fi
    if [ -d "$dir" ]; then
      tar -acf "$backup" "$dir"
    fi
  • #!/bin/bash
    
    backup="${1}-$(date +%Y-%m-%d_%H-%M).tar.gz"
    dir="${1}"
    if [ -f "$backup" ]; then
      rm "$backup"
    fi
    if [ -d "$dir" ]; then
      tar -acf "$backup" "$dir"
    fi

Backup di una cartella (continua)

#!/bin/bash

function usage {
  echo "Usage: ${0} "
  exit 1
}

if [ $# -eq 0 ]; then
  usage
fi

backup="${1}-$(date +%Y-%m-%d_%H-%M).tar.gz"
dir="${1}"
if [ -f "$backup" ]; then
  rm "$backup"
fi
if [ -d "$dir" ]; then
  tar -acf "$backup" "$dir"
fi

Estrarre l'audio da un video su Youtube

#!/bin/bash
function usage {
  echo "Usage: ${0} &lgt;youtube video url>"; exit 1
}

[ $# -eq 0 ] && usage

url="${1}"
youtubedl="/usr/bin/youtube-dl"
ytargs="-c"
video="${youtubedl} ${url} --get-filename}"
title="${youtubedl} ${url} --get-title}"

ffmpeg="/usr/bin/ffmpeg"
ffargs="-i \"${video}\" -acodec libmp3lame -metadata title=\"${title}\" \"${title}\".mp3"

cd /tmp
${youtubedl} "${ytargs}" "${url}" || exit 1
${ffmpeg} "${ffargs}" || exit 1

Riferimenti