IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
logo

FAQ LinuxConsultez toutes les FAQ

Nombre d'auteurs : 56, nombre de questions : 260, dernière mise à jour : 27 juin 2022  Ajouter une question

 

Cette FAQ a été réalisée à partir des contributions des membres du forum Linux de Developpez.com et de l'équipe de rédaction. Merci à eux !

Nous sommes perpétuellement à l'écoute de vos suggestions et corrections, n'hésitez pas à nous en faire part sur le forum.

SommaireLe ShellCommandes avancées (22)
précédent sommaire suivant
 

Par exemple, vous utilisez le Shell zsh, et vous voulez savoir à quel(s) PID (Processus IDentification) il(s) est(sont) lié(s).

La commande fuser retourne les différents PID de zsh :

Code bash : Sélectionner tout
1
2
$ fuser /bin/zsh 
/bin/zsh: 1942e 2860e 2996e 3469m 3487e 4527m 4607e

Comme indiqué dans le man, les caractères suivant le PID correspondent à : On observe donc ici que l'on a cinq programmes zsh en cours d'exécution, et deux projetés en mémoire.

On vérifie la valeur des PID qui correspond bien aux valeurs retournées par fuser :
  • c : répertoire courant ;
  • e : programme en cours d'exécution ;
  • f : fichier ouvert. f est omis par défaut ;
  • r : répertoire racine ;
  • m : fichier projeté en mémoire, ou bibliothèque partagée.


Code bash : Sélectionner tout
1
2
3
4
5
6
7
8
9
$ ps -aux | grep zsh 
francois 1942 0.0 0.0 3560 4 vc/1 S 10:24 0:00 -zsh 
francois 2860 0.0 0.9 3900 2484 pts/1 S 13:43 0:00 /bin/zsh 
francois 2996 0.0 0.8 3692 2212 pts/2 S 14:01 0:00 /bin/zsh 
root 3469 0.0 0.8 3612 2084 pts/1 S 15:25 0:00 zsh 
francois 3487 0.0 1.0 3976 2580 pts/1 S 15:25 0:00 zsh 
root 4527 0.0 0.9 3768 2308 pts/2 S 19:49 0:00 zsh 
francois 4607 0.2 0.8 3728 2268 pts/2 R 20:13 0:00 zsh 
francois 4632 0.0 0.2 1904 760 pts/2 R 20:14 0:00 grep zsh

Une autre alternative est d'utiliser la commande ps de la manière suivante :
Code bash : Sélectionner tout
$ ps -ef | grep zsh

Ici les options POSIX sont privilégiées rendant ainsi cette syntaxe portable sur l'ensemble des UNIX.

Mis à jour le 23 octobre 2013 Francois Trazzi ok.Idriss

Ce sont les opérateurs permettant de gérer les flux de données.

La redirection ">" permet de stocker la sortie d'un programme dans un fichier. Cela crée le fichier s'il n'existait pas, et efface son contenu s'il existe (il faut donc faire attention !) :

Code bash : Sélectionner tout
$ cat fichier1 > fichier_sauvegarde

Si l'on veut rajouter des données au fichier, on utilisera la double redirection ">>" :
Code bash : Sélectionner tout
$ cat ajout >> fichier_sauvegarde

La redirection "<" joue le même rôle. Au lieu de taper au clavier le contenu du fichier, vous pouvez utiliser cette redirection et ainsi le fichier va se substituer a l'entrée standard (saisie clavier) :
Code bash : Sélectionner tout
1
2
$ cat < nom_du_fichier 
$ cat < fichier1 > fichier_sauvegarde

Vous remarquerez que la dernière commande a le même effet que la première.

Mis à jour le 24 novembre 2013 nyal ok.Idriss

Le caractère "|" permet de lier des commandes entre elles. La sortie standard d'une commande devient l'entrée standard de la commande suivante :

Code bash : Sélectionner tout
$ cat fichier | grep YES

La commande cat envoie le contenu du fichier vers la commande grep qui va le lire. Bien entendu, si vous utilisez une commande qui ne lit pas de données sur l'entrée standard, cela n'aura aucun résultat :
Code bash : Sélectionner tout
$ cat fichier | ls

La commande cat envoie bien le contenu vers la commande ls, laquelle ne lit pas sur son entrée standard. Par conséquent, le pipe entre les deux commandes ne sert absolument à rien .

Il est tout à fait possible d'enchaîner un très grand nombre de pipes (la limite dépend des Shells).
Code bash : Sélectionner tout
$ cat fichier | grep YES | sed 's/YES/NO/'

Mis à jour le 23 octobre 2013 nyal ok.Idriss

Voici la signification du sticky bit :

  • sur un fichier : un programme exécutable sera maintenu en zone de swap après la fin de son exécution, ce qui accélérera les chargements ultérieurs ;
  • sur un répertoire : un fichier du répertoire ne peut être supprimé que par son propriétaire.


Permettre à n'importe quel utilisateur de créer et modifier ses fichiers dans un répertoire, c'est mettre les droits rw (et x pour l'exploration) pour tous les utilisateurs (propriétaire, groupe et autres).

Le stickybit sert juste à éviter qu'un utilisateur ne détruise les fichiers des autres. On le fixe de la manière suivante :

Pour le mettre :
Code bash : Sélectionner tout
chmod a+t

Pour l'enlever :
Code bash : Sélectionner tout
chmod a-t

C'est aussi le 1 de la première position lorsque l'on utiliser un masque à quatre chiffres avec la notation octale de chmod.

Mis à jour le 23 octobre 2013 2Eurocents ok.Idriss

À l'aide des commandes grep et cut, on va extraire l'occurrence "/home/francois" du fichier /etc/passwd :

Code bash : Sélectionner tout
1
2
$ cat /etc/passwd | grep francois 
francois:x:502:502::/home/francois:/bin/zsh

La commande grep permet de ne conserver que la ligne contenant "francois" de la sortie standard de cat. Il est toutefois possible de parser directement le fichier avec grep :
Code bash : Sélectionner tout
$ grep "francois" /etc/passwd
Code bash : Sélectionner tout
1
2
$ grep "francois" /etc/passwd | cut -f6 -d: 
/home/francois

La commande cut permet de couper certains mots d'une ligne.
L'option -f6 indique que l'on veut garder la 6e chaîne de caractères, délimitée par le signe ":" (option - d).

Il est également possible d'utiliser le langage awk (avec l'interpréteur gawk par défaut sous Linux) pour faire des découpages similaires voire plus complexes avec des expressions régulières en guise de séparateurs notamment.

Exemple équivalent avec awk :
Code bash : Sélectionner tout
awk -F ":" '($0 ~ "francois"){print $6}' /etc/passwd

Vous remarquerez que dans cet exemple, on a pu également se passer de la commande grep.

Mis à jour le 23 octobre 2013 Francois Trazzi ok.Idriss

La commande find permet de faire le plus rapidement possible ce genre de traitement.

Pour afficher les fichiers vieux de plus de 24 heures :

Code bash : Sélectionner tout
$ find . -ctime +1

Pour les effacer :
Code bash : Sélectionner tout
$ find . -ctime +1 -exec rm -f  \{\} \;

L'option -i de la commande rm est utilisée pour demander une confirmation pour chaque fichier à effacer.

Mis à jour le 23 octobre 2013 nyal ok.Idriss

Ce caractère signifie que la commande sera exécutée en tâche de fond.
Ainsi vous aurez toujours accès au Shell pour exécuter d'autres commandes sur le terminal :

Code bash : Sélectionner tout
$ xmms &

Mis à jour le 23 octobre 2013 nyal ok.Idriss

Quand on lance une application depuis le terminal (xpdf, emacs...), on veut souvent reprendre la main sur ce même terminal, non ?

Mais on a oublié le "&" magique ! C'est terrible, il va falloir tout refermer pour tout réouvrir !

Eh bien non : imaginons le cas :

Code bash : Sélectionner tout
$ xpdf toto.pdf

Si on veut reprendre la main sans avoir à fermer, on revient sur le terminal, puis un petit Ctrl-Z histoire de geler le processus : là, on reprend la main. Et tout de suite derrière, on fait :
Code bash : Sélectionner tout
$ bg

Mis à jour le 23 octobre 2013 ok.Idriss Pouic

Il existe de nombreux programmes FTP en mode console.
Voici un exemple pour exécuter des commandes FTP automatiquement :

Code bash : Sélectionner tout
$ lftp -c "open nom_de_domaine ; user login password ; mput src destination ; ls"

Ou :
Code bash : Sélectionner tout
1
2
3
4
$ ncftp -u login -p passwd host << EOF 
get fichier 
ls 
EOF

Ces méthodes sont utilisées dans les scripts Shells (par cron notamment).

Mis à jour le 23 octobre 2013 nyal ok.Idriss

La commande screen permet de lancer des processus non graphiques, qui seront rattachés au processus init.

Ainsi, vous pourrez enlever votre programme de votre console et le rappelez quand vous le désirez. Pour cela, commençons par créer un screen :

Code bash : Sélectionner tout
screen -dmS nom_du_screen  'commande_a_lancer'


Vous entrez directement dans votre screen en lançant la commande. Pour détacher le screen de votre terminal :
Code : Sélectionner tout
CTRL+A CTRL+D


Pour attacher le screen à votre terminal :
Code bash : Sélectionner tout
screen -x nom_du_screen

Vous pouvez ainsi lancer un bash détachable de votre terminal et récupérable n'importe quand et n'importe où. Très pratique pour ne pas avoir beaucoup de fenêtres ouvertes ou quand on se connecte à distance à une machine de différents postes.

Les raccourcis clavier sont modifiables dans un fichier de configuration /etc/screenrc.

Mis à jour le 23 octobre 2013 Katyucha ok.Idriss

Code bash : Sélectionner tout
1
2
3
4
5
$ toto="bonjour le monde"  
$ echo ${toto:$((${#toto}-10))}  
r le monde 
$ echo ${toto: -10} # version plus simple 
r le monde
  • ${var:x} : extrait la sous chaîne de $var à partir caractère n° x jusqu'à la fin ;
  • $((....)) : permet de faire des calculs.

Mis à jour le 25 novembre 2013 narmataru ok.Idriss zipe31

1) Avec la commande seq :

Code bash : Sélectionner tout
1
2
3
for i in $(seq 1 10); do 
   # traitements itérés avec i allant de 1 à 10 
done
Attention, car si vous voulez générer de grosses listes avec cette méthode, n'oubliez pas que cela consomme de la mémoire... (toutes les valeurs sont calculées et conservées).

2) Autres solutions en bash :
Code bash : Sélectionner tout
1
2
3
4
5
6
7
for i in (( i=1 ; i<=10 ; i++ )); do 
   # traitements itérés avec i allant de 1 à 10 
done 
  
for i in {1..10}; do 
    # traitements itérés avec i allant de 1 à 10 
done

Mis à jour le 24 novembre 2013 alveric bobuse ok.Idriss

Lorsqu'on lance une commande avec le caractère & à la fin, la commande est lancée en tâche de fond mais reste rattachée à votre terminal. Vous pouvez continuer à travailler sur le terminal, mais si vous le quittez, la tâche de fond est détruite (rapport père/fils).

Si vous lancez une commande avec nohup en préfixe (exemple : nohup ma_tache.sh), alors votre tâche est détachée de son père et rattachée à l'init si vous quittez votre terminal...

Mis à jour le 23 octobre 2013 Katyucha ok.Idriss

Pour lire la première ligne d'un fichier uniquement :

Code bash : Sélectionner tout
1
2
read -r premiere_ligne < fichier 
echo "$premiere_ligne"

Ici, le contenu de « fichier » est redirigé vers la commande read, qui va placer ce qu'elle a lu dans une variable « $premiere_ligne ».

Pour lire tout le contenu du fichier, il est possible d'utiliser une boucle while :

Code bash : Sélectionner tout
1
2
3
while read -r ligne; do  
    echo "$ligne" 
done < fichier

Il est également possible de découper la ligne en autant de variables que nécessaire :

Code bash : Sélectionner tout
1
2
3
4
while read -r colonne1 colonne2 toutLeResteDeLaLigne; do  
   ligneComplete="$colonne1 $colonne2 $toutLeResteDeLaLigne" 
   echo "$ligneComplete" 
done < fichier

Si vous avez besoin de découper la ligne en fonction du formatage d'un fichier (CSV par exemple), vous pouvez modifier l'environnement de la commande read en adaptant l'IFS (Internal Field Separator):

Code bash : Sélectionner tout
1
2
3
4
while IFS=';' read -r colonne1 colonne2 toutLeResteDeLaLigne; do 
   ligneComplete="$colonne1;$colonne2;$toutLeResteDeLaLigne" 
   echo "$ligneComplete" 
done < fichier.csv

Vous pouvez également utiliser un tableau :

Code bash : Sélectionner tout
1
2
3
4
while IFS=';' read -ra tableau; do 
    ligneComplete="${tableau[@]}" 
    echo "$ligneComplete" 
done < fichier.csv

Vous pouvez enfin utiliser des paramètres positionnels :

Code bash : Sélectionner tout
1
2
3
4
5
6
while read -r ligne; do  
   IFS=';' 
   set -- $ligne # éclatement de la ligne en paramètres positionnels 
   echo "première colonne : $1" 
   echo "ligne complète : $@" 
done < fichier.csv

Mis à jour le 13 janvier 2014 N_BaH ok.Idriss

Voici une liste non exhaustive de redirections possibles, avec :

  • stdout: la sortie standard d'une commande ;
  • stderr: la sortie d'erreur d'une commande.


1) Rediriger stderr sur stdout :
Code bash : Sélectionner tout
commande 2>&1

Ceci aura pour effet de capturer les deux sorties en une, ce qui peut s'avérer utile si vous redirigez stdout dans un fichier par exemple :
Code bash : Sélectionner tout
1
2
3
$ commande >fichier 2>&1 
# ou 
$ commande 1>fichier 2>&1

Dans cet exemple, stdout et stderr seront toutes deux redirigées vers fichier.

2) Capturer uniquement la sortie stdout et éliminer la sortie stderr d'une commande :
Code bash : Sélectionner tout
$ commande 2>/dev/null

3) Capturer uniquement la sortie stderr et éliminer la sortie stdout
Code bash : Sélectionner tout
$ commande 2>&1 1>/dev/null

4) Éliminer stdout et stderr :
Code bash : Sélectionner tout
1
2
3
$ commande >/dev/null 2>&1 
# ou 
$ commande 1>/dev/null 2>&1

5) Fusionner stdout et stderr pour capturer stderr et renvoyer stdout vers l'ancien stderr :
Code bash : Sélectionner tout
$ commande 3>&1 1>&2 2>&3 3>&-

6) Capturer les sorties stdout et stderr d'une commande dans des fichiers distincts :
Code bash : Sélectionner tout
$ commande [args] 1>commande.out 2>commande.err

7) Rediriger stdout et stderr au même endroit mais en ajoutant le préfixe « Err » aux erreurs :

Code bash : Sélectionner tout
$ commande 2> >(sed 's/^/Err : /' >&2)

8) Rediriger stderr vers stdout et ajouter le résultat de stdout dans un fichier tout en continuant de l'afficher sur la sortie standard :

Code bash : Sélectionner tout
commande 2>&1 | tee fichier

Mis à jour le 27 novembre 2013 hornetbzz lennelei ok.Idriss

La boucle for s'effectue sur une liste de valeur :

Code bash : Sélectionner tout
1
2
3
for var in val1 val2 ...; do 
    # ... 
done

Par conséquent lorsque vous écrivez :

Code bash : Sélectionner tout
1
2
3
for var in $(commande); do 
    # ... 
done

Vous parcourez la sortie de commande « mot par mot » et non « item par item ». Cela peut être source d'erreur notamment lorsqu'un item est composé d'espaces.

Vous trouverez ici des exemples d'erreurs engendrés par cette syntaxe.

Une solution consiste à parcourir la sortie de la commande « ligne par ligne » grâce à cette syntaxe :

Code bash : Sélectionner tout
1
2
3
commande|while read -r; do 
    # la variable $REPLY contient la ligne parcourue 
done

D'autres syntaxes sont possibles :

Code bash : Sélectionner tout
1
2
3
4
5
6
7
8
9
while read -r; do 
    # la variable $REPLY contient la ligne parcourue 
done < <(commande) 
  
# ou 
  
while read -r; do 
    # la variable $REPLY contient la ligne parcourue 
done <<< "$(commande)" # les doubles quotes sont importantes ici

Vous pourrez voir dans ce cours, qu'il y a toujours moyen d'éviter la boucle for sur une sortie de commande.

Mis à jour le 13 janvier 2014 ok.Idriss

La commande ls est généralement superflue dans les scripts voire potentiellement génératrice de bogues (dans le cas où on l'utilise avec une boucle for par exemple).

Pour parcourir les fichiers d'un répertoire, il suffit d'utiliser le métacaractère « * » (wildcard) :

Code bash : Sélectionner tout
1
2
3
for fichier in *; do 
    # ... 
done

Il est également possible de se servir de la wildcard comme vous le feriez avec les commandes find, ls ou autres :

Code bash : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
# préciser une extension 
for fichier in *.log; do 
    # ... 
done 
  
# préciser un chemin de répertoire à parcourir 
dir="/home/votre_nom/rep" 
for fichier in "$rep"/*; do 
    # ... 
done 
  
# ...

Pour récupérer des informations sur un fichier, vous pouvez utiliser la commande stat qui est prévue pour cela. Exemple pour récupérer les droits d'un fichier :

Code bash : Sélectionner tout
1
2
3
stat -c "%A" fichier  
# au lieu de 
ls -l fichier|cut -d" " -f1

Mis à jour le 27 novembre 2013 ok.Idriss

Vous souhaitez trouver dans quels fichiers se trouve la chaine "CHAINE", lister leur chemin (relatif à notre position), et afficher les lignes contenant cette chaine de caractères.

Pour cela, vous pouvez utiliser un grep récursif :

Code bash : Sélectionner tout
$ grep -Rn "CHAINE" repertoire/

Avec les couleurs si votre version de grep et votre configuration le permettent :

Code bash : Sélectionner tout
$ grep --color -Rn "CHAINE" repertoire/

Il est possible d'utiliser la commande find si on veut effectuer la recherche avec des conditions plus strictes. Dans cet exemple, on recherche les fichiers *.sh dont vous êtes l'utilisateur propriétaire et qui sont exécutables :

Code bash : Sélectionner tout
$ find repertoire/ -type f -user nom_user -perm /u+x -name "*.sh" -exec grep --color -Hn "CHAINE" {} 2>/dev/null \;

Mis à jour le 6 décembre 2013 hornetbzz ok.Idriss

De manière générale, il faut encadrer les variables par des doubles quotes dans ses scripts, notamment lorsque l'on utilise la commande test ou son fork [ afin d'éviter ce genre d'erreurs.

Ceci ne s'applique pas lorsque l'on utilise la syntaxe Bash des doubles crochets [[ (commande test étendue).

Mis à jour le 13 janvier 2014 ok.Idriss

La commande qui va suivre vous permettra de supprimer tous les fichiers dans le dossier courant prototypé de la sorte :

- fichier.o
- fichier.extension~
- #fichier.extension#

Voici la commande :

Code bash : Sélectionner tout
find . -name '*~' -print -delete -o -name '#*#' -print -delete

Cela vous permettra de nettoyer vos dossiers.

Mis à jour le 22 octobre 2015 Aooka

Pendant l'exécution d'un script, il peut arriver qu'on ait besoin de demander des informations à un utilisateur ; qu'il s'agisse d'une simple confirmation (continuer [Yn] :), ou d'une donnée plus large (quel est le chemin du fichier à traiter), il est question de lire des données depuis l'entrée standard avec la commande read.

Code bash : Sélectionner tout
read -p 'continuer [Yn] : '


Le script semble figé, mais, en fait, il attend que l'utilisateur valide le texte qu'il a entré en appuyant sur la touche Enter.

L'invite affichée par l'option -p est envoyée sur la sortie d'erreur.

Cela signifie que lorsque cette dernière est renvoyée vers un fichier journal, l'invite ne sera plus visible.
Il peut alors être préférable d'omettre cette option, et de faire un echo de l'invite sur la sortie standard, bien sûr.

Comme pour lire un fichier ligne par ligne, il est possible de demander à l'utilisateur d'entrer des données sous forme d'un tableau.
Il faut que l'utilisateur respecte un certain format :

Code bash : Sélectionner tout
1
2
3
4
5
6
7
  
$ read -a tableau 
'mlk mlk' poi 
$ printf '-> %s\n' "${tableau[@]}" 
-> 'mlk 
-> mlk' 
-> poi


Il faut donc protéger le séparateur par défaut :

Code bash : Sélectionner tout
1
2
3
4
5
$ read -a tableau 
mlk\ mlk poi 
$ printf '-> %s\n' "${tableau[@]}" 
-> mlk mlk 
-> poi


On peut définir un séparateur avec l'IFS (Internal Field Separator) :

Code bash : Sélectionner tout
1
2
3
4
5
$ IFS=';' read -a tableau 
mlk mlk;poi 
$ printf '-> %s\n' "${tableau[@]}" 
-> mlk mlk 
-> poi

Mis à jour le 23 août 2018 N_BaH

Par défaut, grep retourne uniquement les lignes correspondant à la recherche effectuée. Toutefois, il est aussi possible d'afficher un nombre de lignes avant et après les lignes concernées par la recherche grâce aux options :

  • -B NUM : pour afficher NUM lignes avant la ligne concernée ;
  • -A NUM : pour afficher NUM lignes après la ligne concernée ;
  • -C NUM : pour afficher NUM lignes avant et après la ligne concernée.

Ces lignes autour de la ligne concernée sont appelée le "contexte" du résultat.

Mis à jour le 27 juin 2022 LittleWhite

Proposer une nouvelle réponse sur la FAQ

Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour ça


Réponse à la question

Liens sous la question
précédent sommaire suivant
 

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2024 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.