Trucs et astuces shell
Aide mémoire de commandes Bash.
Fond d'écran aide-mémoire
Ce fond d'écran regroupe les commandes Shell les plus courantes. Téléchargez le fond d'écran aide-mémoire shell.
Source: Merci à Olivier Prieur pour fond d’écran avec toutes les commandes unix : trop fort !.
Sudoifier la dernière commande tapée
Si vous avez oublié sudo pour une commande, rattrapez l'erreur:
sudo !!
Source: Oublié de taper sudo ? sudo !!
Gérer les arguments d'un script Bash
Pour gérer les options courtes (-h) ou longues (--help) d'un script Bash, reportez-vous à la fonction getoptex, documentée dans le paquet bash-doc:
sudo apt-get install bash-doc
Ouvrez le fichier /usr/share/doc/bash/examples/functions/getoptx.bash :
command gedit /usr/share/doc/bash/examples/functions/getoptx.bash
Le fonctionnement de cette fonction est similaire à celui de getopt:
man getopt
Obtenir le chemin réel d'un fichier dans Bash (équivalent de la fonction PHP realpath)
Pour obtenir l'équivalent de la fonction PHP realpath dans un script shell, utilisez:
REAL_PATH=$(command readlink -f "./chemin/../vers/mon/fichier.txt")
Source: Merci à Andy Skelton pour son article Bash equivalent for PHP realpath().
Obtenir l'adresse IP correspondant à un hôte:
Obtenez l'adresse IP de l'hôte DOMAIN:
DOMAIN='localhost'
HOST_IP="$(command getent ahostsv4 "${DOMAIN}" \
| command cut --delimiter=" " --fields=1 \
| command tail -n 1)"
echo "${HOST_IP}"
Obtenir l'adresse IP d'une interface réseau:
Obtenez l'adresse IP de l'interface eth0:
NET_DEV="eth0"
NET_IP="$(command ifconfig "${NET_DEV}" \
| command grep 'inet ' \
| command sed -e 's/^.*inet [^:]*:\([^ ]*\) .*$/\1/')"
echo "${NET_IP}"
Obtenir l'adresse IP publique d'un ordinateur:
Obtenez l'adresse IP publique d'un ordinateur derrière un pare-feu NAT (ou autre):
PUBLIC_IP=$(command wget -qO- 'http://ipecho.net/plain')
echo "${PUBLIC_IP}"
Source : Merci au Labo Linux de Supinfo pour l'article Connaître son IP publique derrière un routeur.
Détecter si un port TCP est ouvert
La commande suivante liste les ports TCP ouverts:
command netstat -tnl \
| command cut --characters=21-44 \
| command sed -e 's/.*:\([^:]*\)[ ]*$/\1/' \
| command tail -n +3
La commande suivante incrémente la variable ${SERVER_PORT} jusqu'à ce qu'elle pointe vers un port ouvert. Renseignez le port de base à tester:
SERVER_PORT=8080
Recherchez le premier port ouvert à partir de ce port de base (par incrément de 1):
while [ -n "$(command netstat -tnl \
| command cut --characters=21-44 \
| command sed -e 's/.*:\([^:]*\)[ ]*$/\1/' \
| command tail -n +3 \
| command grep "${SERVER_PORT}")" ]; do
SERVER_PORT=$((${SERVER_PORT} + 1))
done
Vérifier qu'un hôte est joignable
Utilisez ping pour vérifier qu'il est possible d'accéder à un hôte par le réseau. Déclarez la fonction is_host_alive:
# Check if a host is alive.
#
# @param string $host A IP address or FQDN.
#
# @return integer 0 if host is alive, 1 if not.
function is_host_alive() {
command test ${#} -ne 1 && exit 1
PING_SUCCESS_COUNT="$(command ping -c 2 -q "${1}" 2>&1 \
| command grep "received" \
| command cut -d ',' -f2 \
| command cut -d ' ' -f2)"
if [ "${PING_SUCCESS_COUNT}" != "0" -a "${PING_SUCCESS_COUNT}" != "" ]; then
# host replied
return 0
fi
# No reply from host.
return 1
} # is_host_alive()
Renseignez le nom de domaine, ou l'adresse IP, de l'hôte:
CHECKED_HOST="www.google.fr"
Vérifiez que l'hôte répond au ping:
if is_host_alive "${CHECKED_HOST}"; then
echo "${CHECKED_HOST} is alive."
else
echo "${CHECKED_HOST} is dead."
fi
Merci à Linux Poison pour Bash Script: Check Servers Availability using ping command.
Trouver quel processus écoute sur un port
Si vous souhaitez découvrir quel processus écoute sur un port, utilisez (ici pour le port TCP 443):
command lsof -i TCP:443
Convertir une chaîne en hexadécimal
Convertissez une chaîne de caractères en hexadécimal:
CHAINE="exemple"
echo -n "${CHAINE}" \
| command od -An -tx1 -w250
L'option -w250 de od spécifie qu'il doit y avoir 250 caractères par lignes dans la réponse.
Convertir un nombre hexadécimal en décimal
Utilisez (ou FF est le nombre hexadécimal):
command printf "%d\n" 0xFF
Écrire un nombre décimal dans un fichier binaire
Pour convertir un décimal en sa version binaire sur 32bits:
command printf "%.8x" ${NUMBER} | command xxd -r -p -g0 >> 'output.bin'
Source: Merci aux participants à Bash: write integer to binary file
Appliquer une commande à plusieurs fichiers
Hormis le célèbre caractère joker "*", il est possible de sélectionner de manière précise des fichiers lors que l'on utilise un shell Bash. Il est ainsi possible de placer des textes entre { et }, séparés par des virgules, pour faire une sorte de boucle sélectionnant les fichiers correspondants. Par exemple, pour sélectionner les fichiers exemple avec l'extension "odt" et "txt":
cat exemple.{odt,txt}
Trouver les liens symboliques cassés dans un dossier
Listez tous les liens symboliques cassés dans le dossier courant:
command find ./ -type l -follow
Supprimez tous les liens symboliques cassés dans le dossier courant:
command find ./ -type l -follow -print0 | command xargs -0 rm
Obtenir la taille totale d'un dossier sur le disque
Obtenez la taille totale d'un dossier sur le disque:
command du --human-readable --summarize /mon/dossier
Pour obtenir la taille totale de chaque élément contenu dans un dossier, rajoutez une étoile:
command du --human-readable --summarize /mon/dossier/*
Trouvez les fichiers modifiés il y a plus de N jours.
Listez les fichiers modifiés il y a plus de N jours (ici N=365):
command find ./ -mtime +365 -daystart
Source : Merci à MindSpill pour l'article Find files modified before or after a given date.
Empêcher l'exécution concurrente d'un script Bash avec un fichier verrou
Voici une méthode empêchant l'exécution d'un script Bash s'il est déjà en cours d'exécution.
#!/bin/bash
LOCKFILE=/tmp/extract.lock
if [ -f $LOCKFILE ]; then
echo "Lockfile Exists"
#check if process is running
MYPID=`head -n 1 "${LOCKFILE}"`
TEST_RUNNING=`ps -p ${MYPID} | grep ${MYPID}`
if [ -z "${TEST_RUNNING}" ]; then
echo "The process is not running, resuming normal operation!"
rm $LOCKFILE
else
echo "`basename $0` is already running [${MYPID}]"
exit 1
fi
fi
echo $$ > "${LOCKFILE}"
##Do your stuff here
rm $LOCKFILE
exit 0
Source: Merci à Sysadmin Notebook pour Bash script lock file.
Connaître les programmes utilisant un fichier ou un point de montage
Listez les programmes bloquant le démontage d'un point de montage à l'aide des commande "fuser" et "lsof".
Affichez les logiciels utilisant des fichiers sur le point de montage /point/montage:
command lsof /point/montage
La commande lsof n'affiche pas les points de montages présents dans/point/montage et qui bloquent aussi son démontage.
Calculer la somme MD5 de tous les fichiers présent dans un dossier et ses sous-dossiers
Obtenez les sommes MD5 de tous les fichiers présent dans le dossier en cours et ses sous-dossiers:
command find ./ -type f -print0 | command xargs -0 md5sum
Supprimer la dernière accolade fermante et le contenu qui la suit dans un fichier
Supprimez la dernière accolade fermante d'un fichier:
command sed -i -ne '/}/{x;s/^\n//;p;s/.*//;x};H;${g;s/\n\(.*\)}.*/\1/;p}' fichier.php
Source: Merci à ramok sur irc.freenode.net#sed pour son aide précieuse.
Horodater la commande tail
Pour faciliter l'analyse de fichiers journaux sans horodatage, appliquez un horodatage à la volée:
command tail -F mon-fichier.log | command awk '{ print strftime("%c") " " $0}'
Ajoutez un filtre (grep) si besoin est:
command tail -F mon-fichier.log | command egrep 'ma recherche' | command awk '{ print strftime("%c") " " $0}'
Source : Merci à Jugulu pour sa réponse à Show date/time with tail|grep command.
Modifier le contenu d'un fichier
Remplacer la première occurrence d'une recherche
Remplacez la première occurence d'une recherche:
command sed -i -e '0,/recherche/s//remplacement/' fichier.txt
Remplacer la première occurrence d'une recherche après une autre recherche
Remplacez la première occurrence d'une recherche après une autre recherche:
command sed -i -e '/première recherche/,/élément à remplacer/{s/élément à remplacer/remplacement/}' fichier.txt
Source : merci à gnubien sur irc.freenode.net/#sed
Insérer du contenu dans un fichier
Insérez du contenu au milieu d'un fichier:
/bin/sed -i -e "/correspondance sur la ligne après laquelle insérer le contenu/a\
contenu à insérer\\
seconde ligne de contenu à insérer" fichier
Notez les \\ à la fin de chaque ligne de contenu inséré. Ils servent à préserver le retour à la ligne.
Par exemple, pour ajouter la ligne:
blessent mon cœur d'une langueur monotone.
Après la ligne:
Les sanglots longs des violons de l'automne
Dans le fichier BBC.txt, contenant:
Et maintenant, quelques messages personnels :
Les sanglots longs des violons de l'automne
Je répète :
...
Exécutez la commande:
command sed -i -e "/.*sanglots longs.*/a\
blessent mon cœur d'une langueur monotone." BBC.txt
Vous obtenez ainsi le résultat suivant :
Et maintenant, quelques messages personnels :
Les sanglots longs des violons de l'automne
blessent mon cœur d'une langueur monotone.
Je répète :
...
La syntaxe '//a\' permet d'insérer du contenu après la correspondance. La syntaxe '//i\' permet d'en insérer avant (a pour append, i pour insert).
Insérer du contenu uniquement après la première occurence d'une recherche
Dans certains cas, la chaîne après laquelle insérer des lignes est présente plusieurs fois dans le fichier modifié. Dans ce cas, il est nécessaire de séparer la recherche de l'insertion :
command sed -i -e '0,/^eggs[ ]*=/{//a\
Products.Ploneboard
;}' /opt/Plone-3.1/zeocluster/buildout.cfg
Cet exemple insère "Products.Ploneboards" après la première occurrence de "eggs =". Notez le "0," en début d'expression régulière, il restreint la recherche à la première occurence.
Pour insérer du contenu après la première ligne apparaissant après une ligne donnée, utilisez:
command sed -i -e '/contenu de la première ligne/,/contenu de la seconde ligne/{/contenu de la seconde ligne/a\
contenu inséré.
;}' /etc/squid/squid.conf
Références
- Sed - An Introduction and Tutorial.
- Famous Sed One-Liners Explained, Part I par Peteris Krumins.
- Guide avancé d'écriture des scripts Bash.
Remerciements
- Merci à eMerzh pour son article À la découverte de 5 commandes Linux sympa.