Quelle est votre astuce la plus préférée en ligne de commande avec Bash? [fermé]
-
09-06-2019 - |
Question
Nous savons tous comment utiliser <ctrl>-R
pour inverser la recherche dans l'historique, mais saviez-vous que vous pouvez utiliser <ctrl>-S
pour transférer la recherche si vous définissez stty stop ""
? En outre, avez-vous déjà essayé d'exécuter bind -p pour voir tous vos raccourcis clavier répertoriés? Il y a plus de 455 sur Mac OS X par défaut.
Quelle est votre astuce obscure, raccourci clavier ou configuration shopt préféré avec bash?
La solution 7
Lors de l'exécution de commandes, je souhaite parfois exécuter une commande avec les arguments précédents. Pour ce faire, vous pouvez utiliser ce raccourci:
$ mkdir /tmp/new
$ cd !!:*
À l'occasion, au lieu d'utiliser find, je diviserai une boucle d'une ligne si j'ai besoin d'exécuter plusieurs commandes sur une liste de fichiers.
for file in *.wav; do lame "$file" "$(basename "$file" .wav).mp3" ; done;
La configuration des options d’historique de ligne de commande dans mon fichier .bash_login (ou .bashrc) est vraiment utile. Vous trouverez ci-dessous un ensemble de paramètres que j'utilise sur mon Macbook Pro.
Définissez les options suivantes pour que bash efface les commandes en double de votre historique:
export HISTCONTROL="erasedups:ignoreboth"
J’ai aussi une taille d’historique assez élevée. Pourquoi pas? Il ne semble rien ralentir sur les microprocesseurs actuels.
export HISTFILESIZE=500000
export HISTSIZE=100000
Une autre chose que je fais est d’ignorer certaines commandes de mon historique. Pas besoin de se souvenir de la commande de sortie.
export HISTIGNORE="&:[ ]*:exit"
Vous voulez vraiment définir histappend. Sinon, bash écrase votre historique lorsque vous quittez.
shopt -s histappend
Une autre option que j’utilise est cmdhist. Cela vous permet d’enregistrer des commandes multilignes dans l’historique en une seule commande.
shopt -s cmdhist
Enfin, sous Mac OS X (si vous n’utilisez pas le mode vi), vous voudrez réinitialiser < CTRL > -S pour qu’il ne soit plus possible de faire défiler le défilement. Cela empêche bash de pouvoir l'interpréter en tant que recherche avancée.
stty stop ""
Autres conseils
Renommer / déplacer rapidement des fichiers avec des suffixes:
cp /home/foo/realllylongname.cpp{,-old}
Cela s'étend à:
cp /home/foo/realllylongname.cpp /home/foo/realllylongname.cpp-old
cd -
C'est l'équivalent en ligne de commande du bouton Précédent (vous amène au répertoire précédent dans lequel vous étiez).
Un autre favori:
!!
Répète votre dernière commande. Plus utile sous la forme:
sudo !!
Mon favori est '^ string ^ chaine2' qui prend la dernière commande, remplace chaine par chaine2 et l'exécute
$ ehco foo bar baz
bash: ehco: command not found
$ ^ehco^echo
foo bar baz
renommer
Exemple:
$ 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
Tellement utile
Je suis fan des développements !$
, !^
et !*
, en renvoyant, à partir de la dernière ligne de commande soumise: le dernier élément, le premier élément non commandé et tous les éléments non commandés. À savoir (notez que le shell imprime d'abord la commande):
$ 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
Cela est pratique lorsque vous dites ls filea fileb
et souhaitez modifier l’un d’eux: vi !$
ou les deux: vimdiff !*
. Il peut également être généralisé à & "Le n
ème argument &"; comme si:
$ echo foo bar baz
$ echo !:2
echo bar
bar
Enfin, avec les chemins d'accès, vous pouvez accéder à certaines parties du chemin en ajoutant :h
et :t
à l'un des développements précédents:
$ ls /usr/bin/id
/usr/bin/id
$ echo Head: !$:h Tail: !$:t
echo Head: /usr/bin Tail: id
Head: /usr/bin Tail: id
Comment lister seulement les sous-répertoires du répertoire actuel?
ls -d */
C'est un truc simple, mais vous ne savez pas combien de temps il me fallait pour le trouver!
ESC .
Insère les derniers arguments de votre dernière commande bash. Il est plus pratique que vous ne le pensez.
cp file /to/some/long/path
cd ESC .
Bien sûr, vous pouvez " diff file1.txt file2.txt
" ;, mais Bash prend en charge traiter la substitution , ce qui vous permet de diff
la sortie des commandes.
Par exemple, disons que je veux m'assurer que mon script me donne le résultat attendu. Je peux simplement envelopper mon script dans & Lt; () et le transmettre à <=> pour obtenir un test unitaire rapide et sale:
$ 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
$
Comme autre exemple, supposons que je veuille vérifier si deux serveurs ont la même liste de RPM installés. Plutôt que d'envoyer un message à chaque serveur, d'écrire chaque liste de RPM dans des fichiers séparés et de faire un <=> traitement sur ces fichiers, je peux simplement effectuer la <=> depuis mon poste de travail:
$ 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
$
Il y a plus d'exemples dans le Guide avancé de script Bash à l'adresse http://tldp.org/LDP/abs/ html / process-sub.html .
Ma commande préférée est & "; ls -thor &";
.Il convoque le pouvoir des dieux pour répertorier les fichiers les plus récemment modifiés de manière pratique. format lisible.
Plus d'une nouveauté, mais c'est malin ...
Les 10 commandes les plus utilisées:
$ history | awk '{print $2}' | awk 'BEGIN {FS="|"}{print $1}' | sort | uniq -c | sort -nr | head
Exemple de sortie:
242 git
83 rake
43 cd
33 ss
24 ls
15 rsg
11 cap
10 dig
9 ping
3 vi
^ R recherche inversée. Appuyez sur ^ R, tapez un fragment d'une commande précédente que vous souhaitez faire correspondre et appuyez sur ^ R jusqu'à ce que vous trouviez celle que vous voulez. Ensuite, je n'ai pas à me souvenir des commandes récemment utilisées qui sont encore dans mon historique. Pas exclusivement bash, mais aussi: ^ E pour la fin de la ligne, ^ A pour le début de la ligne, ^ U et ^ K à supprimer avant et après le curseur, respectivement.
J'ai souvent des alias pour vi, ls, etc., mais parfois, vous voulez échapper à cet alias. Ajoutez simplement une barre oblique inverse à la commande qui se trouve devant:
Par exemple:
$ alias vi=vim
$ # To escape the alias for vi:
$ \vi # This doesn't open VIM
Cool, n'est-ce pas?
Voici quelques modifications de configuration:
~/.inputrc
:
"\C-[[A": history-search-backward
"\C-[[B": history-search-forward
Cela fonctionne de la même manière que ^R
mais en utilisant les touches de direction. Cela signifie que je peux taper (par exemple) cd /media/
puis appuyer sur la flèche vers le haut pour aller à la dernière chose que je cd
vais dans le dossier /media/
.
(J'utilise Gnome Terminal, vous devrez peut-être modifier les codes d'échappement des autres émulateurs de terminal.)
La complétion de Bash est également incroyablement utile, mais c’est un ajout beaucoup plus subtil. Dans ~/.bashrc
:
if [ -f /etc/bash_completion ]; then
. /etc/bash_completion
fi
Ceci activera la complétion par onglet par programme (par exemple, tenter de compléter une tabulation lorsque la ligne de commande commence par evince
ne montrera que les fichiers que evince peut ouvrir et des options de ligne de commande complétant par une tabulation également.]
Fonctionne bien avec cela aussi dans <=>:
set completion-ignore-case on
set show-all-if-ambiguous on
set show-all-if-unmodified on
J'utilise beaucoup les éléments suivants:
Le modificateur :p
pour imprimer un résultat de l'historique. Ex.
!!:p
Imprimera la dernière commande afin que vous puissiez vérifier qu'elle est correcte avant de la réexécuter. Il suffit d'entrer !!
pour l'exécuter.
Dans le même esprit:
!?foo?:p
va rechercher dans votre historique la commande la plus récente contenant la chaîne 'foo' et l'imprimer.
Si vous n'avez pas besoin d'imprimer,
!?foo
effectue la recherche et l'exécute immédiatement.
J'ai une arme secrète: shell-fu.
Il existe des milliers d’astuces astucieuses, d’astuces originales et de recettes efficaces que la plupart du temps ne tiennent que sur une seule ligne.
Celui que j'aime beaucoup (mais je triche un peu puisque j'utilise le fait que Python est maintenant installé sur la plupart des systèmes Unix):
alias webshare='python -m SimpleHTTPServer'
Maintenant, chaque fois que vous tapez & "; Webshare &" ;, le répertoire actuel sera disponible via le port 8000. Vraiment agréable de partager des fichiers avec des amis sur un réseau local sans clé USB ni répertoire distant. . La vidéo et la musique en streaming fonctionneront également.
Et bien sûr, la classique bombe à fourche qui est complètement inutile mais qui reste très amusante:
$ :(){ :|:& };:
N'essayez pas cela sur un serveur de production ...
Vous pouvez utiliser la commande watch conjointement avec une autre commande pour rechercher des modifications. Par exemple, lorsque je testais mon routeur, je souhaitais obtenir des chiffres à jour sur des éléments tels que le rapport signal / bruit, etc.
watch --interval=10 lynx -dump http://dslrouter/stats.html
type -a PROG
afin de trouver tous les endroits où PROG est disponible, généralement quelque part dans ~ / bin plutôt que celui de / usr / bin / PROG auquel on aurait pu s'attendre.
J'aime construire des commandes avec echo et les diriger vers le shell:
$ find dir -name \*~ | xargs echo rm
...
$ find dir -name \*~ | xargs echo rm | ksh -s
Pourquoi? Parce que cela me permet de regarder ce qui va être fait avant de le faire. Ainsi, si j’ai une horrible erreur (comme supprimer mon répertoire personnel), je peux l’attraper avant que cela ne se produise. De toute évidence, ceci est particulièrement important pour les actions destructives ou irrévocables.
Lorsque vous téléchargez un fichier volumineux, je fais souvent:
while ls -la <filename>; do sleep 5; done
Et puis juste ctrl + c quand j'ai fini (ou si ls
retourne différent de zéro). Son fonctionnement est similaire au programme watch
, mais il utilise le shell à la place. Il fonctionne donc sur les plates-formes sans nc
.
Un autre outil utile est netcat ou printjob.prn
. Si vous le faites:
nc -l -p 9100 > printjob.prn
Ensuite, vous pouvez configurer une imprimante sur un autre ordinateur mais utiliser plutôt l'adresse IP de l'ordinateur exécutant Netcat. Lorsque le travail d'impression est envoyé, il est reçu par l'ordinateur exécutant netcat et transféré dans <=>.
. pushd
et popd
sont presque toujours utiles
L’utilisation de acf_func.sh (répertorié ci-dessous) constitue un moyen privilégié de navigation lorsque j’utilise plusieurs répertoires à des emplacements très séparés dans une arborescence. Une fois défini, vous pouvez faire
cd -
pour voir une liste des répertoires récents, avec un menu numérique
cd -2
pour aller au deuxième répertoire le plus récent.
Très facile à utiliser, très pratique.
Voici le code:
# 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
Développez les lignes compliquées avant d'appuyer sur l'entrée redoutée
- Alt + Ctrl + e & # 8212; shell-expand-line (vous devrez peut-être utiliser Échap , Ctrl + e sur votre clavier)
- Ctrl + _ & # 8212; annuler
- Ctrl + x , * & # 8212; glob-expand-word
$ echo !$ !-2^ *
Alt + Ctrl + e
$ echo aword someotherword *
Ctrl + _
$ echo !$ !-2^ LOG Makefile bar.c foo.h
Ctrl + x , *
$ <=>
& amp; c.
J'ai toujours été partial envers:
ctrl-E # move cursor to end of line
ctrl-A # move cursor to beginning of line
J'utilise aussi shopt -s cdable_vars
, vous pouvez alors créer des variables bash dans des répertoires communs. Donc, pour l’arbre source de mon entreprise, je crée un tas de variables telles que:
export Dcentmain="/var/localdata/p4ws/centaur/main/apps/core"
alors je peux changer de répertoire par cd Dcentmain
.
pbcopy
Ceci copie dans le presse-papier du système Mac. Vous pouvez y diriger les commandes ... essayez:
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
Utiliser 'set -o vi' depuis la ligne de commande, ou mieux, en .bashrc, vous place en mode d'édition vi sur la ligne de commande. Vous commencez en mode "insertion" afin de pouvoir taper et faire un retour arrière comme d'habitude, mais si vous faites une "grosse" erreur, vous pouvez appuyer sur la touche Échap puis utiliser "b" et "f" pour vous déplacer comme vous le faites dans vi. cw pour changer un mot. Particulièrement utile lorsque vous avez lancé une commande d'historique que vous souhaitez modifier.
Semblable à beaucoup d'autres ci-dessus, mon favori actuel est la frappe [alt]. (Alt et & Quot;. & Quot; touches ensemble) c'est la même chose que $! (Insère le dernier argument de la commande précédente) sauf que c'est immédiat et pour moi plus facile à taper. (Ne peut tout simplement pas être utilisé dans les scripts)
par exemple:
mkdir -p /tmp/test/blah/oops/something
cd [alt].
Chaîne plusieurs commandes en utilisant la & amp; & amp; commande:
../run.sh && tail -f log.txt
ou
kill -9 1111 && ./start.sh