Bash command line

De Banane Atomic
Aller à la navigationAller à la recherche

Manipulation de string

echo

Bash.svg
echo -n "sans retour à la ligne"
echo -e "interprétation du caractère d'échappement \r \n"
echo      # retour à la ligne

# affichage avec écrasement de tous les chiffres entre 0 et 100
# et garde affiché les multiples de 10
for i in {1..100..1}
do
    echo -ne "$i\r"
    sleep .2
    if (( $i % 10 == 0 )) ; then
	echo
    fi
done

printf

Bash.svg
# afficher var sous la forme d'un entier de 2 digits
echo $(printf "%02d" $var)

ripgrep

Bash.svg
# chercher une occurrence dans les fichiers d'un dossier
rg -C5 occurence /chemin
# -C5 affiche 5 lignes avant et après les correspondances
# -uu rechercher dans les fichiers et dossiers cachés (.*)
# -i/--ignore-case
# -g '*.txt' rechercher dans les fichiers correspondant au pattern
# -g '!*.txt' rechercher dans les fichiers ne correspondant pas au pattern

grep

Bash.svg
# rechercher les lignes qui commencent par #
... | grep ^#

# rechercher les lignes qui ne commencent par #
... | grep -v ^#

# rechercher les lignes qui se terminent par jpg
... | grep jpg$

# rechercher toutes les occurrences dans les fichiers d'un dossier
grep -rin occurence /chemin
# -r Read all files  under  each  directory,  recursively, following symbolic links only if they are on the command line.
# -R Read all files under each directory, recursively. Follow all symbolic links, unlike -r.
# -i case insensitive
# -n Prefix each line of output with the line number within its input file.
# -H Print the file name for each match.
# -C 5 affiche 5 lignes avant et après les correspondances
# --exclude-dir={.git,.svn,CVS}

# support des expressions rationnelles étendues POSIX :
# les opérateurs {}, (), +, | et ? n'ont plus besoin d'être échappés 
... | grep -E 'http://[a-zA-Z0-9._/]+\.jpg'
# retourne seulement l'expression rationnelle et non toute la ligne
... | grep -Eo 'http://[a-zA-Z0-9._/]+\.jpg'
# pour les assertions look-behind, utiliser Perl-compatible  regular  expression (PCRE) au lieu de extended regular expression (ERE)
grep -Po '(?<=Version )[[:digit:]]+.[[:digit:]]+'

# test la valeur de retour de grep
if ! mount | grep -q /media/xxx; then
    sshfs user@xxx:/home/user /media/xxx
fi
# -q: quiet, ne rien écrire sur stdout
# si une correspondance est trouvée, retourne 0 et valide le test
# si aucune correspondance n'est trouvée, retourne 1 et ne valide pas le test
egrepgrep -E Interpret PATTERNS as extended regular expressions
fgrepgrep -F Interpret PATTERNS as fixed strings, not regular expressions

cut

Découpe une chaîne de caractères

Bash.svg
# découpe suivant le caractère , et sélection de la seconde partie 
echo "123,456,789" | cut -d , -f2  # 456

# espace comme délimiteur
cut -d ' '

awk

Fonction de filtre.

Bash.svg
# Afficher la colonne 9 du résultat de la commande ls
ls -l | awk '{ print $9 }'

# Afficher les colonnes 6 jusqu'à la dernière du résultat de la commande ls
# en espaçant les colonnes par un espace.
ls -l | awk '{ for (i=6; i<NF; i++) printf "%s ", $i ; print $NF }'

# Passer une variable (premier argument $1) à awk
awk -v vawk="$1" '$0 ~ vawk ... '
# Exemple: recherche xxx dans les fichiers du dossier courant
find . -type f -exec awk -v vawk=xxx '$0 ~ vawk {c++} c>0 {print ARGV[1] ; exit 0 } END { if (! c) {exit 1}}' '{}' ';'

# BEGIN - END
who | awk 'BEGIN { printf "(" } { printf "%s", $1 } END { printf ")\n" }'

# Exécuter une commande système
ls -l | awk '{ system("commande bash"$1); print ...; }'

# Exécuter une commande système et en récupérer le résultat
# (compter le nombre d'espace dans chaque ligne)
ls -l | awk '{
    cmd = "echo "$0" | tr \" \" \"\n\" | wc -l"
    cmd | getline nbSpaces
    close(cmd)
    if (nbSpaces == 8)
        print ...;
    else
        print ...;
}'

# connaître le numéro de la ligne correspondant à une occurrence
awk '/occurence/{ print NR; exit }' fichier.txt
  • print: affichage simple avec retour à la ligne.
  • printf: affichage avec substitution sans retour à la ligne.
Variables
FS input Field Separator (espace par défaut)
OFS Output Field Separator (espace par défaut)
RS input Record Separator (retour à la ligne par défaut)
ORS Output Record Separator (retour à la ligne par défaut)
NR Number of Records being processed
NF Number of Fields in the current record

sed (Stream EDitor)

regex

[0-9] [[:digit:]] chiffre, \d n'existe pas
\s espace, tab
\w character [0-9a-zA-Z_]
  • Mode basic regex, échapper ? + { } , \( \) sont utilisés pour les groupes
  • Mode extended regex -r, échapper ( ) car utilisés pour les groupes

Remplacer du texte

Manipulation de chaînes de caractères permettant de remplacer des occurrences dans un flux de texte.

Bash.svg
# remplacer des occurrences dans un fichier texte
sed "s/occurrence à remplacer/texte de substitution/drapeaux" -i fichier-cible.txt

# dry run: afficher la sortie au lieu de remplacer dans le fichier
sed "s/occurrence à remplacer/texte de substitution/drapeaux" fichier-cible.txt

# utilisation des groupes
sed "s/\(groupe 1\) \(groupe 2\)/\1 \2/" -i fichier-cible.txt

# caractères spéciaux
sed "s/[0-9]\+\.[0-9]\{1,2\}/ /" -i fichier-cible.txt

# utiliser les simples quotes et un autre signe de séparation : #
sed 's#occurrence à remplacer#texte de substitution#drapeaux' -i fichier-cible.txt

# échapper des simples quotes
echo 'texte' | sed 's/occurrence à remplacer avec un simple quote \x27/texte de substitution/'

# Exemples
# ajouter un \ à la fin de chaque lignes
sed 's/$/\\/' fichier.txt

# échapper un backslash
echo '123\\456' | sed 's/\\/+/'
echo '123\\456' | sed "s/\\\\/+/"

# multiple replace
sed 's/regex1/txt1/; s/regex2/txt2/;' fichier.txt
sed '
s/regex1/txt1/
s/regex2/txt2/' \
-i fichier.txt

Drapeaux :

  • g (global) : remplacement de toutes les occurrences, par défaut seule la première est remplacée
  • I (case-Insensitive)
  • M (Multi lines) : ^ et $ désignent respectivement le debut et la fin d'une ligne, par défaut ils désignent le début et la fin du flux de texte.
Il est possible d'utiliser un autre caractère de séparation que / au cas où celui-ci serait déjà présent dans le texte et qu'il serait impossible ou fastidieux à échapper.
sed -i "s|aaa|bbb|" fichier
sed fait un traitement ligne par ligne, dans le cas d'une expression rationnelle sur plusieurs lignes envisager un autre outils.
Dans le cas où le texte de remplacement contiendrait un retour à la ligne
  • pour un texte encadré par ', utiliser un \ avec un retour à la ligne
  • pour un texte encadré par ", utiliser un \n

Extraire du texte

Bash.svg
# récupère la ligne 'regex (groupe) regex' et extrait 'groupe'
sed -n -r 's/regex (groupe) regex/\1/p' fichier.txt
# -n: suppress automatic printing of pattern space

Insérer du texte

Bash.svg
# insérer avant la correspondance
sed '/regex/i texte à insérer' -i fichier.txt

# insérer après la correspondance
sed '/regex/a texte à insérer' -i fichier.txt

# insérer après la correspondance
sed '/regex/i \
texte\
multi-lignes' -i fichier.txt

# insérer à la deuxième ligne
sed '2i texte à insérer' -i fichier.txt

# modifier le fichier
sed '/regex/i texte à insérer' -i fichier.txt
# modifier le fichier et créer un fichier *.bak
sed '/regex/i texte à insérer' -i.bak fichier.txt

Supprimer des lignes

Bash.svg
# supprimer une ligne entière
sed '/occurrence de la ligne a supprimer/d' -i fichier.txt
sed '\|occurrence de la ligne a supprimer|d' -i fichier.txt

# supprimer la première ligne du fichier
sed '1d' -i fichier-cible.txt

# supprimer la première et la dernière lignes du fichier
sed '1d;$d' -i fichier.txt

# supprimer les lignes 2 à 4 du fichier
sed '2,4d' -i fichier.txt

# supprimer toutes les lignes du fichier sauf la première
sed '1!d' -i fichier.txt

# récupérer la ligne d'une occurrence et supprimer un bloc de 5 lignes
line_number_to_delete=$(awk '/occurrence/{ print NR; exit }' fichier.txt)
if [ -n "${line_number_to_delete}" ] && (( line_number_to_delete != 0 )); then
    sed "$line_number_to_delete,$(( line_number_to_delete + 5 ))d" -i fichier.txt
fi

Erreurs

sed: couldn't open temporary file /path/sedlCpwu7: Permission denied

sed doit avoir les droits d'écriture dans le dossier du fichier à modifier pour créer un fichier temporaire.

Bash.svg
# solution maunelle
sed '2i text' /path/file > /tmp/file
cat /tmp/file > /path/file
rm /tmp/file

wc

Compte le nombre de lignes, de mots, de caractères

Bash.svg
# Compte le nombre de lignes renvoyé par la commande ps -e | grep X
ps -e | grep X | wc -l

# nombre de lignes du fichier « mon-fichier.txt »
echo $(wc -l < mon-fichier.txt)

# Compte le nombre de caractères avec le \0 de fin de mot
echo "123" | wc -m  # 4

tr

Remplacement caractère par caractère.

Bash.svg
# compter le nombre d'espace
echo 'un petit texte' | tr ' ' '\n' | wc -l

tail

Bash.svg
# Affiche au fur et à mesure les lignes ajoutées au fichier
tail -f fichier.log
# fonctionne aussi avec plusieurs fichiers en même temps

# Affiche les 10 dernières lignes d'un fichier
tail fichier.txt

# Supprime les 4 premières lignes d'un fichier
tail -n +5 fichier.txt > fichier_réduit.txt

head

Bash.svg
# affiche les 5 premières lignes de la sortie
ls -at | head -n 5

tac

Inverse de cat: affiche le contenu d'un fichier de la dernière ligne à la première.

rev

Lit les lignes à l'envers

Bash.svg
cat mon-fichier.txt | rev

paste

Concaténation de 2 fichiers ligne par ligne

Bash.svg
paste 1.txt 2.txt -d ';'
# -d séparateur
# 1;un
# 2;deux

jq

Manipulation de donnée JSON.

Bash.svg
# affichage avec coloration syntaxique
echo '{"un":"1","deux":"2"}' | jq

# requête
echo '{"un":"1","deux":"2"}' | jq .deux  # "2"
# affichage brut (raw)
echo '{"un":"1","deux":"2"}' | jq -r .deux  # 2
# afficher toutes les values
echo '{"un":"1","deux":"2"}' | jq '.[]'  # "1" "2"
# afficher toutes les keys
echo '{"un":"1","deux":"2"}' | jq 'keys | .[]'  # "deux" "un"

# lancer une commande pour chaque élément
jq -r '.backup | .[]' backup_pc_folders.json | \
    xargs -I '{}' -P 4 -t bash -c "echo '{}'"

jq -r '.backup | .[]' backup_folders.json |
  while read -r folder; do
    echo $folder
  done

jq -r '.[]|[.name, .value] | @tsv' MyAppSettings.json |
  while IFS=$'\t' read -r name value; do
    echo $name - $value
  done

# stocker le résultat dans un tableau
IFS=$'\n' read -r -d '' -a my_array < <(jq -r '.key | .[]' file.json && printf '\0')

sort

Trie la sortie d'une commande

Bash.svg
# Trie la liste des fonts en ignorant la casse
fc-list : family | sort -f

# 08 juin 2013 - texte
sort -k 3,3 -k 2M -k 1
# trie par rapport à l'année -k 3,3
# puis trie par rapport au mois -k 2M
# enfin trie par rapport au jour -k 1

du -h dossier | sort -h
  • -f → ignore la casse
  • -M → comparer les mois
  • -r → inverse les résultats
  • -k → trie par rapport à un élément
  • --debug → affiche l'élément qui a servit au trie
  • -h, --human-numeric-sort → compare human readable numbers (e.g., 2K 1G)
  • -R, --random-sort → mélange aléatoirement au lieu de trier

Manipulation de fichiers / dossiers

cd

Bash.svg
# retour dans le dossier précédent
cd -

ls

-a do not ignore entries starting with .
-A do not list implied . and ..
-l use a long listing format
-o like -l, but do not list group information
-r reverse order while sorting
-t sort by modification time, newest first
-S sort by file size, largest first
-h print human readable sizes
Bash.svg
# lister les dossiers seulement
ls -d */ | cut -f1 -d'/'

# lister les fichiers par taille
ls -lhS

# lister les fichiers par date, le plus récent en premier
ls -thor

exa

Modern replacement for ls.

Bash.svg
# -1: display one entry per line
exa -1 --icons

# -l: display extended file metadata as a table
# -g: list each file’s group
exa -lg --icons

# -a: show hidden and “dot” files. Use this twice to also show the `.' and `..' directories
exa -lgaa --icons

mv

Bash.svg
# copie /chemin1/dossier1 dans /chemin2/dossier2
mv /chemin1/dossier1 /chemin2/dossier2
# /chemin2/dossier2/dossier1

# copie /chemin1/dossier1 dans /chemin2 et le renomme dossier2
mv -T /chemin1/dossier1 /chemin2/dossier2
# /chemin2/dossier2

cp

Bash.svg
# copie de folder1 dans folder2
cp -r /folder1 /folder2
# si folder2 existe déjà, folder1 est copié dans folder2 (/folder2/folder1)
# si folder2 n'existe pas, folder2 est créé et contient le même contenu que folder1

# si folder2 existe déjà et que l'on veut copier le contenu de folder1 dans folder2
cp -r /folder1/. /folder2

rm

Bash.svg
# remove all files except file1.txt and file2.txt
shopt -s extglob
rm -i !(file1|file2).txt
shopt -u extglob

# zsh
setopt extended_glob
rm -i -- ^(file1|file2).txt

trash

Bash.svg
# move a file to the trash
trash-put [filename]

# display the content of the trash and allow to select which files to restore
trash-restore

# empty the trash
trash-empty

# list the content of the trash
trash-list

fd

fd [-HIEsiaLp0hV] [-d depth] [-t filetype] [-e ext] [-E exclude] [-c when] [-j num] [-x cmd] [pattern] [path]

Bash.svg
# extension
fd -e png
# regex
fd '^x.*y$'
# type: Fichier, Dossier, symLink, eXecutable, Empty 
fd -t f
# fichiers et dossiers cachés
fd -H xxx
# ignore les exclusions de git (.gitignore) et fd (.fdignore)
fd -I xxx
# exclure
fd -E /mnt/external-drive '*.bak'
fd peut être masqué par le plugin zsh common-aliases (fichier ~/.oh-my-zsh/plugins/common-aliases/common-aliases.plugin.zsh)

find

Bash.svg
# Recherche d'un fichier commençant par libpcre dans /
find / -name 'libpcre*'
# ne pas afficher les messages Permission denied
find / -name 'libpcre*' 2>&1 | grep -v 'Permission denied'

# Lister tous les dossiers avec une profondeur d'exploration de 1 (pas de sous-dossiers)
find / -maxdepth 1 -type d

# Recherche tous les fichiers dont les extensions sont so ou exe
find . -name '*.exe' -or -name '*.so'
find . -regex '.*\(so\|exe\)$'
# regex prend en compte le chemin complet et pas seulement le nom de fichier, c'est pourquoi il commence par .*

# Recherche tous les fichiers dont les extensions ne sont ni so ni exe
find . \! -name '*.exe' \! -name '*.so'

# supprimer tous les fichiers *.gz de plus de 7 jours
find . -type f -mtime +7 -name '*.gz' -delete

# Rechercher tous les fichiers contenant l'expression rationnelle
find . -type f -exec awk '/regex/ {c++} c>0 {print ARGV[1] ; exit 0 } END { if (! c) {exit 1}}' \{\} \;

# rechercher tous les fichiers qui viennent d'être modifiés
find / -type f -ls -mmin -1
# -mmin -1 : modifiés depuis 1 minute ou moins

diff

Bash.svg
# create the diff file
diff -u /path1/file1.txt /path2/file2.txt > /path3/patch.diff

# apply the patch
patch /path1/file1.txt < /path3/patch.diff

Disc usage

df

Displays the amount of space available on the file systems

Bash.svg
df -hl -x tmpfs -x devtmpfs -x overlay
# -h print sizes in powers of 1024 (e.g., 1023M)
# -l limit listing to local file systems
# -x limit listing to file systems not of type TYPE

du

  • -s, --summarize : display only a total for each argument
  • -h, --human-readable: print sizes in human readable format (e.g., 1K 234M 2G)
Bash.svg
# taille du dossier
du -hs dossier

dust

Bash.svg
# display the size of the bigest folders and their bigest content (21 directories/lines by default)
dust -br /path
# -b do not show percentages or draw ASCII bars
# -r reverse order of output, with root at the lowest

# display the size of all the folders
dust -brd 1 /path
# -d 1 shows 1 level of subdirectories + remove restriction on the number of directories/lines displayed

# display the size of the bigest folders and their bigest content (10 directories/lines)
dust -brn 10 /path
# -n 10 shows 10 directories/lines instead of the 21 default

# install
cargo install du-dust

chmod

Bash.svg
# chmod [ugo][+-][rwxXst] fichier-ou-dossier
# X get execute rights only to directories and to files which already have execute permission for some user

# forcer les droits u:rw g:r o:r
chmod 644 fichier-ou-dossier

# ajouter le droit write au propriétaire
chmod u+w fichier-ou-dossier

# supprimer tous les droits write à tous les éléments d'un répertoire
# (non récursif et ne s'applique pas au répertoire)
chmod -w dossier/*

# supprimer tous les droits write à tous les éléments d'un répertoire
# (récursif et s'applique aussi au répertoire)
chmod -R -w dossier

# donne au groupe les mêmes droits que ceux de l'utilisateur
chmod g=u fichier-ou-dossier

# modifiez les droits de tous les dossiers sans toucher aux fichiers
find /chemin/vers/un/dossier/ -type d -print0 | xargs -0 chmod 755
# modifiez les droits de tous les fichiers sans toucher aux dossiers
find /chemin/vers/un/dossier/ -type f -print0 | xargs -0 chmod 644
Droits d'endossement: suid, sgid et stiky bit
suid s à la place du x du propriétaire: rwsr-xr-x → 4755 (suid=4) Un programme lancé avec ce droit suid sera exécuté avec les droits du propriétaire du programme et non les droits de l'utilisateur qui l'a lancé.
sgid s à la place du x du groupe: rwxr-sr-x → 2755 (sgid=2) Un programme lancé avec ce droit sgid sera exécuté avec les droits du groupe du programme et non les droits du groupe de l'utilisateur qui l'a lancé.

Les fichiers nouvellement créés auront le goup id du dossier.

stiky bit t à la place du x des autres: rwxr-xr-t → 1755 (stiky bit=1) Dans un répertoire avec ce droit stiky bit, seuls les propriétaires des fichiers pourront les effacer.
S'il n'y avait pas de droit d'exécution x avant d'appliquer ces droits, les lettres s et t seront mises en majuscule.

chown

Bash.svg
chown user:group fichier-ou-dossier
# -R  mode récursif
# -h  modifie les liens symboliques plutôt que les cibles des liens

# change le propriétaire si celui-ci est 1000
chown --from=1000:1000 root:root fichier-ou-dossier

chgrp

Bash.svg
chgrp group fichier-ou-dossier

# équivalent à
chown :group fichier-ou-dossier

ACL - Access Control Lists

Bash.svg
# lister les ACL
getfacl /path

# ajoute les droits rw pour l'utilisateur myuser récursivement dans le dossier /path/folder
setfacl -R -m u:myuser:rw /path/folder
# -m (--modify)

# ajoute les droits rwx pour le groupe mygroup récursivement dans le dossier /path/folder
setfacl -R -m g:mygroup:rwx /path/folder

# remove all extended ACL entries
setfacl -b /path/folder

Connaitre le type MIME d'un fichier

Bash.svg
xdg-mime query filetype fichier.ext
# image/jpeg

file -b -i fichier.ext
# image/jpeg; charset=binary

bat

A cat clone with syntax highlighting and Git integration.

Bash.svg
bat /path/file.ext
.zshenv
# use bat as a colorizing pager for man
export MANPAGER="sh -c 'col -bx | bat -l man -p'"

Archivage

tar

Bash.svg
# extrait une archive dans le dossier courant, tar devine le bon décompresseur
tar xvf archive.tar.gz
# extrait une archive dans /mon_dossier
tar xvf archive.tar.gz -C /mon_dossier

# créer une archive tar.gz contenant des fichiers
tar czf Archive.tar.gz fichier1.txt fichier2.txt *.sh
# créé une archive tar.gz à partir de mon_dossier
tar cvzf archive.tar.gz mon_dossier
# créé une archive tar.gz à partir de mon_dossier en excluant le contenus de mon_sous_dossier1 et mon_sous_dossier2
tar cvzf archive.tar.gz --exclude={mon_dossier/mon_sous_dossier1/*,mon_dossier/mon_sous_dossier2/*} mon_dossier
# créé une archive tar.gz et supprimer les fichiers archivés
tar cvzf archive.tar.gz fichier1.ext fichier2.ext --remove-files

# créer une archive tar
tar cf MonDossier.tar MonDossier
tar cf Fichiers.tar fichier1.txt fichier2.txt *.sh

# créer une archive tar.7z
tar cf - MonDossier | 7z a -si MonDossier.tar.7z

# multithreads avec pigz
tar cf Archive.tar.gz -I pigz Dossier1 Dossier2 Fichier1
tar cf - Dossier1 Dossier2 Fichier1 | pigz > Archive.tar.gz
# désarchiver
tar xf Archive.tar.gz -I pigz

# encrypter l'archive
tar cf - MonDossier | pigz | openssl aes-256-cbc -pass pass:mon_mot_de_passe > MonDossier.tar.gz.enc
# décrypter l'archive
openssl aes-256-cbc -d -pass pass:mon_mot_de_passe -in MonDossier.tar.gz.enc | tar -xz -f -
  • x : extract files from an archive
  • c : create archive from files
  • f : use archive file
  • v : verbosely list files processed
  • z : gzip
  • j : bzip (bz2)
tar peut deviner le décompresseur à utiliser (gzip, bzip, etc). Il n'est donc pas nécessaire de spécifier les options correspondantes (z, j)
gzip est plus rapide que bzip2 mais compresse moins.

Suppression de « / » au début des noms des membres

tar supprime le « / » au début des noms de dossiers et fichiers à archiver. Ceci afin d'éviter d'écraser des dossiers et fichiers systèmes lors de la décompression. Pour éviter ce comportement, il faut utiliser des chemins relatifs au lieu de chemins absolus.

unzip

Bash.svg
unzip fichier.zip
# -q dézippe silencieusement sans afficher dans le détail tous les fichiers qui sont créés

gzip

Bash.svg
# décompresser une archive dans le même dossier
gzip -dk archive.gz
# -k : keep the archive, sinon elle est supprimée par défaut

# décompresser une archive avec choix de la destination
gzip -dkc archive.gz > /ailleurs/fichier

# créer une archive
gzip -k fichier.txt
# -k : conserver fichier.txt, sinon il est supprimé
gzip ne peut compresser qu'un seul fichier. C'est pourquoi il est utilisé en combinaison avec tar

7zip

Bash.svg
# create an archive with folder1 and file1.ext
7z a archive.7z folder1 file1.ext
# -p to ask for a password
# -tzip to create a zip instead of of 7z

# désarchiver (-o: change the output folder)
7z x MonArchive.7z -oFolder
# désarchiver et renommer le fichier (-so: standard output). Peut créer un problème d'encoding.
7z x MonArchive.7z -so > file.ext

# créez une archive tar.7z
tar cf - MonDossier | 7z a -si MonDossier.tar.7z

# extraire le contenu d'une archive tar.7z
7z x -so MonDossier.tar.7z | tar xf -

Avec Cygwin:

Bash.svg
seven-zip=$(cygpath -u "C:\Program Files\7-Zip\7z.exe")

"$seven-zip" a -tzip archive.zip Dossier Fichier.ext
Les archives zip avec un cryptage AES-256 et un mot de passe ne peuvent être déchiffrées nativement sous Windows

pigz

Bash.svg
# compress
pigz file.txt  # file.txt.gz
pigz -c file.txt > archive.gz

# uncompress
pigz -d file.txt.gz

# options
# -k keep source file
# -z compress to zlib (.zz) instead of gzip
# -K compress to zip instead of gzip
# --best / -9 best and slowest compression
# --fast / -0 fastest and lowest compression
# -c write to stdout (won't delete)

# compress directory
tar cf - directory/ | pigz > directory.tar.gz
tar --use-compress-program=pigz -cf directory.tar.gz directory/

Network

wget

Bash.svg
# Télécharger un fichier
wget http://...MonFichier.ext

# Renommez le fichier téléchargé
wget http://...MonFichier.ext -0 chemin/AutreNom.ext
# Affichez le contenu du fichier dans la sortie standard
wget http://...MonFichier.ext -0 -

# Téléchargez toutes les images jpg et gif d'un site
# Dans ce cas le mode récursif ne marchera pas car les fichiers html ou php ne seront pas téléchargés
wget -m -A jpg,gif http://site.fr/

# Téléchargez récursivement le contenu de dossier sans remonter au répertoire parent
wget -r -np http://site.fr/dossier/

# test si le fichier existe
wget --spider -q http://...MonFichier.ext
if [ $? == 0 ]
# en 1 ligne
wget --spider -q http://...MonFichier.ext && echo ok || echo ko
--max-redirect=0 empèche les redirection 302 Moved Temporarily
--no-verbose réduit les commentaires de sortie
-q pas d'affichage en sortie
--referer= spécifie l'url de la page qui demande le téléchargement du fichier
-e robots=off ignorer les instructions du fichier robots.txt
-np ne pas récupérer des éléments du dossier parent
--user-agent= faire passer wget pour un navigateur web

Firefox - Linux 32 : Mozilla/5.0 (X11; Linux i686; rv:20.0) Gecko/20100101 Firefox/20.0
Internet Explorer 10 - Windows 7 32 : Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)

--limit-rate=50k limite la vitesse de téléchargement
-nd dans le cas d'un téléchargement récursif, pas de création de la hiérarchie de dossiers
EXIT STATUS
0   No problems occurred.
1   Generic error code.
2   Parse error---for instance, when parsing command-line options, the .wgetrc or .netrc...
3   File I/O error.
4   Network failure.
5   SSL verification failure.
6   Username/password authentication failure.
7   Protocol errors.
8   Server issued an error response.

curl

wget vs curl

Bash.svg
curl http://www.domain.fr/file.txt > file.txt
Récupérer la commande curl équivalente:

Firefox → Ctrl+Shift+q (Network in Developer Tools) → Reload

Clique-droit sur une ligne → copy as cURL

Autres

date

Bash.svg
date +%Y-%m-%d
# 2020-01-30

date -d "yesterday" +%Y-%m-%d
# 2020-01-29

secret-tool

Accès à Gnome Keyring

Bash.svg
# enregistrer un mot de passe avec le label MySQL et les clé→valeur server→mysql user→root key→password
secret-tool store --label='MySQL' server mysql user root key password
# les clé→valeur serviront par la suite à la récupération du mot de passe

# récupération du mot de passe avec les clé→valeur server→mysql user→root key→password
secret-tool lookup server mysql user root key password
Si plusieurs entrées correspondent aux clé→valeur, la première est retournée.

xdotool

Bash.svg
# Control+v puis Entrée
xdotool key ctrl+v Return

# Control+v
# délai de 0ms (au lieu de 12ms) entre l'appui des touches
# les modificateur ctrl, alt, super sont ignorés
xdotool key --delay 0 --clearmodifiers ctrl+v

# alt + tab
xdotool keydown alt key Tab; sleep .1; xdotool keyup alt

# bouton 1 de la sourie
xdotool click 1

# target a specific window
xdotool search --class 'My window class' windowactivate --sync key Right
# windowactivate --sync  active the window and wait until it is activated
# --onlyvisible  search only among displayable windows. Useful when the search retrieves multiple results with undisplayable windows.
Use xprop to get info on a window (name, class)

Détacher un processus

Cela permet de fermer le terminal en laissant le processus tourner.

Bash.svg
nohup [commande] &

# si le processus est déjà lancé
# le mettre en pause: Ctrl-Z
# le faire tourner en background
bg
# puis détacher le processsus
disown

Clipboard

Bash.svg
# copie test dans le presse papier
echo test | xclip -selection clipboard

# copie test dans le presse papier du bouton du milieu
echo test | xclip

# copie d'un fichier binaire
cat photo.png | base64 | xclip
# coller
echo '# clique-milieu pour coller
' | base64 -d > photo.png

rsvg-convert

Convertir une image SVG en PNG

Bash.svg
rsvg-convert -w $size -h $size fichier.svg > fichier.png

FTP

Les options de ftp : v → verbeux, n → désactive auto-login (lecture d'informations dans le fichier ~/.netrc)

Bash.svg
#!/bin/bash 

ftp -vn << EOF 
open bananeatomic.free.fr 
quote user bananeatomic 
quote pass ****
cd dossier_destination 
passive 
ascii 
put chemin_fichier_local [chemin_fichier_destination] 
bye 
EOF

hl - Highlight (colorize) text data using regular expressions

Bash.svg
# coloration en rouge de texte
echo "un petit texte" | hl -3r texte

# utilisation d'expression rationnelle: coloration en vert des mots qui contiennent un e
echo "un petit texte" | hl -e -3g '\<\w*e\w*\>'

# utilisation de la configuration (/etc/default/hl)
df -h  | hl --df

# désactiver la colorisation des commandes colorisées
USE_HL=no df -h

# installation
yay --editmenu -S hl-git
# in PKGBUILD remove lines 25 and 26
# sed "s/inline //g" -i cr_main.c
/etc/default/hl
pacman          :
     -e
     -3g '^\S[^/]+/([^ ]+)'
Pour faciliter la coloration, des scripts encapsulent les commandes à colorer.
Ces scripts sont placés dans /usr/lib/hl_bin et PATH est modifié pour que les nouveaux scripts aient la préséance sur les commandes.

sleep, timeout

Bash.svg
# arrête le programme pendant 1 seconde
sleep 1 && echo ok

# définit un temps d'attente max
timeout 1 sleep 2 && echo ok || echo ko
# code de retour: 124 (timeout), 0 (ok)

Parallel

Allow to run commands in parallel. The GNU Parallel tool needs to be installed.

Bash.svg
# list all mp4, then remove extension, then add avi extension
ls *.mp4 | sed -n 's/\.mp4$//p' | parallel echo "{}.avi"

tldr

Simplified and community-driven man pages with practical examples.

Bash.svg
tldr [command]

XML with xmlstarlet

Bash.svg
# replace: edit update
xml ed -u "/query" --value "new value" file.xml
Global option Description
L edit file inplace
S preserve non-significant spaces
O omit XML declaration (<?xml ...?>)