Differences between revisions 4 and 6 (spanning 2 versions)
Revision 4 as of 2013-06-08 15:18:38
Size: 8276
Comment: sync with English master
Revision 6 as of 2020-03-26 12:32:49
Size: 9226
Comment: sync with English master v. 23
Deletions are marked like this. Additions are marked like this.
Line 7: Line 7:
Notare: #debian non è necessariamente il posto migliore per trovare aiuto con gli script shell. Se si ha un problema con uno script che ha a che fare con bash (o la shell Bourne), si potrebbe provare piuttosto #bash. La FAQ di #bash è all'indirizzo http://mywiki.wooledge.org/BashFAQ e contiene molti più trucchi di quanto non faccia questa pagina. {{{#!wiki note
'''
Nota:''' Il Wiki Debian non è necessariamente il posto migliore per trovare aiuto con gli script shell. Se si ha un problema con uno script che ha a che fare con bash (o la shell Bourne), si potrebbe provare piuttosto la [[it/Bash|pagina di bash]]. Una FAQ di bash è all'indirizzo http://mywiki.wooledge.org/BashFAQ e contiene molti più trucchi di quanto non faccia questa pagina. }}}
Line 12: Line 13:
df -h per un formato intelligibile in mega & giga}}} df -h  # per un formato intelligibile in mega & giga}}}
Line 129: Line 130:
cp grandefile grandefile2 &}}}
o premere ''Ctrl+Z'' mentre il comando è in esecuzione (ciò lo fermerà) e, per esempio, usare:

{{{
bg cp}}}
per far sì che continui a funzionare, poi usare

{{{
fg cp}}}
per rispostarlo in primo piano (''Ctrl+Z'' lo potrà poi fermare di nuovo ed inviarlo allo sfondo) e usare

{{{
kill cp}}}
per terminarlo.
sleep 100 &}}}
Visualizza una riga simile a: {{{ [1] 6338 }}}, che indica che questo processo è il compito numero 1 e che il suo ID di processo è 6338.

Per uccidere questo compito:
{{{
kill %1 }}}
o {{{
kill 6338 }}}

Nota: se sono stati avviati molti processi sullo sfondo e si desidera vederne l'elenco usare {{{jobs}}}.

Si può anche far passare un compito in esecuzione sullo sfondo all'esecuzione in primo piano, poi sospenderlo e poi riavviarlo sullo sfondo.
Avviare un processo sullo sfondo:
{{{
sleep 100 &}}}
Per spostarlo in primo piano (assumendo che sia il compito numero 1): {{{
fg %1}}}
Poi premere ''Ctrl+Z''. Questo sospende il processo e lo manda sullo sfondo.
Ora riavviare il processo sospeso lasciandolo sullo sfondo:{{{
bg %1}}}
Per uccidere questo compito:
{{{
kill %1}}}
Line 211: Line 221:


----
CategorySystemAdministration | CategoryCommandLineInterface |
## CategoryRedundant: merge some parts with other shell/CLI pages (ShellScripting)
## ShellScripting does not exist (anymore) . As a personal comment - Would be nice to not delete this info. Rather rename/make it a subpage/ecc. (yes bits and pieces are in other pages, see first question and FreeDisk page, but it is a nice reading all in one page).

Translation(s): English - Français - Italiano

Trucchi con gli script di shell

Nota: Il Wiki Debian non è necessariamente il posto migliore per trovare aiuto con gli script shell. Se si ha un problema con uno script che ha a che fare con bash (o la shell Bourne), si potrebbe provare piuttosto la pagina di bash. Una FAQ di bash è all'indirizzo http://mywiki.wooledge.org/BashFAQ e contiene molti più trucchi di quanto non faccia questa pagina.

Come vedere quanto spazio su disco è rimasto?

df 
df -h  # per un formato intelligibile in mega & giga

Come vedere dove sono tutti i file grandi? Il filesystem è pieno.

cd /qualcheparte
du -sk * | sort -n
# Ripetere quante volte è necessario

Se si vuole vedere quali sono le directory grandi invece dei file, si può fare:

du -x /qualcheparte | sort -n | tail -10
# Questo mostra le 10 più grandi directory in /qualcheparte

Un altro modo:

find /qualcheparte -size +2000k -ls
# Questo mostra tutti i file più grandi di 2000 kilobyte in /qualcheparte

Se si vuole tenere i propri file .dev, si possono filtrarli fuori dall'elenco

find / -size +2000k ! -name "*.deb" -ls
# Questo mostra tutti i file nell'intero filesystem più grandi di 2000 kilobyte che non sono pacchetti Debian

Una directory è piena di MP3... come rinominarli tutti in modo da avere segni di sottolineatura al posto degli spazi?

rename 's/ /_/g' *.mp3

Il comando rename non è un comando generale di Unix, ma è incluso con Perl, che è naturalmente installato in modo predefinito in Debian.

Come farlo in modo ricorsivo?

È un po' complicato. Si può ottenere usando find un elenco di file da passare a rename, ma se vengono rinominate anche alcune delle directory rename non può tenerne traccia. Si deve usare l'opzione -depth con find per assicurarsi che ciascun file sia rinominato prima della directory che lo contiene.

cd /qualcheparte
find . -depth -name '* *' -type f -print0 | xargs -r0 rename 's/ /_/g'

Come rinominare (ricorsivamente) tutti i file sostituendo la maiuscole con minuscole?

Ancora una volta questo è complicato se le directory stesse hanno lettere maiuscole all'interno dei loro nomi. Assumiamo per il momento che non le abbiano. Allora usare:

cd /qualcheparte
find . -name '*[A-Z]*' -type f -print0 | xargs -0 rename 'y/A-Z/a-z/'

Sfortunatamente, ogni volta che questo quesito viene riproposto, ciò non è sufficiente: chi chede aiuto di solito ha anche lettere maiuscole nei nomi di directory. Perciò potrebbe essere richiesto qualcosa di simile a:

cd /qualcheparte
find . -type d -depth -name '*[A-Z]*' -print |
  while read dir; do dname="$(dirname $dir)"; bname="$(basename $dir)";
  newbname="$(echo $bname | tr [:upper:] [:lower:])"; mv "$dir" "$dname/$newbname"; done
# Che rinomina le directory. L'opzione -depth lo fa iniziare prima dalle directory più profonde, in modo che
# A viene rinominata quando A/B è già stata rinominata in A/b.
find . -name '*[A-Z]*' -type f -print0 | xargs -0 rename 'y/A-Z/a-z/'

Si noti che lo script più complesso qui sopra è imperfetto: fallisce se ci sono caratteri "a capo" nel nome delle directory e può anche fallire, in talune circostanze, se i nomi di file o directory contengono spazi. Usarlo a proprio rischio e pericolo. (Suggerimento: se si vuole testarlo prima di affidarvicisi, aggiungere un echo davanti a mv.)

In realtà questa soluzione più semplice potrebbe funzionare meglio:

find /qualcheparte -depth -name '*[A-Z]*' -print0 | xargs -r0 rename 'y/A-Z/a-z/'

Anche qui potrebbe essere una buona idea mettere un echo prima del comando rename per testarlo prima di eseguirlo realmente.

Come rimuovere i file che iniziano con "-"?

unlink -pippo

Ci sono tre modi diversi:

rm -- -foo
rm ./-foo
usando 'mc' e premendo F8 sul file interessato

Questi due trucchi funzionano con quasi qualunque strumento a riga di comando, non solo con rm.

Come monitorare qualche cosa in tempo reale?

Se è un file di log, seguire l'ultima parte del file:

tail -f /var/log/messages

oppure

less +F /var/log/messages

Se è un comando generico, usare watch:

watch -n 1 ls -l ~/qualche/file

Questo funziona bene per monitorare un firewall con iptables / tc o cose simili.

Come ottenere solo il nome file da un percorso completo di file?

Ci sono due modi:

basename /percorso/al/file
pippo=/percorso/al/file ; echo ${pippo##*/}

Come testare se una directory contiene o meno file?

if [ "$(ls -A qualchedir)" ]; then
    echo "Contiene file"
fi

Notare: un singolo argomento all'interno delle parentesi quadre equivale a [ -n argomento ]. Sembra non esserci un modo pulito per fare questo usando solo i comandi interni della shell. (C'è stato un tentativo che ci è andato vicino, ma è fallito in presenza di un file chiamato * all'interno della directory.)

Un altro metodo:

if [ "$(ls -A qualchedir | wc -l)" -gt 0 ]; then
    echo "Trovati file"
fi

Un metodo più corto: [ $(ls -A qualchedir) ] && echo "La directory non e' vuota"

Notare: il doppio carattere & funziona come un AND booleano, perciò non è necessario usare "if".

Come avviare un processo sullo sfondo?

Basta aggiungere in fondo una e commerciale (&):

sleep 100 &

Visualizza una riga simile a:  [1] 6338 , che indica che questo processo è il compito numero 1 e che il suo ID di processo è 6338.

Per uccidere questo compito:

kill %1 

o

kill 6338 

Nota: se sono stati avviati molti processi sullo sfondo e si desidera vederne l'elenco usare jobs.

Si può anche far passare un compito in esecuzione sullo sfondo all'esecuzione in primo piano, poi sospenderlo e poi riavviarlo sullo sfondo. Avviare un processo sullo sfondo:

sleep 100 &

Per spostarlo in primo piano (assumendo che sia il compito numero 1):

fg %1

Poi premere Ctrl+Z. Questo sospende il processo e lo manda sullo sfondo. Ora riavviare il processo sospeso lasciandolo sullo sfondo:

bg %1

Per uccidere questo compito:

kill %1

Come lavorare con array in bash?

Assegnare ad un array:

arr=(uno due tre quattro)
mieiogg=(*.ogg)

Iterazioni in uno:

for f in "${mieiogg[@]}"; do ...; done

Selezionare un elemento casuale:

miefirme=($HOME/firme/*)
cat ${miefirme[RANDOM % ${#miefirme[*]}]}

(Nell'esempio precedente notare che le parentesi per l'indice dell'array forzano anche un contesto di valutazione numerica, in cui non è necessario che RANDOM sia preceduto da un carattere $.)

Non si può facilmente cancellare un elemento dal mezzo di un array, ma si può aggirare la cosa reindicizzando l'array saltando tutti gli elementi su cui si è usato unset:

arr=(zero uno due tre quattro)
unset arr[1]
arr=("${arr[@]}")

Questo lascerà al loro posto tutti gli elementi "vuoti", cancellando solo quelli "unset".

Come usare una variabile all'interno di una variabile (interpolazione di variabili) in bash?

Se si vuole fare qualcosa del tipo ${$var}, usare questo formato: ${!var}

Perciò se si ha:

PIPPO=uno
PLUTO=PIPPO

allora ${!PLUTO} restituisce "uno"

Questo funziona solo se si fa riferimento ad una variabile esistente, non per l'assegnazione di una variabile. Se si vuole assegnare un nome di variabile generato dinamicamente, si deve usare eval:

IFACE=eth0
eval IP_${IFACE}=192.168.1.1

o, in molti casi, usare semplicemente un array:

N=17
ROW[N]="Questa e' la diciottesima riga (contando da 0)."

Il trucco di usare eval può essere usato anche per far riferimento ad una variabile esistente:

IFACE=eth0
eval echo \$IP_${IFACE}

l'uso di eval genera un secondo passaggio sul codice. Il primo passaggio sostituisce $ a \$ e poi sostituisce il valore di ${IFACE}, ottenendo "eval echo $IP_eth0". Il secondo passaggio sostituisce quindi il valore della variabile ${IP_eth0}, premesso che esista.

Come contare le righe di file con una determinata estensione in una determinata directory?

find $dir -name *.[$estensioni] -exec cat \{\} \; | wc -l

trova i file in $dir con una qualsiasi delle estensioni $estensioni e legge i file usando cat e poi usando 'wc -l' per contare le righe di testo.

Si può fare anche

wc -l $dir/*.$estensioni


CategorySystemAdministration | CategoryCommandLineInterface |