Outils pour utilisateurs

Outils du site


doc:guides:bash

Bash et commandes basiques

Voici un petit nombre de commandes unix qui couvriront 90% de vos besoins à long terme! Pas besoin d'en connaitre toutes les variantes, surtout pas. Il est souvent bien assez efficace de combiner deux commandes simples plutôt que de recherche une option qui permettrait de le faire en une commande. De toute façon s'il s'agit d'optimiser réellement, le shell n'est pas souvent la meilleure option… La productivité passe généralement en priorité!

La majorité des commandes comprend l'argument --help pour afficher un résumé moins verbeux que man commande. Pour rechercher une commande on peut utiliser man -k motclé (k=keyword), ou … google, ou https://die.net

Voyez enfin explain shell pour un déchiffrage d'une commande bash composée, bien utile pour apprendre.

Langage bash

Commande Usage
# Commentaire (sauf si entouré de guillemets etc)
cmd & Commande lancée en tache de fond, voir bg, fg ci-dessous
; Séparateur d'instruction, à défaut d'un retour à la ligne
cmd1 | cmd2 Enchainer le stdout (et non pas stderr!) de la commande de gauche dans le stdin de celle de droite. Utilisez cmd1 2>&1 | grep elt pour filter stdout et stderr.
&&, || Enchainer les commandes cmd && echo ok ("et": si cmd réussit), ou bien cmd || echo failed ("ou": si cmd échoue)
cmd > fichier Rediriger la sortie "stdout". Utiliser 2> pour rediriger la sortie d'erreur. Spécial: &> (stdout+stderr) ou 2>&1 (stderr dans stdout). Et donc cmd &> /dev/null pour rendre une commande totalement silencieuse, même en cas d'erreur
cmd < fichier Envoyer le contenu du fichier dans l'entrée de la commande. Souvent équivalent optimisé de cat fichier | cmd
$var Plus sûrement écrit "$var" (qui, lui, respecte les espaces): remplacé par le contenu de la variable. Pour un texte littéral écrire '$var' (bash n'interprête plus rien). Spécifier ${var} si ambigü: echo "${HOME}aa".
$HOME Dossier 'home" de l'utilisateur en cours (aussi noté ~)
$PATH Chemins des exécutables séparés par :. Ajoutez les votres à la fin, pas au début, et jamais . Ex. export $PATH="$PATH:$HOME/bin"
$( cmd ) Remplacé par le résultat de la commande: echo "I am $(whoami)". Anciennement écrit `cmd` (backquotes)
for f in a b c; dodone Répéter avec f="a" puis f="b"… Ex. for f in *.bak; do echo "Depl $f"; mv $f /tmp; done
if tst1 ; then cmd1 ; elif tst2 ; then cmd2 else cmd3 ; fi Si tst1 (une commande) est évaluée positivement, executer cmd1 sinon si tst2 est positif, excéuter cmd2 sinon exécuter cmd3. Exemple: if grep erreur /var/log/fichier.log; then exit; fi. Voyez aussi caseesac qui a ses avantages.
while cmd; dodone Boucler si cmd est vraie
$? Le code d'erreur retournée par la dernière commande (0=positif, autres=erreur): rm fic; [ "$?" != 0 ] && echo Echec
$# Le PID du script en cours

:!: Voyez ci-après les "conditions" en bash, notamment l'utilisation de [[ … ]].

Fichiers et dossiers

Commande Usage
echo Affiche un texte (echo "Bonjour"). Pour les adeptes du C, on peut aussi utiliser printf "Cou%s\n" "cou".
mv Déplacer un fichier
cp Copier un fichier, souvent avec -a pour conserver les droits et propriétés
cd Changer de dossier actuel (utilisez cd - pour basculer entre deux dossiers)
pwd Print working directory: le dossier courant. Mieux: export PS1='\u@\h:\w #'
ls ls -AlF très utile, à mettre en alias
tree A installer (apt install tree), affiche une arborescence en texte
mkdir Créer un dossier, récursivement avec mkdir -p /tmp/sub1/sub2/sub3/dir
dirname, basename extraire le chemin ou le dernier élément d'un fichier. [ $(basename $HOME) = $(whoami) ] && echo "Vous êtes à la racine de votre dossier personnel"
tar Compresser tar cvzf archive.tgz fichiers et décompresser avec xvfz (create/extract)
rsync -a Copier seulement les différences (bien plus efficace que scp): rsync -a --delete --dry-run … pour tester sans risque, --info=progress2 pour voir la progression
find -exec Cherche: find /var/log -type f -name '*.gz' -mtime +31 -exec rm {} ';'
which Donne le chemin vers un exécutable
locate Trouve un fichier dans le système
ln -s Lien symbolique (fichier ou dossier: ln -s source destination). Toujours avec -s!
touch Mettre a jour la date d'un fichier, ou le créer vide
inotifywait Déclencher une action lors d'un changement dans un dossier

Contenus et traitements

Commande Usage
echo Afficher une chaine de caractères, utiliser les doubles quotes pour étendre les variables, de simples quotes pour du littéral, et des accolades pour "protéger" le nom de variables: echo "${HOME}is my" sweet '$HOME'
less Utiliser /motclé pour rechercher puis n ou shift+n pour naviguer. Et 90g pour aller à une ligne donnée. q pour quitter less.
tail -F Affiche en continu la fin d'un fichier, même s'il est recrée
grep -i Rechercher du text (cf --color bien pratique, egrep pour des regex avancées, fgrep pour du texte pur). grep -v pour inverser le filtre.
tee -a dupliquer stdout dans un fichier
diff diff -y affiche les différences entre deux fichiers cote à coté
cat -n Afficher un contenu. Ou simplement cat > nouveaufichier.txt, coller/saisir son texte, puis control-d pour terminer. Une façon très efficace de créer ou ajouter à un fichier.
cut En caractères (cut -c1-8) ou en field avec délimiteur (cut -d: -f1,3-4)
tr "translitterate": tr / _ pour remplacer une lettre, ou tr -d ':' pour l'enlever
sed "Traitement de texte mode unix": sed -i s@rech@rempl@g fichier (s=subsitute, g=global), ps|sed -n '/bash/s|\s*\(.*\) pts/[0-9: ]*\(.*\)|\2: \1|p'
awk Langage bien plus clair que sed pour les traitements un peu complexes ou pour de vrais calculs numériques. df -BG -l -t ext4| awk '{sum += $4} END {print sum "GB free"}'
sort Tri, ordonnancement (un peu piégeux), utile aussi avec uniq

Divers et bash

Commande Usage
!cmd Ré-exécuter la dernière commande qui commençait par "cmd"
history Voir l'historique, souvent avec history | grep macommande
control k Effacer la ligne à droite du curseur
alias Ex. alias syslog="tail -F /var/log/syslog" ou alias hgrep='history|grep' , alias ..='cd ..' très utiles à ajouter dans son $HOME/.bashrc
bash -eux monscript.sh Lancer un script en mode verbeux (x) et arrêt sur la première erreur (e) ou variable non déclarée (u). Mieux: commencez votre script avec #!/bin/bash -feux -o pipefail
vi Utilisez vipw, vigr, visudo pour les fichiers respectifs (passwd, groups, sudoers). Commandes <esc> puis u=undo, cw change word, d$ delete to end of line, J=join… Utilisez <esc> suivi de :q! pour sortir (quit) sans sauvegarder vos modifications. Voyez ci-après le paragraphe dédié.
printf Permet un formatage à la C, souvent bien pratique et plus clair: printf "% -20s: %.2f\n" Element 123.456
xargs Ex: ls|grep -v zip|xargs rm supprimme tous les fichiers locaux, sauf les zip. Et ls *.txt | xargs -I@ mv @ @.bak est mieux et moins verbeux que ls *.txt | while read f; do mv $f $f.bak; done.

Gestion de process

Commande Usage
fg, bg et jobs Apres un control-z (process suspendu), bg pour le passer en background, jobs pour lister les processes, fg pour repasser en foreground. control-c pour le tuer.
ps Monter les process en cours, ex avec un ps aux | grep macommande
kill Tuer un process par son PID (ou le job 2 avec kill %2)
pkill Tuer un process via son nom pkill bash (oups)
nohup No hang up: nohup commande &> log.txt & ne sera pas tuée par la fin de session

Réseau et observation

Commande Usage
ssh Se logguer à distance
ssh-add Laisse son "agent" se souvenir d'une passphrase protégeant une clé, pour ne pas avoir à la saisir à chaque fois
curl Faire du GET ou du POST vers une adresse web
netstat netstat -tanp affiche les service IP en cours, ou plus moderne: ss -ltp
iperf3 Client et serveur: calculer une bande passante
ping Voir si un serveur ou une adresse IP répond (sans garantie parfaite car il peut refuser). Si nc existe, c'est plus efficace de faire un nc -zw $tmout $srv $port
tracepath Equivalent au vieux traceroute, vers un serveur tracepath -4b free.fr
df -hl "Disk free" en mode long et "h"umain
du -sh * Occupation disque des éléments du dossier en cours
NMON=mcdn nmon moniteur de ressources, configuré pour memory, cpu, disks, network. Remplace htop, iftop, iotop … On peut utilement placer le export NMON=mcdn dans son .bashrc.

Utilisateurs et droits

Commande Usage
sudo Exécuter une commande en tant que root (voir visudo ou le groupe sudoers)
su En étant root, pour devenir un utilisateur (su - normaluser). Cf. aussi runuser -u username commande
adduser ou le minimaliste useradd ref.
chmod Changer des droits: chmod -R go-w mondossier ou chmod u+x monexec
chown Nouveau propriétaire chown jeremie ~/.ssh/*
chgrp Nouveau groupe chgrp adm fichiersensible (cf. aussi combiné sudo chown -R www-data:www-data /var/www)

Admin / système

Commande Usage
apt install pour installer, ou update, upgrade, dist-upgrade pour mettre à jour le système
service status|stop|start|restart gère les "daemons": service apache2 restart
mount (bas niveau) Monter un device sur un dossier (point de montage): mount /dev/sdd1 /tmp/cléusb. Démonter avec unmount. Cf. aussi blkid et lsblk. Notez le pratique tmpfs /volatile tmpfs nodev,nosuid,noexec,nodiratime,size=512M 0 0 dans /etc/fstab pour se faire un "ramdisk" rapide et volatile, monté avec mount /volatile une fois le dossié crée.
sshfs Monte un dossier distant localement: sshfs root@srv.com:/etc /tmp/remote_etc
mysql mysql -u root --database DB ouvre un shell SQL
ip Configuration du réseau: ip a ou ip route

Parenthèses, crochets et accolades

  • ( … ): permet d'enchainer des commandes à l'intérieur d'un sous-shell, dans un process séparé: les assigations de variables et redirections faites à l'intérieur n'impacteront pas l'extérieur! x=1; (x=2); echo $x retourne 1 et non pas 2!
  • { … } les crochets servent aussi à regrouper des commandes, mais cette fois ci dans le même process: ainsi x=1; {x=2}; echo $x donne cette fois-ci bien 2. C'est peu utilisé en pratique.
  • $( … ) est une substitution de commande. La sortie stdout des commandes exécutées à l'intérieur des parenthèses se substitue à l'expression: echo "Aujourd'hui nous sommes le $(date)"
  • $(( … )) retourne la valeur de l'expression arithmétique. Attentions, seuls les nombres entiers sont gérés par bash!
  • ${ … } permet d'étendre un paramètre: soit avec sa valeur, soit avec l'une des très nombreuses opérations possibles de bash en la matière. Citons par exemple
    • ${a-ABC} qui retourne la valeur de la variable a si elle est définie et ABC sinon (valeur par défaut)
    • ${a: -4} qui retourne les 4 derniers caractères de la variable $a
    • {a#prefix} ou {a%suffix} pour éliminer un début ou une fin de chaîne de caractères…
  • [[ … ]] explicitent les conditions:
    • avec un préfixe, par exemple
      • [[ -n $a ]] pour tester l'existence de la variable
      • [[ -f /etc/file.conf ]] pour celle d'un fichier
    • avec un triplet:
      • [[ "$s1" == "abcd" ]] compare des chaines de caractères, mais attention car une partie droite sans guillemet forme un pattern:
        • [[ $var == "ab*" ]] teste l'égalité à la chaine exacte ab*
        • mais [[ $var == ab* ]] teste si la variable var commence par ab
    • on peut utiliser des parenthèses, ainsi que les classiques négation !, conjonction && et disjonction ||
    • :!: conservez bien un espace entre chacun des éléments de l'expression !
  • [ … ] est historiquement la façon d'encoder des conditions et qui reste davantage portable que les doubles crochets. En bash elle est obsolète, d'autant qu'elle présente davantage de pièges: à éviter. En fait /usr/bin/[ est une commande tout comme test ! A noter, fonctionellement, test -f fic est quasiment équivalent à [ -f fic ] et à [[ -f fic ]].

Exemple:

if [[ "${newfile: -4}" = ".jpg" ]] || [[ "${newfile: -5}" = ".jpeg" ]]
then
  [[ $(identify -format %m "$newfile") != 'JPEG' ]] &&
      echo "Le fichier $newfile est nommé en JPEG mais ne c'est pas un JPEG !"
  fi
fi

Eléments spécifiques à bash

Plus de commandes et gestion de l'historique sur cette page (Control-R: rechercher, ou !debutcmd:p pour confirmation…)

Un "heredoc" avec remplacement de variables, très pratique pour générer de grosses sections de configuration, ou pour gérer facilement des quotes hétérogènes sans devoir recourir à \" par exemple:

cat > fichier.cfg <<FIN
Mon fichier avec des "$variables"
interprétes par 'bash'
Et sans quotes, incroyable!
FIN

Déclarer une fonction (même syntaxe que sh)

monquit()
{
  echo "$(date): arguments: $1 $2"
  exit
}
monquit "Succès" "fichier ok"

Usage du IFS "internal field separator" et d'un "herestring" <<< pour extraire efficacement les deux valeurs 0000 et 0021 du nom du fichier (moins gore que deux sed?).

IFS='-.' read -r dummy1 x y dummy2 <<< "tileshp/contours-0000-0021.shp"

Autres commandes bash utiles:

  • trap (routine en cas d'erreur),
  • flock (zone critique à ne pas exécuter en même temps qu'un autre process ou soi-même plusieurs fois)…

Les éditeurs vi et vim

Certains préfèreront utiliser nano qui est plus intuitif mais vraiment plus limité que "vi". Ce dernier est dur à maintriser mais il est présent partout et il est en fait extrêmement puissant.

Voici donc quelques fonctions utiles dans vi (à saisir après la touche <esc>)

Générique

  • :q! quit (meme s'il y a des modifications)
  • :wq write and quit
  • * rechercher le mot lu sous le curseur
  • /rech pour rechercher, n pour next, N pour précédent (idem less)
  • 8G aller à la ligne 8 (idem less)

Edition

  • u undo (répétable)
  • i insert (I pour insérer en début de ligne)
  • a append (A pour ajouter en fin de ligne)
  • o nouvelle ligne au dessous (O pour une nouvelle ligne au dessus)
  • J pour joindre la ligne qui suit à celle sous le curseur
  • d? pour "delete", où ? en précise la portée:
    • dd pour la ligne
    • d$ jusqu'à la fin de ligne
    • d^ vers la gauche (tapez d^ )
    • dw (delete word, et 3dw supprime 3 mots, vous voyez la logique implacable?)…
  • r? pour "replace", avec la même logique que le d
  • c? pour "change" (delete+insert), suivi comme ci-dessus
    • cc change line (donc 5cc pour changer 5 lignes d'un coup)
    • c$ remplace toute la fin de ligne (idem que C)
    • c^ remplace tout le début de ligne
    • cw change word …
  • yy yank line (copie de la ligne courante), yw copie du "word" sous le curseur, etc …
  • p paste (coller le contenu du "y", à droite du curseur)
  • w beginning of next word, e end of next word

Avancé

  • control O et control I rejouer les positions successivement suivies
  • :%s/rech/rempl/gc pour remplacer avec demande (aaaarg)
  • :r!CMD ajouter le résultat de la commande CMD (ex. :r!date)
  • :%!cat -n numéroter toutes les lignes
  • :,$d détruire du curseur jusqu'à la fin du fichier

Couper-coller (vim et pas vi)

  • V initie la zone à copier/couper en surbrillance …
  • puis d pour la couper (delete), ou bien y pour la copier (yank)
  • enfin p la colle après le curseur (P pour avant le curseur)

Fichiers SSH et journaux importants

Variable ou fichier Intérêt
/var/log/syslog Journal système principal. Ex. tail -F /var/log/syslog pour le voir "en live"
/var/log/auth.log Journal des tentatives d'identifications
/etc/cron/cron.* Taches récurrentes
/var/log/nginx/access.log Journal par défaut du serveur web (si c'est nginx)
~/.ssh/authorized_keys Les clés publiques (une par ligne) qui permette d'accès au compte
~/.ssh/config Alias et raccourcis pour ses accès SSH (très pratique!)
/etc/ssh/sshd_config Configuration du serveur SSH

Outils annexes en ligne de commande

Il existe réellement des milliers d'outils, écrits dans toutes sortes de langages ou de scripts (exécutables/binaires, python, PHP…)

Certains sont très classiques, comme ceux mentionnés ci-avant (les cut, sed, grep …). D'autres le sont moins mais reste très utiles. On peut citer

  • jq pour exploiter du JSON (et jc pour convertir des sorties de commande unix en json)
  • mlr (miller) pour du CSV (ou la suite CSVkit, dont in2csv pour convertir du Excel)
  • datamash pour des calculs sur des tables (ex. calculer la médiane des colonnes d'un fichier CSV).
  • gnuplot pour créer des graphiques (non trivial!)
  • wesplot permet de tracer en live un résultat d'un pipe linux

Pour un usage orienté "data science", vous pouvez aussi consulter ce site, plutôt bien fait.

N'hésitez pas à recourir à Python non plus, qui fonctionne aussi en ligne de commande si besoin.

Il existe aussi des versions améliorées ou plus rapides d'outils, comme pour la recherche de fichiers ou de contenu avec fdfind ou ripgrep

Il ne s'agit bien sûr pas de les connaître tous mais bien de s'en approprier assez, pour qu'une fois combinés ils vous permettent de régler 99% de vos besoins. Vous croiserez bien sûr de nouvelles fonctions tout le temps, des "raccourcis" plus rapides ou plus pratiques, rien ne presse.

Veillez cependant à n'utiliser que des outils reconnus, car il est toujours risqué d'installer un exécutable qui provient d'une source peu connue ou non officielle (typiquement les fonctions qui ne sont pas disponibles via apt).

doc/guides/bash.txt · Dernière modification : 2023/11/30 19:53 de jeremie