Aller au contenu | Aller au menu | Aller à la recherche


Unix bash, les commandes que l'on ne devrait pas oublier

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

  1. Lister tous les processus qui comprennent "SCREEN" dans leur programme ou argument de l'utilisateur "www-data"
pgrep -u www-data -l -f SCREEN
  1. 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

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

# 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

# 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

Ressouces

Sites Bash utiles et utilisés

Guide avancé d'écriture des scripts Bash

Traduction française, Guide avancé d'écriture des scripts Bash de l'Advanced Bash-Scripting Guide

Ajouter un commentaire

Le code HTML est affiché comme du texte et les adresses web sont automatiquement transformées.

Fil des commentaires de ce billet