Size: 8434
Comment:
|
Size: 8276
Comment: sync with English master
|
Deletions are marked like this. | Additions are marked like this. |
Line 2: | Line 2: |
||<tablestyle="width: 100%;" style="border: 0px hidden">~-[[DebianWiki/EditorGuide#translation|Translation(s)]]: [[ShellTricks|English]] - [[fr/ShellTricks|Français]] - [[it/ShellTricks|Italiano]]-~||<style="text-align: right;border: 0px hidden"> (!) [[/Discussion|Discussion]]|| |
~-[[DebianWiki/EditorGuide#translation|Translation(s)]]: [[ShellTricks|English]] - [[fr/ShellTricks|Français]] - Italiano-~ |
Line 8: | 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://wooledge.org/mywiki/BashFaq e contiene molti più trucchi di quanto non faccia questa pagina. | 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. |
Translation(s): English - Français - Italiano
Contents
-
Trucchi con gli script di shell
- Come vedere quanto spazio su disco è rimasto?
- Come vedere dove sono tutti i file grandi? Il filesystem è pieno.
- Una directory è piena di MP3... come rinominarli tutti in modo da avere segni di sottolineatura al posto degli spazi?
- Come farlo in modo ricorsivo?
- Come rinominare (ricorsivamente) tutti i file sostituendo la maiuscole con minuscole?
- Come rimuovere i file che iniziano con "-"?
- Come monitorare qualche cosa in tempo reale?
- Come ottenere solo il nome file da un percorso completo di file?
- Come testare se una directory contiene o meno file?
- Come avviare un processo sullo sfondo?
- Come lavorare con array in bash?
- Come usare una variabile all'interno di una variabile (interpolazione di variabili) in bash?
- Come contare le righe di file con una determinata estensione in una determinata directory?
Trucchi con gli script di shell
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.
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 (&):
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.
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