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 (.*)
# -g "*.txt" rechercher dans les fichiers respectant le 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 -R -n -H -C 5 --exclude-dir={.git,.svn,CVS} occurence /chemin
# -R Read all files under each directory, recursively. Follow all symbolic links, unlike -r.
# -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

# 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
egrep → grep -E
fgrep → grep -F

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] chiffre, \d n'existe pas
\s espace, tab
  • Mode basic regex, échapper ? + { } ( )
  • Mode extended regex -r, plus besoin d'échapper les caractères précédents

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 -i "s/occurrence à remplacer/texte de substitution/drapeaux" 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 -i "s/\(groupe 1\) \(groupe 2\)/\1 \2/" fichier-cible.txt

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

# utiliser les simples quotes et un autre signe de séparation : #
sed -i 's#occurrence à remplacer#texte de substitution#drapeaux' 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/\\\\/+/"

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.

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

# modifier le fichier
sed -i '/regex/i texte à insérer' fichier.txt
# modifier le fichier et créer un fichier *.bak
sed -i.bak '/regex/i texte à insérer' 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

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

# lancer une commande pour chaque élément name/value
jq -r '.[]|[.name, .value] | @tsv' MyAppSettings.json |
  while IFS=$'\t' read -r name value; do
    echo $name - $value
  done

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

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

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 *.exe
find . -name '*.exe' -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

du - taille d'un dossier

  • -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

chmod

Bash.svg
# chmod [ugoa][+-][rwx] fichier-ou-dossier

# 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 a-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 a-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

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

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 - Dossier1 Dossier2 Fichier1 | pigz > Archive.tar.gz

# 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
# créez une archive contenant MonDossier et MonFichier.ext
7z a -tzip MonArchive.zip MonDossier MonFichier.ext

# désarchivez
7z x MonArchive.7z

# 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

Autres

date

Bash.svg
date +"%Y-%m-%d"
# 2013-04-27

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

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

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

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

MySql

Bash.svg
mysql -h [ip] -D [database name] -u [user] -p[password] -e "commande mysql" -vvv
# -vvv pour afficher la sortie mysql dans le terminal

mysql -u [user] -p[password] << EOF
commandes mysql
EOF

# il faut mettre le mot de passe entre simple quote s'il contient les caractères suivants : * ? [ < > & ; ! | $ ( )
mysql -u [user] -p'[password]'

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
/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)