Come shell predefinita per molte delle varianti Linux e Unix, Bash include un'ampia varietà di funzionalità sottoutilizzate, quindi era difficile decidere di cosa discutere. Alla fine, ho deciso di concentrarmi sui suggerimenti di Bash che semplificano le attività quotidiane.
Come consulente, vedo una pluralità di ambienti e stili di lavoro diversi. Ho attinto a questa esperienza per restringere i suggerimenti a quattro grandi categorie:trucchi per terminali e linee, navigazione e file, cronologia e comandi utili. Queste categorie sono del tutto arbitrarie e servono più a organizzare i miei pensieri che a qualsiasi tipo di classificazione definitiva. Molti dei suggerimenti qui inclusi potrebbero rientrare soggettivamente in più di una categoria.
Senza ulteriori indugi, ecco alcuni dei trucchi Bash più utili che ho riscontrato.
Lavorare con la cronologia di Bash
Uno dei modi migliori per aumentare la produttività è imparare a utilizzare la cronologia di Bash in modo più efficace. Con questo in mente, forse una delle modifiche più importanti che puoi apportare in un ambiente multiutente è abilitare l'histappend
opzione alla tua shell. Per farlo, esegui semplicemente il seguente comando:
shopt -s histappend
Ciò consente a più sessioni del terminale di scrivere nella cronologia contemporaneamente. Nella maggior parte degli ambienti questa opzione non abilitato. Ciò significa che spesso le cronologie vengono perse se hai più di una singola sessione Bash aperta (in locale o tramite SSH).
Un'altra operazione comune è ripetere l'ultimo comando con sudo
. Ad esempio, supponiamo di voler creare una directory mkdir /etc/ansible/facts.d
. A meno che tu non sia root, questo comando fallirà. Da quello che ho osservato, la maggior parte degli utenti ha raggiunto il up
freccia, scorri fino all'inizio della riga e aggiungi il sudo
comando. C'è un modo più semplice. Basta eseguire il comando in questo modo:
sudo !!
Bash eseguirà sudo
e poi l'intero comando precedente. Ecco esattamente come appare quando viene eseguito in sequenza:
[user@centos ~]$ mkdir -p /etc/ansible/facts.d
mkdir: cannot create directory ‘/etc/ansible’: Permission denied
[user@centos ~]$ sudo !!
sudo mkdir -p /etc/ansible/facts.d
Quando il !!
viene eseguito, il comando completo viene trasmesso al terminale in modo da sapere cosa è stato appena eseguito.
Simile ma usato molto meno frequentemente è il !*
scorciatoia. Questo dice a Bash che vuoi tutti gli *argomenti* dal comando precedente da ripetere nel comando corrente. Questo potrebbe essere utile per un comando che ha molti argomenti che vuoi riutilizzare. Un semplice esempio è la creazione di un gruppo di file e la modifica dei permessi su di essi:
[user@centos tmp]$ touch file1 file2 file3 file4
[user@centos tmp]$ chmod 777 !*
chmod 777 file1 file2 file3 file4
È utile solo in una serie specifica di circostanze, ma potrebbe farti risparmiare alcune sequenze di tasti.
Parlando di salvataggio delle sequenze di tasti, parliamo di trovare comandi nella cronologia. La maggior parte degli utenti farà qualcosa del genere:
history |grep <some command>
Tuttavia, c'è un modo più semplice per cercare nella cronologia. Se premi
ctrl + r
Bash eseguirà una ricerca inversa della tua cronologia. Quando inizi a digitare, i risultati inizieranno ad apparire. Ad esempio:
(reverse-i-search)`hist': shopt -s histappend
Nell'esempio sopra, ho digitato hist
e corrispondeva a shopt
comando che abbiamo trattato in precedenza. Se continui a premere ctrl + r
, Bash continuerà a cercare all'indietro in tutte le altre corrispondenze.
Il nostro ultimo trucco non è tanto un trucco quanto un comando utile che puoi utilizzare per contare e visualizzare i comandi più utilizzati nella cronologia.
[user@centos tmp]$ history | awk 'BEGIN {FS="[ \t]+|\\|"} {print $3}' | sort | uniq -c | sort -nr | head
81 ssh
50 sudo
46 ls
45 ping
39 cd
29 nvidia-xrun
20 nmap
19 export
In questo esempio, puoi vedere quel ssh
è di gran lunga il comando più utilizzato nella mia storia al momento.
Navigazione e denominazione dei file
Più risorse Linux
- Comandi Linux cheat sheet
- Cheat sheet sui comandi avanzati di Linux
- Corso online gratuito:Panoramica tecnica RHEL
- Cheat sheet della rete Linux
- Cheat sheet di SELinux
- Cheat sheet dei comandi comuni di Linux
- Cosa sono i container Linux?
- I nostri ultimi articoli su Linux
Probabilmente sai già che se digiti un comando, un nome di file o un nome di cartella, puoi premere il tab
chiave una volta per completare la formulazione per te. Funziona se esiste una singola corrispondenza esatta. Tuttavia, potresti non saperlo se premi tab
due volte, ti mostrerà tutte le corrispondenze in base a ciò che hai digitato. Ad esempio:
[user@centos tmp]$ cd /lib <tab><tab>
lib/ lib64/
Questo può essere molto utile per la navigazione nel file system. Un altro trucco utile è abilitare cdspell
nel tuo guscio Puoi farlo emettendo il shopt -s cdspell
comando. Questo ti aiuterà a correggere i tuoi errori di battitura:
[user@centos etc]$ cd /tpm
/tmp
[user@centos tmp]$ cd /ect
/etc
Non è perfetto, ma ogni piccola cosa aiuta!
Dopo aver cambiato con successo le directory, cosa succede se è necessario tornare alla directory precedente? Questo non è un grosso problema se non sei molto in profondità nell'albero delle directory. Ma se sei in un percorso abbastanza profondo, come /var/lib/flatpak/exports/share/applications/
, puoi digitare:
cd /va<tab>/lib/fla<tab>/ex<tab>/sh<tab>/app<tab>
Fortunatamente, Bash ricorda la tua directory precedente e puoi tornarci semplicemente digitando cd -
. Ecco come sarebbe:
[user@centos applications]$ pwd
/var/lib/flatpak/exports/share/applications
[user@centos applications]$ cd /tmp
[user@centos tmp]$ pwd
/tmp
[user@centos tmp]$ cd -
/var/lib/flatpak/exports/share/applications
Va tutto bene, ma cosa succede se hai un sacco di directory in cui vuoi navigare facilmente? Bash ti ha coperto anche lì. C'è una variabile che puoi impostare che ti aiuterà a navigare in modo più efficace. Ecco un esempio:
[user@centos applications]$ export CDPATH='~:/var/log:/etc'
[user@centos applications]$ cd hp
/etc/hp
[user@centos hp]$ cd Downloads
/home/user/Downloads
[user@centos Downloads]$ cd ansible
/etc/ansible
[user@centos Downloads]$ cd journal
/var/log/journal
Nell'esempio sopra, ho impostato la mia home directory (indicata con la tilde:~
), /var/log
e /etc
. Qualsiasi cosa al livello più alto di queste directory verrà compilata automaticamente quando ci si fa riferimento. Directory che non sono alla base delle directory elencate in CDPATH
non sarà trovato. Se, ad esempio, la directory che stai cercando fosse /etc/ansible/facts.d/
questo non verrebbe completato digitando cd facts.d
. Questo perché mentre la directory ansible
si trova in /etc
, facts.d
non è. Pertanto, CDPATH
è utile per raggiungere la cima di un albero a cui accedi di frequente, ma può diventare complicato da gestire quando esplori una struttura di cartelle di grandi dimensioni.
Infine, parliamo di due casi d'uso comuni che tutti fanno a un certo punto:modificare l'estensione di un file e rinominare i file. A prima vista, potrebbe sembrare la stessa cosa, ma Bash offre alcuni trucchi diversi per svolgere queste attività.
Sebbene possa essere un'operazione "sporca e sporca", la maggior parte degli utenti a un certo punto deve creare una copia rapida di un file su cui stanno lavorando. La maggior parte copierà esattamente il nome del file e aggiungerà semplicemente un'estensione di file come .old
o .bak
. C'è una rapida scorciatoia per questo in Bash. Supponiamo di avere un nome file come spideroak_inotify_db.07pkh3
di cui vuoi conservare una copia. Potresti digitare:
cp spideroak_inotify_db.07pkh3 spideroak_inotify_db.07pkh3.bak
Puoi fare un lavoro veloce usando le operazioni di copia/incolla, usando la scheda completa, possibilmente usando una delle scorciatoie per ripetere un argomento o semplicemente digitando il tutto. Tuttavia, il comando seguente dovrebbe rivelarsi ancora più veloce una volta che ti sarai abituato a digitarlo:
cp spideroak_inotify_db.07pkh3{,.old}
Questo (come puoi intuire) copia il file aggiungendo il .old
estensione del file al file. È fantastico, potresti dire, ma voglio rinominare un gran numero di file contemporaneamente. Certo, potresti scrivi un ciclo for per gestirli (e in effetti, lo faccio spesso per qualcosa di complicato), ma perché dovresti quando c'è una pratica utility chiamata rename
? C'è una certa differenza nell'uso di questa utility tra Debian/Ubuntu e CentOS/Arch. La ridenominazione basata su Debian usa una sintassi simile a SED:
user@ubuntu-1604:/tmp$ for x in `seq 1 5`; do touch old_text_file_${x}.txt; done
user@ubuntu-1604:/tmp$ ls old_text_file_*
old_text_file_1.txt old_text_file_3.txt old_text_file_5.txt
old_text_file_2.txt old_text_file_4.txt
user@ubuntu-1604:/tmp$ rename 's/old_text_file/shiney_new_doc/' *.txt
user@ubuntu-1604:/tmp$ ls shiney_new_doc_*
shiney_new_doc_1.txt shiney_new_doc_3.txt shiney_new_doc_5.txt
shiney_new_doc_2.txt shiney_new_doc_4.txt
Su una casella CentOS o Arch sarebbe simile:
[user@centos /tmp]$ for x in `seq 1 5`; do touch old_text_file_${x}.txt; done
[user@centos /tmp]$ ls old_text_file_*
old_text_file_1.txt old_text_file_3.txt old_text_file_5.txt
old_text_file_2.txt old_text_file_4.txt
[user@centos tmp]$ rename old_text_file centos_new_doc *.txt
[user@centos tmp]$ ls centos_new_doc_*
centos_new_doc_1.txt centos_new_doc_3.txt centos_new_doc_5.txt
centos_new_doc_2.txt centos_new_doc_4.txt
Bash key binding
Bash ha molte scorciatoie da tastiera integrate. Puoi trovarne un elenco digitando bind -p
. Ho pensato che sarebbe stato utile metterne in evidenza diversi, anche se alcuni potrebbero essere noti.
- ctrl + _ (annulla)
- ctrl + t (scambia due caratteri)
- ALT + t (scambia due parole)
- ALT + . (stampa l'ultimo argomento del comando precedente)
- ctrl + x + * (espandi globo/stella)
- ctrl + freccia (vai avanti di una parola)
- ALT+f (vai avanti di una parola)
- ALT + b (sposta indietro di una parola)
- ctrl + x seguito da ctrl + e (apre la stringa di comando in un editor in modo da poterla modificare prima dell'esecuzione)
- ctrl + e (sposta il cursore alla fine)
- ctrl + a (sposta il cursore per iniziare)
- ctrl + xx (sposta all'estremità opposta della linea)
- ctrl + u (taglia tutto prima del cursore)
- ctrl + k (taglia tutto dopo il cursore)
- ctrl + y (incolla dal buffer)
- ctrl + l (L minuscola, cancella lo schermo)
Non parlerò di quelli più ovvi. Tuttavia, alcune delle scorciatoie più utili che ho trovato sono quelle che ti consentono di eliminare parole (o sezioni di testo) e annullarle. Supponiamo che tu stia per interrompere un gruppo di servizi utilizzando systemd
, ma volevi avviarne solo alcuni dopo il completamento di alcune operazioni. Potresti fare qualcosa del genere:
systemctl stop httpd mariadb nfs smbd
<hit the up button to get the previous command>
<use 'ctrl + w' to remove the unwanted arguments>
Ma cosa succede se ne togli uno di troppo? Nessun problema:usa semplicemente ctrl + _
per annullare l'ultima modifica.
Gli altri comandi di taglio consentono di rimuovere rapidamente tutto dal cursore fino alla fine o all'inizio della riga (usando Ctrl + k
e Ctrl + u
, rispettivamente). Questo ha l'ulteriore vantaggio di posizionare il testo tagliato nel buffer del terminale in modo da poterlo incollare in seguito (usando ctrl + y
). Questi comandi sono difficili da dimostrare qui, quindi ti consiglio vivamente di provarli da solo.
Ultimo ma non meno importante, vorrei citare una combinazione di tasti usata di rado che può essere estremamente utile in ambienti ristretti come i container. Se un comando sembra confuso dall'output precedente, c'è una soluzione:premendo ctrl + x + ctrl + e
aprirà il comando in qualsiasi editor sia impostato nella variabile di ambiente EDITOR. Ciò ti consentirà di modificare un comando lungo o confuso in un editor di testo che (potenzialmente) può avvolgere il testo. Il salvataggio del lavoro e l'uscita, proprio come si farebbe quando si lavora su un file normale, eseguirà il comando all'uscita dall'editor.
Suggerimenti vari
Potresti scoprire che avere i colori visualizzati nella tua shell Bash può migliorare la tua esperienza. Se stai utilizzando una sessione in cui non è abilitata la colorazione, di seguito sono riportati una serie di comandi che puoi inserire nel tuo .bash_profile
per aggiungere colore alla tua sessione. Questi sono abbastanza semplici e non dovrebbero richiedere una spiegazione approfondita:
# enable colors
eval "`dircolors -b`"
# force ls to always use color and type indicators
alias ls='ls -hF --color=auto'
# make the dir command work kinda like in windows (long format)
alias dir='ls --color=auto --format=long'
# make grep highlight results using color
export GREP_OPTIONS='--color=auto'
# Add some colour to LESS/MAN pages
export LESS_TERMCAP_mb=$'\E[01;31m'
export LESS_TERMCAP_md=$'\E[01;33m'
export LESS_TERMCAP_me=$'\E[0m'
export LESS_TERMCAP_se=$'\E[0m'
export LESS_TERMCAP_so=$'\E[01;42;30m'
export LESS_TERMCAP_ue=$'\E[0m'
export LESS_TERMCAP_us=$'\E[01;36m'
Oltre a regolare le varie opzioni all'interno di Bash, puoi anche utilizzare alcuni trucchi accurati per risparmiare tempo. Ad esempio, per eseguire due comandi uno dopo l'altro, indipendentemente dallo stato di uscita di ciascuno, utilizzare il ;
per separare i comandi, come mostrato di seguito:
[user@centos /tmp]$ du -hsc * ; df -h
Questo calcola semplicemente la quantità di spazio occupata da ciascun file nella directory corrente (e la somma), quindi interroga il sistema per l'utilizzo del disco per dispositivo a blocchi. Questi comandi verranno eseguiti indipendentemente da eventuali errori generati da du
comando.
Cosa succede se si desidera eseguire un'azione al completamento con successo del primo comando? Puoi usare il &&
scorciatoia per indicare che si desidera eseguire il secondo comando solo se il primo comando restituisce uno stato di uscita corretto. Ad esempio, supponiamo di voler riavviare una macchina solo se gli aggiornamenti hanno esito positivo:
[root@arch ~]$ pacman -Syu --noconfirm && reboot
A volte durante l'esecuzione di un comando, potresti voler catturare il suo output. La maggior parte delle persone conosce il tee
comando, che copierà l'output standard sia sul terminale che su un file. Tuttavia, se desideri acquisire un output più complesso, ad esempio, da strace
, dovrai iniziare a lavorare con il reindirizzamento I/O. I dettagli del reindirizzamento I/O esulano dallo scopo di questo breve articolo, ma per i nostri scopi ci occupiamo di STDOUT
e STDERR
. Il modo migliore per catturare esattamente ciò che stai vedendo è combinare i due in un unico file. Per farlo, usa 2>&1
reindirizzamento.
[root@arch ~]$ strace -p 1140 > strace_output.txt 2>&1
Questo metterà tutto l'output rilevante in un file chiamato strace_output.txt
per la visualizzazione in seguito.
A volte, durante un comando di lunga durata, potrebbe essere necessario sospendere l'esecuzione di un'attività. Puoi usare la scorciatoia 'stop' ctrl + z
fermare (ma non uccidere) un lavoro. Il lavoro viene aggiunto alla coda dei lavori, ma non lo vedrai più finché non lo riprenderai. Questo lavoro può essere ripreso in un secondo momento usando il comando in primo piano fg
.
Inoltre, puoi anche semplicemente mettere in pausa un lavoro con ctrl + s
. Il lavoro e il relativo output rimangono in primo piano nel terminale e l'uso della shell non restituito all'utente. Il lavoro può essere ripreso premendo ctrl + q
.
Se stai lavorando in un ambiente grafico con molti terminali aperti, potresti trovare utile avere scorciatoie da tastiera per copiare e incollare l'output. Per farlo, usa le seguenti scorciatoie:
# Copies highlighted text
ctrl + shift + c
# Pastes text in buffer
ctrl + shift + v
Supponiamo nell'output di un comando in esecuzione di vedere un altro comando in esecuzione e di voler ottenere maggiori informazioni. Ci sono alcuni modi per farlo. Se questo comando è nel tuo percorso da qualche parte, puoi eseguire il which
comando per scoprire dove si trova quel comando sul tuo disco:
[root@arch ~]$ which ls
/usr/bin/ls
Con queste informazioni, puoi ispezionare il binario con il file
comando:
[root@arch ~]$ file /usr/bin/ls
/usr/bin/ls: ELF 64-bit LSB pie executable x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=d4e02b88e596e4f82c6cc62a5bc4ce5827209a49, stripped
Puoi vedere tutti i tipi di informazioni, ma la più importante per la maggior parte degli utenti è l'ELF 64-bit LSB
senza senso. Ciò significa essenzialmente che si tratta di un binario precompilato anziché di uno script o di un altro tipo di eseguibile. Uno strumento correlato che puoi utilizzare per ispezionare i comandi è il command
strumento stesso. Semplicemente eseguendo command -V <command>
ti darà diversi tipi di informazioni:
[root@arch ~]$ command -V ls
ls is aliased to `ls --color=auto`
[root@arch ~]$ command -V bash
bash is /usr/bin/bash
[root@arch ~]$ command -V shopt
shopt is a shell builtin
Ultimo ma sicuramente non meno importante, uno dei miei trucchi preferiti, soprattutto quando lavoro con i container o in ambienti in cui ho poca conoscenza o controllo, è l'echo
comando. Questo comando può essere utilizzato per fare qualsiasi cosa, dal controllo per assicurarsi che il tuo for
loop eseguirà la sequenza prevista per consentire di verificare se le porte remote sono aperte. La sintassi è molto semplice da verificare per una porta aperta:echo > /dev/<udp or tcp>/<server ip>/<port>
. Ad esempio:
user@ubuntu-1604:~$ echo > /dev/tcp/192.168.99.99/222
-bash: connect: Connection refused
-bash: /dev/tcp/192.168.99.99/222: Connection refused
user@ubuntu-1604:~$ echo > /dev/tcp/192.168.99.99/22
Se la porta è chiusa al tipo di connessione che stai tentando di effettuare, riceverai un Connection refused
Messaggio. Se il pacchetto viene inviato con successo, non ci sarà alcun output.
Spero che questi suggerimenti rendano Bash più efficiente e divertente da usare. Ci sono molti più trucchi nascosti in Bash di quelli che ho elencato qui. Quali sono i tuoi preferiti?
Appendice 1. Elenco di suggerimenti e trucchi trattati
# History related
ctrl + r (reverse search)
!! (rerun last command)
!* (reuse arguments from previous command)
!$ (use last argument of last command)
shopt -s histappend (allow multiple terminals to write to the history file)
history | awk 'BEGIN {FS="[ \t]+|\\|"} {print $3}' | sort | uniq -c | sort -nr | head (list the most used history commands)
# File and navigation
cp /home/foo/realllylongname.cpp{,-old}
cd -
rename 's/text_to_find/been_renamed/' *.txt
export CDPATH='/var/log:~' (variable is used with the cd built-in.)
# Colourize bash
# enable colors
eval "`dircolors -b`"
# force ls to always use color and type indicators
alias ls='ls -hF --color=auto'
# make the dir command work kinda like in windows (long format)
alias dir='ls --color=auto --format=long'
# make grep highlight results using color
export GREP_OPTIONS='--color=auto'
export LESS_TERMCAP_mb=$'\E[01;31m'
export LESS_TERMCAP_md=$'\E[01;33m'
export LESS_TERMCAP_me=$'\E[0m'
export LESS_TERMCAP_se=$'\E[0m' # end the info box
export LESS_TERMCAP_so=$'\E[01;42;30m' # begin the info box
export LESS_TERMCAP_ue=$'\E[0m'
export LESS_TERMCAP_us=$'\E[01;36m'
# Bash shortcuts
shopt -s cdspell (corrects typoos)
ctrl + _ (undo)
ctrl + arrow (move forward a word)
ctrl + a (move cursor to start)
ctrl + e (move cursor to end)
ctrl + k (cuts everything after the cursor)
ctrl + l (clears screen)
ctrl + q (resume command that is in the foreground)
ctrl + s (pause a long running command in the foreground)
ctrl + t (swap two characters)
ctrl + u (cuts everything before the cursor)
ctrl + x + ctrl + e (opens the command string in an editor so that you can edit it before it runs)
ctrl + x + * (expand glob/star)
ctrl + xx (move to the opposite end of the line)
ctrl + y (pastes from the buffer)
ctrl + shift + c/v (copy/paste into terminal)
# Running commands in sequence
&& (run second command if the first is successful)
; (run second command regardless of success of first one)
# Redirecting I/O
2>&1 (redirect stdout and stderr to a file)
# check for open ports
echo > /dev/tcp/<server ip>/<port>
`` (use back ticks to shell out)
# Examine executable
which <command>
file <path/to/file>
command -V <some command binary> (tells you whether <some binary> is a built-in, binary or alias)