Cosa c'è di nuovo?
HWReload

Registrati e partecipa alle attività del forum

Introduzione alla shell

Archer_65

Utente
Iscritto dal:
13 Marzo 2021
Messaggi
60
GUIDA - Introduzione alla shell
Title.png

Salve carissimi, oggi si friggono cervelli :D
No, torniamo seri, oggi cercherò di introdurvi la cosa più temuta dagli utonti: la shell. In particolare bash.


Requisiti
  • Voglia di scervellarsi.
  • ...
  • ...
Basta così

Precisazioni
  • Non si intende sostituire un buon libro di testo.
  • C'è bisogno di fare delle prove, quindi non leggete e basta, non vi resterà nulla di concreto.
  • Non è difficile come sembra.
Iniziamo!

Introduzione
Prima dell'avvento di icone e finestre, la linea di comando permetteva l'interazione con la macchina. Sui sistemi UNIX chi interpreta e gestisce i comandi è la shell.
La shell fornisce un modo per creare script, eseguire programmi, compilare codice e molto altro. Sebbene possa sembrare poco intuitiva risulta molto più potente delle GUI (Graphical User Interface), offrendo funzioni avanzate che, altrimenti, non sarebbero accessibili.
Ce ne sono di diverse, ad esempio bash (Bourne Again Shell), zsh (Z Shell) e dash (nota per la sua velocità). Bash è usata in molte distribuzioni GNU/Linux e considerata uno "standard".


PROMPT

Se sul vostro sistema non è presente un'interfaccia grafica (o non funziona, per qualche oscura ragione), vi ritroverete il prompt dopo aver effettuato l'accesso.

Per un utente regolare:

Bash:
$
Per un utente root:
Bash:
#

Solitamente $ e # sono preceduti da informazioni quali username, data, nome dell'utente, directory corrente.
Esempio:
Bash:
[pinco@pallo ~] $

TERMINALE

Se avete un'interfaccia grafica potete aprire il terminale, ne esistono molti, quello preinstallato andrà benissimo.
NOTA: Potete anche personalizzarlo cambiando font, colori etc.


VIRTUAL CONSOLE

Le virtual console permettono di avere più sessioni della shell aperte, è possibile spostarsi tra queste con la combinazione CTRL+ALT e un tasto tra F1 e F6.

I comandi
Il modo più semplice per eseguire un comando è scriverlo da una shell, proviamo.
Bash:
$ date
Thu May 13 15:00:23 UTC 2021
Il comando date, senza nessuna opzione, ha questo output.

Provate altri comandi, quali:


Comando
Significato
pwd
Mostra la directory corrente.
hostname
Mostra l'hostname del computer.
ls
Elenca i file e le cartelle nella directory corrente.

La sintassi

Molti comandi hanno opzioni aggiuntive, utili per cambiare il comportamento del comando. Solitamente le opzioni consistono in una lettera preceduta da un trattino.
ESEMPIO:
Bash:
$ ls –l –a –t

$ ls –lat
I due comandi sono equivalenti, -l (long listing), -a (mostra file nascosti), -t (ordinamento per data).

Molte opzioni vengono rappresentate da un'intera parola preceduta da due trattini (--), ad esempio:
--help per l'opzione aiuto di molti comandi.
NOTA: Ci sono comandi che non seguono questa convenzione.

Molti comandi accettano anche argomenti, sono delle informazioni aggiuntive quali file, dispositivi, utenti, sulle quali il comando agisce. Esempio?
Bash:
$ cat /etc/passwd
In questo caso /etc/passwd è l'argomento fornito al comando cat.
NOTA: Questo comando mostra il contenuto del file /etc/passwd.

A volte gli argomenti sono posti immediatamente dopo un'opzione. Per opzioni a singola lettera, l'argomento segue dopo uno spazio. Per opzioni rappresentate da una parola intera, l'argomento segue un segno uguale (=).
ESEMPI:
Bash:
$ ls --hide=Documenti
Questo comando elenca i file (o directory) nella directory corrente (come già spiegato prima per ls) escludendo il file (o directory) Documenti, potete fare delle prove cambiando argomenti.

Bash:
$ tar –cvf homecompressa.tar /home/pinco
Qui viene usato il comando tar, le opzioni dicono di creare (c) un file (f) denominato homecompressa.tar, che include il contenuto della cartella /home/pinco e di tutte le sue sottocartelle e mostrare in maniera verbosa (v) dei messaggi. È bene notare che homecompressa.tar è un argomento dell'opzione f, quindi viene posto immediatamente dopo l'opzione.

PROVE:
Provate i seguenti comandi:
Bash:
$ ls

$ ls –a
Il comando ls -a mostra, a differenza di ls, anche i file nascosti in una directory (che sono preceduti da un punto).

Bash:
$ date

$ date +'%d/%m/%y'
Il comando date ha opzioni speciali che permettono di manipolare il formato di stampa.
NOTA: date --help per info aggiuntive.


L'identità

Effettuato l'accesso, si ha una identità, che include username, group name, user ID, group ID. Linux tiene traccia della tua sessione, sa quando hai effettuato l'accesso, per esempio.
Per avere informazioni su questa "identità":
Bash:
$ id

uid=1000(mario) gid=1000(mario) gruppi=1000(mario),998(wheel)
Questo il mio output, da come potete vedere appartengo al gruppo mario e al gruppo wheel. È normale che un utente abbia come nome del suo gruppo primario proprio il suo username. Questi nomi (e numeri) rappresentano i permessi che un utente ha.

È possibile ottenere informazioni sulla sessione corrente utilizzando il comando:
Bash:
$ who -uH

NOME   LINEA      ORA                           IDLE      PID         COMMENTO
mario    pts/1       2021-05-13 19:02       .            27843     (:0)

L'output mostra che l'utente mario sta usando lo pseudo terminale pts/1, IDLE mostra quanto a lungo la shell è rimasta aperta senza nessun comando digitato (il punto indica che, al momento, è attiva). PID mostra l'ID del processo, COMMENT il nome del computer dal quale è stato effettuato l'accesso (potrebbe essere un altro computer) o il nome del display locale X dal quale viene usato il terminale.


Dove sono questi comandi?
Bene, tutto molto carino, ma dove sono questi comandi? Per trovare i comandi digitati la shell fa riferimento al path. Per comandi non presenti nel path è possibile digitare il percorso del comando per esteso, basta conoscerlo.
Bash:
$ /bin/date
Questo ovviamente non è conveniente, specialmente se il percorso è lungo. Molto più comodo avere i propri comandi in una directory e poi aggiungerle alla variabile d'ambiente PATH, una lista di percorsi controllati in maniera sequenziale per i comandi digitati.
Per sapere qual è il PATH:
Bash:
$ echo $PATH

/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl
Esempio di output.

Ogni percorso è separato dai due punti.
NOTA: Linux non controlla la directory corrente per l'esecuzione di un comando prima di cercare nel path, è bene notare che, se un comando non è presente in quest'ultimo, ci sarà bisogno di scrivere l'intero percorso (relativo o assoluto). Anche l'ordine è importante, i percorsi nel path sono controllati da sinistra a destra.

Ci sono comandi interni alla shell, altri possono essere "sovrascritti" creando alias personali.
"E quindi? Va come gli pare?"

Assolutamente no, ecco l'ordine:

  1. Alias. Nomi impostati dal comando alias. Digitando alias potete vedere quali alias sono impostati. Sono comodi per accorciare un comando particolarmente complicato.
  2. Parole riservate. Ci sono parole riservate alla shell. Alcune sono per fini "programmativi" (do, while, case, else).
  3. Funzioni. Set di comandi.
  4. Comandi interni. Non c'è una rappresentazione di questi nel filesystem, sono integrati nella shell, ad esempio: cd (cambia directory), echo (stampa), exit (per uscire da una shell), pwd (per indicare la directory corrente).
  5. Comandi nel filesystem. Il comando è eseguito dal filesystem del computer.
Volete sapere a quale categoria appartiene un comando?
Bash:
$ type comando
Fate qualche prova ?

Se un comando non è nel path, potete usare locate per provare a cercarlo (cercherà in qualsiasi parte del sistema accessibile dall'utente). Cercherà in tutto il filesystem. Se ci sono file aggiunti di recente updatedb (come utente root) aggiornerà il database di locate.


Completamento
È possibile risparmiare tempo (e battiture) grazie al completamento. Digitate qualcosa e poi premete il tasto TAB. Questo vale per:
  • Comandi, alias, funzioni.
  • Variabili, se viene digitato $ prima.
  • Username, se viene digitato ~ prima.
  • Hostname, se viene digitato @ prima.

NOTA: Se vi sono più possibilità verranno mostrate tutte.
Richiamare comandi dalla cronologia

Editing di base
Ripetere comandi usati in precedenza può essere conveniente. È possibile richiamarlo e anche modificarlo. Il comando history mostra questi comandi.
Il sistema di editing di bash è basato sull'editor emacs. È possibile anche usare i comandi dell'editor vi, ma non entreremo nel dettaglio, non questa volta.
Concentriamoci sullo stile emacs e proviamo un comando:
Bash:
$ ls /usr/bin | sort –f | less
Questo comando elenca i contenuti della directory /usr/bin, ordina alfabeticamente (case insensitive) e porta l'output al comando less. Mostrerà la prima pagina dell'output, è possibile andare avanti riga per riga (con Invio), pagina per pagina (con Barra Spaziatrice), uscire (con q).
Modifichiamo il comando.

  1. Freccia su. Mostra il comando più recente della cronologia.
  2. CTRL+A. Sposta il cursore all'inizio.
  3. CTRL+F o Freccia destra. Ripeti il comando per posizionarti dov'è presente il primo slash (/)
  4. CTRL+D. Digita questo comando quattro volte per cancellare /usr.
  5. Invio. Esegue il comando appena modificato.
Potete usare le frecce direzionali per muovervi col cursore (destra e sinistra) o per navigare tra i comandi nella cronologia (su e giù).
Vi lascio qualche combinazione:


Combinazione
Significato
CTRL+FVai un carattere avanti.
CTRL+BVai un carattere indietro.
ALT+FVai una parola avanti.
ALT+BVai una parola indietro.
CTRL+AVai all'inizio.
CTRL+EVai alla fine.
CTRL+LPulisci.
CTRL+DCancella carattere corrente.
BackspaceCancella carattere precedente.
CTRL+TScambia carattere corrente e precedente.
ALT+TScambia parola corrente e precedente.
ALT+UParola in maiuscolo.
ALT+LParola in minuscolo.
ALT+CCapitalizza parola.
CTRL+VInserisci un carattere speciale. TAB = CTRL+V+TAB.
CTRL+KTaglia fino a fine linea.
CTRL+UTaglia fino a inizio linea.
CTRL+W Taglia parola precedente.
ALT+DTaglia parola successiva.
CTRL+YIncolla il testo tagliato più recente.
CTRL+CCancella la riga.

Navigazione specifica

Abbiamo visto che è possibile modificare un comando dopo averlo richiamato, ma è possibile fare altro.
Bash:
$ history 3
123 ls
124 date
125 sudo pacman -Syyu
Mostra i 3 comandi più recenti della cronologia, preceduti da un numero.

È possibile richiamare questi comandi ed eseguirli in un solo colpo con il punto esclamativo (!).

  • !n Esegui comando numero. Basta rimpiazzare n con il numero desiderato.
    Esempio:
    Bash:
    $ !32
  • !! Esegui comando precedente.
  • !?stringa? Esegui comando (più recente) contenente una stringa.
    Esempio:
    Bash:
    $ !?dat?
    Se nella cronologia c'è un comando con una sottostringa del genere, allora verrà eseguito.
Invece di usare la cronologia e basta è possibile richiamare un comando preciso e modificarlo:

Combinazione
Significato
Freccia su (CTRL+P) – Freccia giù (CTRL+N)Naviga nella cronologia.
CTRL+RPermette di inserire una stringa e cercare a ritroso, apparirà un comando che corrisponde alla stringa inserita (se esiste), sarà possibile modificarlo e eseguirlo.
CTRL+SCome sopra, ma cerca in avanti (potrebbe non funzionare sempre).
ALT+PSimile a CTRL+R, ma non è incrementale, bisogna premere Invio.
ALT+NCome sopra, cerca in avanti (potrebbe non funzionare sempre).

Esiste anche fc, basta digitarlo seguito da un numero (identificativo del comando) e verrà aperto un editor di testo (di default vi, per uscire digitare :wq o :q! per non salvare). Effettuate i cambiamenti e all'uscita il comando verrà eseguito.
NOTA: fc accetta anche un range (esempio, fc 32 35).
La cronologia è nel file .bash_history nella directory home. Di default vengono memorizzati 1000 comandi.


Comandi multipli

Connessione: PIPE
È possibile anche ridirezionare l'input e l'output dei comandi. Per permettere questo, la shell fornisce dei metacaratteri. Tra questi troviamo pipe (|), ampersand (&), punto e virgola ( ; ), parentesi e segni minore e maggiore (< e >).
Pipe rende l'output di un comando l'input di un altro comando. Per esempio:
Bash:
$ cat /etc/passwd | sort | less
In questo caso:

  1. Il comando cat elenca i contenuti del file /etc/passwd.
  2. L'output (tramite pipe) "diventa" input per il comando sort, che ordina alfabeticamente.
  3. L'output di sort "diventa" input per less.
Vediamo un altro comando più complesso:
Bash:
$ gunzip < /usr/share/man/man1/grep.1.gz | nroff –c –man | less
In questo caso:

  1. Il contenuto del manuale del comando grep è diretto verso gunzip per essere estratto.
  2. L'output di gunzip diventa input per nroff (che formatta il manuale usando la macro –man.
  3. L'output di nroff a questo punto viene passato a less.
Quindi? Semplicemente è possibile lavorare sul testo e cambiare, cancellare, ordinare il contenuto. Il concetto chiave è quello di voler "spezzare" tutto in diversi programmi, questo permette una maggiore modularità e anche eventuali correzioni diventano più semplici.

Sequenza: PUNTO E VIRGOLA


A volte si desidera eseguire una sequenza di comandi, è possibile farlo grazie a ;.
Bash:
$ date ; troff –me documento | lpr ; date
Il primo comando mostra la data prima che inizi la formattazione di un documento tramite troff e viene poi portato l'output alla stampante (tramite lpr). Poi, una volta finito, viene usato di nuovo il comando date, per mostrare data e ora.

Perché farlo? In questo modo è possibile capire quanto tempo ha richiesto la formattazione del documento.


Background: AMPERSAND

Alcuni comandi richiedono un po' per il completamento, ma spesso vorremmo evitare di attendere prima di chiudere la shell. In questi casi torna utile ampersand (&) alla fine del comando, permette di eseguire un programma in background.
Comandi per formattare il testo quali nroff e troff sono un esempio, in caso di documenti particolarmente grandi.


Espansione
Comandi

È possibile rendere l'output di un comando argomento per un altro comando.
  1. $(comando)
  2. `comando`
Questi sono i due modi per espandere un comando, esempio:
Bash:
$ vi $(find /home | grep ciaomamma)
In questo esempio è prima eseguita l'espansione, cioè il comando find stampa tutti i file e le directory "sotto" /home e l'output è poi indirizzato a grep che filtra i file (e directory) prendendo solo quelli che contengono nel loro nome la stringa ciaomamma. Il comando vi apre tutti questi file per modificarli, uno ad uno (per uscire da vi :q!)
Utile se si conosce il nome del file ma non la sua posizione...


Espressioni aritmetiche

È possibile passare il risultato di un'espressione aritmetica a un comando. Ci sono due forme per fare ciò:
  1. $[espressione]
  2. $(espressione)
Esempi:
Bash:
$ echo "Ho $[2021 – 2000] anni"

Ho 21 anni.
La shell interpreta l'espressione, passando poi la stringa tra " " al comando echo, che mostrerà a schermo anche il risultato!

Bash:
$ echo "Ci sono $(ls | wc –w) file in questa directory."
NOTA: ls elenca i contenuti della directory e poi esegue il conteggio delle parole per contare gli elementi (wc –w).

Provate.

Variabili


Variabili che conservano informazioni possono essere espanse tramite $. Il valore della variabile sarà stampato:

Bash:
$ ls –l $BASH

-rwxr-xr-x 1 root root 952720  9 mag 11.53 /bin/bash

La shell conserva informazioni utili nelle variabili. Esempi sono $SHELL (identifica la shell usata), $PS1 (che definisce il prompt della shell).
Tramite il comando set è possibile visualizzare tutte le variabili per la shell in uso. Le variabili d'ambiente si possono visualizzare con il comando env.

Con echo $VARIABILE è possibile ottenere il valore di una variabile.
Bash:
$ echo $USER
affred
Questo stampa il valore della variabile USER.

Qui una tabella con variabili d'ambiente comuni:


Variabile
Descrizione
BASHContiene il percorso del comando bash.
BASH_VERSIONNumero rappresentante la versione corrente di bash.
EUIDUser ID dell'utente, assegnato all'avvio della shell.
FCEDITQuesta variabile, se impostata, indica l'editor predefinito usato dal comando fc. Di default è vi.
HISTFILELocazione della cronologia. Solitamente in $HOME/.bash_history.
HISTFILESIZENumero delle voci che la cronologia può contenere, di default sono 1000.
HISTCMDRitorna il numero del comando corrente nella cronologia.
HOMEDirectory home, solitamente è possibile tornarci digitando solo cd.
HOSTTYPEValore che indica l'architettura del computer in uso. ES: x86_64.
MAILLocazione del file mailbox. Solitamente sotto /var/spool/mail/nomeutente.
OLDPWDDirectory di lavoro precedente.
OSTYPEIdentifica il sistema operativo, solitamente qualcosa come linux o linux-gnu.
PATHLista dei percorsi che definiscono il path.
PPIDProcess ID del comando che ha avviato la shell.
PROMPT_COMMANDPuò essere impostato un comando da mostrare prima di mostrare il prompt della shell.
PS1Valore del prompt, può contenere varie cose. Esistono anche PS2, PS3 etc.
PWDDirectory corrente.
RANDOMGenera un numero casualmente tra 0 e 99999.
SECONDSSecondi passati dall'avvio della shell.
SHLVLNumero che identifica il livello della shell, questo aumenta ogni volta che viene richiamato un nuovo comando.
TMOUTQuesto può essere impostato per uscire dalla shell dopo un tot di inattività. Utile per evitare accessi non autorizzati.

Qualche chicca

Uscire dalla shell

Per uscire dalla shell: CTRL+D o exit, se si è in un terminale causerà la chiusura di quest'ultimo...Ok, la chicca non era questa, andiamo avanti.

Alias

Esempio:
Bash:
$ alias rm='rm -i'
Quell'opzione permette di chiedere conferma per la rimozione di un file.

È possibile rimuovere un alias tramite unalias.
NOTA: Questo vale solo per la shell corrente, è possibile inserire degli alias persistenti attraverso .bashrc.

Configurare la shell


Ci sono vari file di configurazione che definiscono il comportamento della shell. Alcuni sono eseguiti per ogni utente e per ogni shell, altri sono specifici di utenti che creano i loro file di configurazione.

Gli utenti possono modificare questi file direttamente dalla loro home, attraverso file come .bash_profile e .bashrc.
Un modo molto semplice per modificare questi file è usare l'editor nano:
Bash:
$ nano $HOME/.bashrc
Con il file aperto è possibile spostarsi ed effettuare le modifiche che si ritengono opportune, ad esempio aggiungere degli alias. Per salvare CTRL+O, per uscire CTRL+X. La prossima volta che verrà aperta una shell sarà possibile usufruire delle modifiche effettuate.

È anche possibile farlo senza aprire una nuova shell:
Bash:
$ source $HOME/.bashrc

Il prompt
Il prompt consiste in una serie di caratteri che appaiono ogni volta che la shell è pronta ad accettare un comando. La variabile d'ambiente PS1 imposta ciò che il prompt contiene ed è quello con cui si interagisce la maggior parte delle volte. Se la shell richiede input aggiuntivi si utilizzano i valori PS2, PS3, PS4.

Solitamente il prompt, di default, ha già qualche informazione:
Bash:
[pinco@pallo ~]$
Qualcosa del genere...

NOTA: ~ rappresenta $HOME in forma contratta. Quindi quella informazione dell'esempio sopra cambia ogni volta che si cambia directory, in sintesi: è la working directory.
Vari caratteri speciali permettono di includere varie informazioni nel prompt. Ecco una tabella:


Carattere
Descrizione
\!Mostra il numero (nella cronologia) del comando corrente.
\#Simile a quello precedente, ma include solo i comandi della shell corrente.
\$Mostra se si è utente ($) o root (#).
\WMostra il nome di base della directory corrente. ES: /usr/share/themes apparirà solo come themes.
\wMostra il percorso completo della directory corrente.
\[Precede una sequenza di caratteri non stampabili, può essere usata per aggiungere colori, grassetto, etc.
\]Segue una sequenza di caratteri non stampabili.
\\Mostra un backslash.
\dMostra nome del giorno, mese, numero del giorno. ES: Ven Mag 14
\hMostra l'hostname del computer che sta eseguendo la shell.
\nVa a capo.
\sMostra il nome della shell. ES: bash, zsh, dash.
\tStampa l'ora corrente. ES: 23:39:21.
\uStampa lo username.

Per modificare permanentemente il valore PS1 basta recarsi in .bashrc nella vostra home e modificare il valore di PS1.

Aggiungere variabili d'ambiente a .bashrc

Esempio con PATH:
Supponiamo di voler aggiungere la /home/pallo/fattimiei al path. Aprite .bashrc e aggiungete la seguente riga:
Codice:
PATH=$PATH:/home/pallo/fattimiei ; export PATH
Questo legge il path corrente, aggiunge la directory, esporta il nuovo path.

Potete creare variabili vostre.


Ottenere informazioni sui comandi

A primo impatto la shell sembra ostica, ma non è per nulla difficile!
Come faccio a sapere che comandi ho a disposizione, cosa possono fare, come usarli?

  • Controllare il PATH. Scrivete echo $PATH. Avrete una lista di directory, supponiamo di voler ottenere una lista di comandi presenti nella directory /bin.
    Bash:
    $ ls /bin
  • Usare help. Molti comandi sono nella shell stessa, quindi non appaiono in nessuna directory. Il comando help mostra questi comandi e le opzioni disponibili per essi (help | less per una lista). Per info su un comando in particolare: help comando.
  • Opzione --help (o –h) con il comando. Molti comandi includono questa opzione.
    Bash:
    date --help | less
  • Comando info. Altro strumento per informazioni sui comandi.
  • Comando man. Per il manuale, usatelo questo, è sacro.
Qualche nota su man

Numero sezione
Nome sezione
Descrizione
1Comandi utenteComandi che possono essere eseguiti senza privilegi da qualsiasi utente.
2System callFunzioni usate per chiamate al kernel.
3Funzioni di libreria di CFunzioni che forniscono un'interfaccia per librerie di programmazione.
4Dispositivi e file speciali"Nodi" del filesystem che rappresentano dispositivi hardware (come CD) o software (come generatori casuali di numeri)
5Formati e convenzioniTipi di file o file di configurazione specifici.
6GiochiGiochi disponibili.
7MistaPanoramica di argomenti come protocolli, filesystem, etc.
8Strumenti di amministrazione e demoniComandi che richiedono privilegi particolari.

Il comando man permette di cercare pagine del manuale o mostrarle, ecco qualche esempio:
Bash:
$ man –k passwd
…
passwd        (1) - cambia la password utente
passwd        (5) - il file delle password

$ man passwd

$ man 5 passwd

Usando –k si può cercare il nome e il sommario delle sezioni di tutte le pagine man installate sul sistema. Ce ne sono parecchie che includono "passwd" nel nome o nella descrizione.
NOTA: mandb lanciato da root inizializza il database.

Inoltre, man passwd mostrerebbe la prima sezione, se voglio un'altra sezione è bene specificarla, ad esempio man 5 passwd.
È possibile navigare nella pagina del manuale, ovviamente, basta usare Page Down, Page Up, Invio, freccia su e giù. Con / si può cercare un termine, con n si ripete la ricerca in avanti, con N all'indietro. Per uscire q.


Fine dell'introduzione

Bene, abbiamo finito per oggi. :drunk2:
La prossima volta cercherò di dare indicazioni per quanto riguarda il filesystem e indirizzerò all'utilizzo di comandi in maniera più specifica, spero questa introduzione possa esservi utile!
 
Top