Unix bash, les commandes que l'on ne devrait pas oublier
Par PlaceOweb le samedi, septembre 3 2011, 18:33 - Bash - Lien permanent
Un bref rappel pour les utilisateurs et les administrateurs sous linux. A coup de vi, awk, sed pour expression régulières, .sh, etc... pour se simplifier les taches quotidiennes d'édition, substitution en faisant des scripts.
Si vous rechercher la même chose sous Windows, suivez ce lien : mémo sur Windows des commandes utiles
killall
A défaut de faire fonctionner killall avec un patern d'expression régulière, voici d'autres méthodes :
pkill et pgrep
- Lister tous les processus qui comprennent "SCREEN" dans leur programme ou argument de l'utilisateur "www-data"
pgrep -u www-data -l -f SCREEN
- Tuer tous les processus qui comprennent "SCREEN" dans leur programme ou argument de l'utilisateur "www-data"
pkill -u www-data -f SCREEN
NOM
pgrep, pkill - Rechercher ou envoyer un signal à des processus en fonction de leur nom et d'autres propriétés
SYNOPSIS
pgrep [-cflvx] [-d délimiteur] [-n|-o] [-Pppid,...] [-g pgrp,...] [-s sid,...] [-u euid,...] [-U uid,...] [-G gid,...] [-t term,...] [motif]
pkill [-signal] [-fvx] [-n|-o] [-P ppid,...] [-gpgrp,...] [-s sid,...] [-u euid,...] [-U uid,...] [-G gid,...] [-t term,...] [motif]
-l Lister le nom du processus avec son identifiant. (Seulement pour pgrep.)
-f Le motif n'est normalement comparé qu'au nom du processus. Avec -f, la ligne de commande complète est utilisée.
Tuer tous les processus correspondant à un motif en une seule commande (expression régulière)
ps ax|grep myPattern|awk '{print $1}'|xargs kill
screen
# Créer le screen "monScreen" détaché screen -A -m -d -S monScreen $SOFTPATH/$SOFTBIN $SOFTARGS
# Quitter le screen "monScreen" screen -S monScreen -X quit
- Introduction à GNU Screen pour les nuls
- Exécuter des programmes en arrière-plan - screen : plusieurs consoles en une
- FAQ Linux - Le Shell > Commandes avancées - Démarrer un programme non-graphique en arrière plan et le rappeller à la volée ?
awk
Lister un ligne précisée et numérotée d'un fichier
Lister le contenu de la ligne 33 du fichier
awk 'NR == 33 {print $0 }' fichier
Imprimer de la ligne 5 à la ligne 10 , chaque ligne précédée par son numéro
awk 'NR == 5 , NR == 10 {print NR" : " $0 }' fichier
Utiliser une variable dynamique
get=$(($i + 5))
awk -F '&' '{print $'"$get"'}'
// Resultat de awk -F '&' '{print $5}'
#!/bin/bash
var="variable"
variable="dynamique"
echo "Ma $var est une ${var} ${!var}"
// Resultat : Ma variable est une variable dynamique
Exemple de programme surveillant le temps d'exécutions des processus Apache, et les tuant s'ils tournent depuis trop longtemps : checkApache.sh
#/bin/sh
#ps faux|grep apache2
#ps faux|grep apache2|awk '{print $1,$5}'
# ps faux
#USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
#1 2 3 4 5 6 7 8 9 10 11
#ps faux|grep apache2|awk '{print $1,$2,$3,$4,$10,$11}'
#for i in `ps faux|grep apache2|awk '{print $1,$2,$3,$4,$10,$11}'`
#do
# echo "Welcome $i times"
#done
maxApacheTime=1;
ps faux|grep apache2|awk '
BEGIN { print "Verification des process Apache2 (>'"$maxApacheTime"'s)"; FS=" "; i=0;}
# i=3 # initialisation du compteur à 1 (on commence par le champ 1)
{print $0}
$10 > '"$maxApacheTime"' { i++; system("kill -9 "$2); print "xXx ! Kill processus Apache PID "$2" car il dure depuis "$10"s au lieu des '"$maxApacheTime"'s permises, ligne n°"NR" "i": "$0}
END { print i , ""PID" killed." }
Verification des process Apache2 (>1s) root 31468 0.0 0.0 5656 788 pts/1 S+ 18:32 0:00 \_ grep apache2 root 31080 0.0 0.7 291212 14784 ? Ss Jan08 0:22 /usr/sbin/apache2 -k start www-data 18371 80.5 3.1 320836 63596 ? R 15:17 156:59 \_ /usr/sbin/apache2 -k start xXx ! Kill processus Apache PID 18371 car il dure depuis 156:59s au lieu des 1s permises, ligne n°3 1: www-data 18371 80.5 3.1 320836 63596 ? R 15:17 156:59 \_ /usr/sbin/apache2 -k start www-data 29913 0.0 3.3 317536 67028 ? S 18:08 0:00 \_ /usr/sbin/apache2 -k start www-data 30127 0.0 0.9 291968 19520 ? S 18:11 0:00 \_ /usr/sbin/apache2 -k start www-data 30504 0.0 0.8 295048 17888 ? S 18:17 0:00 \_ /usr/sbin/apache2 -k start www-data 30905 0.0 0.9 292468 19856 ? S 18:24 0:00 \_ /usr/sbin/apache2 -k start www-data 30919 0.0 0.9 291992 19560 ? S 18:24 0:00 \_ /usr/sbin/apache2 -k start www-data 31088 0.0 0.8 292468 16980 ? S 18:26 0:00 \_ /usr/sbin/apache2 -k start www-data 31143 0.1 3.1 317528 63196 ? S 18:27 0:00 \_ /usr/sbin/apache2 -k start www-data 31145 0.0 0.9 291968 19196 ? S 18:27 0:00 \_ /usr/sbin/apache2 -k start www-data 31151 0.0 0.8 292980 17388 ? S 18:27 0:00 \_ /usr/sbin/apache2 -k start www-data 31159 0.0 0.4 291744 8424 ? S 18:27 0:00 \_ /usr/sbin/apache2 -k start 1 "PID" killed.
Ressouces awk
- La commande awk
- sing BEGIN/END - The GNU Awk User's Guide
- Awk Introduction Explained by examples rather than by definitons
- Global Variable in awk...
# Global Variable in awk
# You can do :
A=20071225
awk '{ print "the value of A is" '"$A"' }' infile
# Or
A=20071225
awk -v A="$A" '{ print "........"; c=10; print $c ; c=A ; print A}' infile
#Or
A=20071225
awk '{ print "........"; c=10; print $c ; c=A ; print A}' A="$A" infile
#Or
export A=20071225
awk '{ c=ENVIRON["A"] + $1; print c}' infile
find
- Exercices sur find
- Manuel documente la version GNU de find
- Les commandes grep et find
- Wikipedia find et xargs
# ls -al *
-bash: /bin/ls: Argument list too long
# find . -exec ls -al {} \;
# find -name "*.php" -exec chown www-data.www-data {} \;
# find -name "*.php" -exec chmod 644 {} \;
# find . -exec grep hinet.net {} \;
# find . -type f -print | xargs grep hinet.net
grep
grep extraire que la partie recherchée entre parenthèses : grep -o, --only-matching : N'afficher que les parties (non vides) correspondantes des lignes sélectionnées, chaque partie étant affichée sur une ligne séparée.
grep case insensitive : grep -i, --ignore-case : Ignorer la casse aussi bien dans le MOTIF que dans les fichiers. (-i est une spécification POSIX.)
vim
How to do case insensitive search in Vim. case insensitive ignorecase en rajoutant \c
/ma_recherche\C " Case sensitive /ma_recherche\c " Case insensitive
Astuces ou commandes fréquentes
Copier un fichier via SSH
Résumé de l'article Shell Transferer des fichiers via ssh :
ssh serveur "cat fichier_distant" > fichier_local
En le compressant pour économiser du temps de transfert et de la bande passante :
ssh serveur "gzip -c fichier_distant" > fichier_local.gz
ssh serveur "gzip -c fichier_distant" |gunzip > fichier_local
Effacer un fichier ayant un nom débutant par un tiret "-fichier.txt".
rm -- -fichier.txt
Note : -- est utilisable pour toutes les commandes shell.
Renommer plusieurs fichiers simultanément.
Exemple : pour renommer les fichiers *.jpeg en *.jpg
for i in *.jpeg; do mv "$i" "${i%.jpeg}.jpg"; done
Afficher les lignes d'un fichier sans les lignes commentées.
Les lignes commentées sont celles qui commencent par # dans les fichiers. Pour afficher à l'écran le contenu du fichier sans ces lignes, tapez :
sed -e "/^#/d" fichier
Explication de la commande :
- sed (Stream Editor) permet de travailler sur les flux.
- ^ signifie tout ce qui commence par (dans notre cas, ce qui commence par #).
- d permet de supprimer les lignes qui correspondent à l'expression indiquée entre les barres obliques (/^#/ dans notre exemple).
Supprimer les ^M en fin de ligne d'un fichier texte écrit sous Windows.
Il suffit de taper au choix dans vim:
:set fileformat=unix
:%s/\r//g ou :%s/(CTRL+v)(CTRL+m)//g
En dehors du fichier
sed s/{CTRL+v}{CTRL+m}//g filename >> newfile
Supprime tout vos caractères 'r' du fichier
tr -d 'r' < fichier_windows.txt > fichier_windows_converti.txt
Supprimer les lignes vides (ou ne contenant que des espaces) dans un fichier
sed '/^[[:space:]]*$/d' /TMP/fichier
Supprimer les lignes vides sous VI
:g/^$/d
Supprimer les lignes contenant le motif (vim delete line)
:g/la_chaine_recherchéé_dont_il_faut_effacer_la_ligne/d
Substitution de "abc" par "ijk" sous VI
:%s/abc/ijk/g
Changer de répertoire, revenir au répertoire précédent
cd $OLDPWD
ou
cd - #permet de remonter autant de fois que l'on veut
Vider le contenu d'un fichier existant ou qui n'existe pas
:>fichier
Adresse IP, parsing grep posix ip
hostname -i | egrep '[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}'
La première commande affichera l'adresse IP, et la seconde vérifiera qu'il s'agit d'une expression régulière POSIX concernant une IP (V4)
egrep not ascii (recherche tous les caractères non ASCII : les caractères accentués par exemple é è ç ...)
grep --color='auto' -P -n "[^[:ascii:]]" file.txt
How Do I grep For all non-ASCII Characters in UNIX
grep --color='auto' -P -n "[\x80-\xFF]" file.xml
(grep) Regex to match non-ASCII characters?
PCRE (Perl-Compatible Regular Expression)
[^\x00-\x7F]
POSIX
[[:ascii:]] - matches a single ASCII char
[^[:ascii:]] - matches a single non-ASCII char
Calculer en bash
Calculs : faire des additions, soustractions, multiplications, divisons, modulos... La liste des opérations est la suivante :
- + , - , *, / : addition, soustraction, multiplication, division
- % : reste de la division entière
- ** : exponentiel
a=2
b=4
c=1
d=$(( a**b + c ))
#retourne "2 puissance 4 plus 1" = "17"
echo $d
Remarque : à l'intérieur des doubles parenthèses, les noms des variables n'ont pas besoin d'être préfixés par le caractère $. Vous pouvez néanmoins le faire quand même, les deux syntaxes seront acceptés.
# Incrémente une variable, de la même manière que let y=y+1 et y=$(($y+1))
y=`expr $y + 1`
y=$(($y+1))
Un substring en bash
# Extrait une sous-chaîne de caractères de $longueur caractères, en partant de $position.
z=`expr substr $chaine $position $longueur`
Convertir en majuscule et minuscule en bash
Tiré de Le shell Bash et plus encore
# Convertit le premier caractère en majuscule
word=abce123azreaz
first=`echo ${word:0:1} | tr 'a-z' 'A-Z'`
rest=`echo ${word:1} | tr 'A-Z' 'a-z'`
echo "$first-$rest"
# Retourne : A-bce123azreaz
Dates
Obtenir une date formatée il y a plusieurs jours (1 mois)
date +%d%m%Y --date='-1month'
Purger et/ou déplacer des fichiers obsolètes, idéal pour l'archivage
cd /monRepertoire/quiContient/lesVieuxFichiers
# Compresser en tar.gz les fichiers vieux d'il ya plus d'un jour
tar -czvf - `find . -daystart -mtime +0 -type f -print` > `date +"%Y%m%d"`/ftparchives/$maDate.tar.gz
# Rechercher les fichiers modifiés aujourd'hui dans de dossier web
find /var/www -mtime 0
# Supprimer les vieux fichiers > 80 jours
find . -mtime +80 -type f -exec rm -fv {} \;
# Rechercher, puis supprimer les dossiers .svn en récursif
find . -name .svn -type d -exec ls -al {} \;
find . -name .svn -type d -exec rm -frv {} \;
Impossible de supprimer tous les fichiers d'un dossier, sûrement car il y en a trop dans votre répertoire
# rm -f * -bash: /bin/rm: Liste d'arguments trop longue Argument list too long
Utilisez find :
find . -exec rm -f {} \;
Pour supprimer uniquement des fichiers selon l'extension :
# rm -f *.html find . -name '*.html' -exec rm -f {} \;
Autres ressources liées
Comment effacer un "gros" répertoire (50000 fichiers par exemple) ?
J'ai mon répertoire qui fait 3Go ! J'ai donc voulu le vider, mais impossible. Il y a presque 50 000 fichiers, et quand je fais un rm *, j'ai l'erreur : bash: /bin/rm: Liste de paramètres trop longue
On peut taper en ligne de commande :
find tonRepertoire -type f | xargs rm -f
Supprimer une grande quantité de fichiers impossible
ls | xargs rm -f
Programmation.shell : Supprimer liste de fichier en bash
xargs -a a_supprimer.lst -d \n rm
Le nombre d'utilisateurs connectés, leur détail et heure de connexion sont accessibles depuis les commandes : finger who w
serveurLinux:~# finger Login Name Tty Idle Login Time Office Office Phone root root *pts/0 Jan 25 01:07 (ags84-1-83-242-241-7.fbx.proxad.net) root root *pts/4 17:12 Jan 22 11:27 (lns-zfv-48f-61-157-154-112.adsl.proxad.net) serveurLinux:~# who root pts/0 2008-01-25 01:07 (ags84-1-83-242-241-7.fbx.proxad.net) root pts/4 2008-01-22 11:27 (lns-zfv-48f-61-157-154-112.adsl.proxad.net) serveurLinux:~# w 03:20:50 up 3 days, 14:45, 2 users, load average: 0,12, 0,05, 0,01 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT root pts/0 ags84-1-83-242-2 01:07 0.00s 0.25s 0.00s w root pts/4 lns-zfv-48f-61-1 Tue11 17:14 2:42m 0.75s -bash
Tri et taille humaine des fichiers
# Notez l'utilisation de sort -h qui permet le tri des valeurs humaines (K, M, G)
du -hc --max-depth=1 | sort -h
Extraire une ligne spécifique (numéro) d'un fichier
Par exemple pour extraire uniquement une ligne (la 37582)
Méthode 1
sed -n -e 37582 fichier.log > /tmp/extractJustOneLine
# ou pour une partie de lignes de ... à ...
# sed -n -e 100,200p fichier.log
Méthode 2
cat -n fichier.log|grep ^37582 > /tmp/extractJustOneLine
Méthode 3
tail -n +37582 fichier.log > /tmp/extractFromLine
head -n 1 /tmp/extractFromLine > /tmp/extractJustOneLine
Méthode 4
Par ouverture avec vim de 2 fichiers en simultanée vim Éditer plusieurs fichiers
vim fichier1 fichier2. Vous pouvez passer au suivant en tapant :n, au précédent en tapant :N
Avec le fichier 1, se positionner à la bonne ligne (SHIFT 37582), copier la ligne (yy), se placer sur le second fichier (:n), coller (p), enregistrer et quitter (:wq!)
VIM et SED
- Vim Tips Wiki : Search and replace
- Sed - Trucs et astuces
- vim : expressions régulières rechercher remplacer (mémo)
- sed
Ressouces
Sites Bash utiles et utilisés
- Une exploration en profondeur de l'art de la programmation shell, le guide avancé (4.0-fr) d'écriture des scripts Bash et ses exemples de scripts (18 juin 2006)
- Approfondir Bash
- Toutes les commandes linux
- http://www.shellunix.com/
- Les Principales commandes
- Les expressions régulières
- La commande sed
- La commande awk
- Command-line Fu est un petit site rassemblant toutes ces petites lignes de commande sous Linux qu'on ne retient jamais, dont on a besoin très souvent et qu'on galère à retrouver sur le net...
Guide avancé d'écriture des scripts Bash
Traduction française, Guide avancé d'écriture des scripts Bash de l'Advanced Bash-Scripting Guide