Qual è il tuo trucco da riga di comando preferito usando Bash?[Chiuso]
-
09-06-2019 - |
Domanda
Sappiamo tutti come usare <ctrl>-R
per invertire la ricerca nella cronologia, ma sapevi che puoi usare <ctrl>-S
per inoltrare la ricerca se impostato stty stop ""
?Inoltre, hai mai provato a eseguire bind -p per visualizzare tutte le scorciatoie da tastiera elencate?Ce ne sono oltre 455 su Mac OS X per impostazione predefinita.
Qual è il tuo trucco oscuro preferito, la scorciatoia da tastiera o la configurazione shopt che preferisci utilizzando bash?
Soluzione 7
Quando eseguo i comandi, a volte vorrò eseguire un comando con gli argomenti precedenti.Per fare ciò, puoi usare questa scorciatoia:
$ mkdir /tmp/new
$ cd !!:*
Occasionalmente, invece di utilizzare find, creerò un ciclo di una riga se devo eseguire una serie di comandi su un elenco di file.
for file in *.wav; do lame "$file" "$(basename "$file" .wav).mp3" ; done;
Configurare le opzioni della cronologia della riga di comando nel mio .bash_login (o .bashrc) è davvero utile.Quello che segue è un quadro di impostazioni che utilizzo sul mio Macbook Pro.
L'impostazione di quanto segue fa sì che bash cancelli i comandi duplicati nella cronologia:
export HISTCONTROL="erasedups:ignoreboth"
Inoltre, ho aumentato anche le dimensioni della mia cronologia piuttosto in alto.Perché no?Non sembra rallentare nulla sui microprocessori di oggi.
export HISTFILESIZE=500000
export HISTSIZE=100000
Un'altra cosa che faccio è ignorare alcuni comandi della mia cronologia.Non è necessario ricordare il comando di uscita.
export HISTIGNORE="&:[ ]*:exit"
Vuoi assolutamente impostare histappend.Altrimenti, bash sovrascrive la cronologia quando esci.
shopt -s histappend
Un'altra opzione che utilizzo è cmdhist.Ciò ti consente di salvare comandi su più righe nella cronologia come un unico comando.
shopt -s cmdhist
Infine, su Mac OS X (se non stai utilizzando la modalità vi), ti consigliamo di ripristinare <CTRL>-S dall'arresto dello scorrimento.Ciò impedisce a bash di interpretarlo come ricerca in avanti.
stty stop ""
Altri suggerimenti
Rinominare/spostare rapidamente file con suffissi:
cp /home/foo/realllylongname.cpp{,-old}
Questo si espande a:
cp /home/foo/realllylongname.cpp /home/foo/realllylongname.cpp-old
cd -
È l'equivalente da riga di comando del pulsante Indietro (ti porta alla directory precedente in cui ti trovavi).
Un altro preferito:
!!
Ripete il tuo ultimo comando.Molto utile nella forma:
sudo !!
Il mio preferito è '^string^string2' che prende l'ultimo comando, sostituisce string con string2 e lo esegue
$ ehco foo bar baz
bash: ehco: command not found
$ ^ehco^echo
foo bar baz
rinominare
Esempio:
$ ls
this_has_text_to_find_1.txt
this_has_text_to_find_2.txt
this_has_text_to_find_3.txt
this_has_text_to_find_4.txt
$ rename 's/text_to_find/been_renamed/' *.txt
$ ls
this_has_been_renamed_1.txt
this_has_been_renamed_2.txt
this_has_been_renamed_3.txt
this_has_been_renamed_4.txt
Così utile
Sono un fan di !$
, !^
E !*
expandos, di ritorno, dalla riga di comando inviata più recente:l'ultimo elemento, il primo elemento non di comando e tutti gli elementi non di comando.Vale a dire (notare che la shell stampa prima il comando):
$ echo foo bar baz
foo bar baz
$ echo bang-dollar: !$ bang-hat: !^ bang-star: !*
echo bang-dollar: baz bang-hat: foo bang-star: foo bar baz
bang-dollar: baz bang-hat: foo bang-star: foo bar baz
Questo è utile quando, per esempio ls filea fileb
, e desideri modificarne uno: vi !$
o entrambi: vimdiff !*
.Può anche essere generalizzato a "the n
l'argomento" in questo modo:
$ echo foo bar baz
$ echo !:2
echo bar
bar
Infine, con i nomi di percorso, puoi ottenere parti del percorso aggiungendo :h
E :t
a uno qualsiasi degli espansori di cui sopra:
$ ls /usr/bin/id
/usr/bin/id
$ echo Head: !$:h Tail: !$:t
echo Head: /usr/bin Tail: id
Head: /usr/bin Tail: id
Come elencare soltanto sottodirectory in quella corrente?
ls -d */
È un trucco semplice, ma non sapresti quanto tempo mi ci è voluto per trovarlo!
ESC.
Inserisce gli ultimi argomenti del tuo ultimo comando bash.È utile più di quanto pensi.
cp file /to/some/long/path
CD ESC.
Certo che puoi "diff file1.txt file2.txt
", ma Bash supporta sostituzione del processo, che ti consente di farlo diff
l'output dei comandi.
Ad esempio, diciamo che voglio assicurarmi che il mio script mi fornisca l'output che mi aspetto.Posso semplicemente racchiudere il mio script in <( ) e inserirlo in diff
per ottenere un test unitario rapido e sporco:
$ cat myscript.sh
#!/bin/sh
echo -e "one\nthree"
$
$ ./myscript.sh
one
three
$
$ cat expected_output.txt
one
two
three
$
$ diff <(./myscript.sh) expected_output.txt
1a2
> two
$
Come altro esempio, diciamo che voglio verificare se due server hanno lo stesso elenco di RPM installati.Invece di inviare sshing a ciascun server, scrivere ogni elenco di RPM in file separati e fare a diff
su quei file, posso semplicemente fare il diff
dalla mia postazione di lavoro:
$ diff <(ssh server1 'rpm -qa | sort') <(ssh server2 'rpm -qa | sort')
241c240
< kernel-2.6.18-92.1.6.el5
---
> kernel-2.6.18-92.el5
317d315
< libsmi-0.4.5-2.el5
727,728d724
< wireshark-0.99.7-1.el5
< wireshark-gnome-0.99.7-1.el5
$
Ci sono altri esempi nella guida avanzata di sceneggiatura Bash http://tldp.org/LDP/abs/html/process-sub.html.
Il mio comando preferito è "ls -thor"
Convoca il potere degli dei per elencare i file modificati più di recente in un formato facilmente leggibile.
È più una novità, ma è intelligente...
Primi 10 comandi utilizzati:
$ history | awk '{print $2}' | awk 'BEGIN {FS="|"}{print $1}' | sort | uniq -c | sort -nr | head
Output di esempio:
242 git
83 rake
43 cd
33 ss
24 ls
15 rsg
11 cap
10 dig
9 ping
3 vi
^R ricerca inversa.Premi ^R, digita un frammento di un comando precedente che desideri abbinare e premi ^R finché non trovi quello che desideri.Quindi non devo ricordare i comandi utilizzati di recente che sono ancora nella mia cronologia.Non esclusivamente bash, ma anche:^E per fine riga, ^A per inizio riga, ^U e ^K per cancellare rispettivamente prima e dopo il cursore.
Spesso ho alias per vi, ls, ecc.ma a volte vuoi sfuggire all'alias.Basta aggiungere una barra rovesciata al comando davanti:
Per esempio:
$ alias vi=vim
$ # To escape the alias for vi:
$ \vi # This doesn't open VIM
Fantastico, non è vero?
Ecco un paio di modifiche alla configurazione:
~/.inputrc
:
"\C-[[A": history-search-backward
"\C-[[B": history-search-forward
Funziona allo stesso modo di ^R
ma usando invece i tasti freccia.Ciò significa che posso digitare (ad es.) cd /media/
quindi premi la freccia su per passare all'ultima cosa I cd
'd all'interno del /media/
cartella.
(Io uso Gnome Terminal, potrebbe essere necessario modificare i codici di escape per altri emulatori di terminale.)
Anche il completamento di Bash è incredibilmente utile, ma è un'aggiunta molto più sottile.In ~/.bashrc
:
if [ -f /etc/bash_completion ]; then
. /etc/bash_completion
fi
Ciò consentirà il completamento della scheda per programma (ad es.tentativo di completamento con tab quando la riga di comando inizia con evince
mostrerà solo i file che Evince può aprire e completerà anche le opzioni della riga di comando tramite scheda).
Funziona bene anche con questo in ~/.inputrc
:
set completion-ignore-case on
set show-all-if-ambiguous on
set show-all-if-unmodified on
Io uso molto quanto segue:
IL :p
modificatore per stampare un risultato della cronologia.Per esempio.
!!:p
Stamperà l'ultimo comando in modo da poter verificare che sia corretto prima di eseguirlo nuovamente.Basta entrare !!
per eseguirlo.
Allo stesso modo:
!?foo?:p
Cercherà nella cronologia il comando più recente che conteneva la stringa "foo" e lo stamperà.
Se non hai bisogno di stampare,
!?foo
fa la ricerca e la esegue subito.
Ho un'arma segreta: shell-fu.
Esistono migliaia di consigli intelligenti, trucchi interessanti e ricette efficaci che la maggior parte delle volte rientrano in un'unica riga.
Uno che adoro (ma imbroglio un po' dato che sfrutto il fatto che Python è installato sulla maggior parte dei sistemi Unix ora):
alias webshare='python -m SimpleHTTPServer'
Ora ogni volta che digiti "webshare", la directory corrente sarà disponibile tramite la porta 8000.Davvero utile quando vuoi condividere file con gli amici su una rete locale senza chiave USB o directory remota.Funzionerà anche lo streaming di video e musica.
E ovviamente la classica bomba a forcella, completamente inutile ma comunque molto divertente:
$ :(){ :|:& };:
Non provarlo in un server di produzione ...
È possibile utilizzare il comando watch insieme a un altro comando per cercare le modifiche.Un esempio di ciò è stato quando stavo testando il mio router e volevo ottenere numeri aggiornati su cose come il rapporto segnale-rumore, ecc.
watch --interval=10 lynx -dump http://dslrouter/stats.html
type -a PROG
Per trovare tutti i luoghi in cui è disponibile Prog, di solito da qualche parte in ~/bin piuttosto che quello in/usr/bin/prog che ci si sarebbe aspettato.
Mi piace costruire comandi con eco e collegarli alla shell:
$ find dir -name \*~ | xargs echo rm
...
$ find dir -name \*~ | xargs echo rm | ksh -s
Perché?Perché mi permette di vedere cosa verrà fatto prima di farlo.In questo modo, se si verifica un errore terribile (come rimuovere la mia directory home), posso rilevarlo prima che accada.Ovviamente, questo è molto importante per le azioni distruttive o irrevocabili.
Quando scarico un file di grandi dimensioni, molto spesso faccio:
while ls -la <filename>; do sleep 5; done
E poi basta ctrl+c quando ho finito (o if ls
restituisce un valore diverso da zero).È simile a watch
programma ma utilizza invece la shell, quindi funziona su piattaforme senza watch
.
Un altro strumento utile è netcat, o nc
.Se fate:
nc -l -p 9100 > printjob.prn
Quindi puoi configurare una stampante su un altro computer ma utilizzare invece l'indirizzo IP del computer che esegue netcat.Quando il lavoro di stampa viene inviato, viene ricevuto dal computer che esegue netcat e vi viene scaricato printjob.prn
.
pushd
E popd
torna quasi sempre utile
Un modo preferito di navigare quando utilizzo più directory in posizioni ampiamente separate in una gerarchia ad albero è utilizzare acf_func.sh (elencato di seguito).Una volta definito, puoi farlo
CD --
per vedere un elenco delle directory recenti, con un menu numerico
cd-2
per andare alla seconda directory più recente.
Molto facile da usare, molto pratico.
Ecco il codice:
# do ". acd_func.sh"
# acd_func 1.0.5, 10-nov-2004
# petar marinov, http:/geocities.com/h2428, this is public domain
cd_func ()
{
local x2 the_new_dir adir index
local -i cnt
if [[ $1 == "--" ]]; then
dirs -v
return 0
fi
the_new_dir=$1
[[ -z $1 ]] && the_new_dir=$HOME
if [[ ${the_new_dir:0:1} == '-' ]]; then
#
# Extract dir N from dirs
index=${the_new_dir:1}
[[ -z $index ]] && index=1
adir=$(dirs +$index)
[[ -z $adir ]] && return 1
the_new_dir=$adir
fi
#
# '~' has to be substituted by ${HOME}
[[ ${the_new_dir:0:1} == '~' ]] && the_new_dir="${HOME}${the_new_dir:1}"
#
# Now change to the new dir and add to the top of the stack
pushd "${the_new_dir}" > /dev/null
[[ $? -ne 0 ]] && return 1
the_new_dir=$(pwd)
#
# Trim down everything beyond 11th entry
popd -n +11 2>/dev/null 1>/dev/null
#
# Remove any other occurence of this dir, skipping the top of the stack
for ((cnt=1; cnt <= 10; cnt++)); do
x2=$(dirs +${cnt} 2>/dev/null)
[[ $? -ne 0 ]] && return 0
[[ ${x2:0:1} == '~' ]] && x2="${HOME}${x2:1}"
if [[ "${x2}" == "${the_new_dir}" ]]; then
popd -n +$cnt 2>/dev/null 1>/dev/null
cnt=cnt-1
fi
done
return 0
}
alias cd=cd_func
if [[ $BASH_VERSION > "2.05a" ]]; then
# ctrl+w shows the menu
bind -x "\"\C-w\":cd_func -- ;"
fi
Espandi linee complicate prima di premere il temuto invio
- Alt+Ctrl+e — linea di espansione della shell (potrebbe essere necessario utilizzare Esc, Ctrl+e sulla tastiera)
- Ctrl+_ — disfare
- Ctrl+X, * — glob-espandi-parola
$ echo !$ !-2^ *
Alt+Ctrl+e
$ echo aword someotherword *
Ctrl+_
$ echo !$ !-2^ *
Ctrl+X, *
$ echo !$ !-2^ LOG Makefile bar.c foo.h
&C.
Ho sempre avuto un debole per:
ctrl-E # move cursor to end of line
ctrl-A # move cursor to beginning of line
anch'io uso shopt -s cdable_vars
, quindi puoi creare variabili bash nelle directory comuni.Quindi, per l'albero dei sorgenti della mia azienda, creo una serie di variabili come:
export Dcentmain="/var/localdata/p4ws/centaur/main/apps/core"
quindi posso passare a quella directory tramite cd Dcentmain
.
pbcopy
Questo copia negli appunti del sistema Mac.Puoi reindirizzare i comandi ad esso ... prova:
pwd | pbcopy
$ touch {1,2}.txt
$ ls [12].txt
1.txt 2.txt
$ rm !:1
rm [12].txt
$ history | tail -10
...
10007 touch {1,2}.txt
...
$ !10007
touch {1,2}.txt
$ for f in *.txt; do mv $f ${f/txt/doc}; done
Utilizzando 'set -o vi' dalla riga di comando, o meglio, in .bashrc, ti mette in modalità di modifica vi sulla riga di comando.Inizi in modalità 'inserisci' in modo da poter digitare e tornare indietro normalmente, ma se commetti un errore 'grosso' puoi premere il tasto esc e quindi usare 'b' e 'f' per spostarti come fai in vi.cw per cambiare una parola.Particolarmente utile dopo aver richiamato un comando della cronologia che desideri modificare.
Simile a molti sopra, il mio preferito attuale è la sequenza di tasti [alt].(Tasti Alt e "." insieme) equivale a $!(Inserisce l'ultimo argomento del comando precedente) tranne che è immediato e per me più semplice da digitare.(Non può essere utilizzato negli script)
per esempio:
mkdir -p /tmp/test/blah/oops/something
cd [alt].
Stringa più comandi insieme utilizzando il file && comando:
./run.sh && tail -f log.txt
O
kill -9 1111 && ./start.sh