Debian Le livre s’appelle Debian mais la majorité des articles peuvent s'appliquer sur d'autres distribution linux. J'utilise juste principalement Debian d'où le nom. Les Bases Base de Bash Shell Sous Linux, un shell est l’interpréteur de commandes qui fait office d’interface entre l'utilisateur et le système d’exploitation. Il s’agit d’interpréteurs, cela implique que chaque commande saisie par l’utilisateur et vérifiée puis exécutée. Nous avons déjà parlé des différents types de shell existants (csh, tcsh, sh, bash, ksh, dash, etc.). Nous travaillerons plus avec le bash (Bourne Again SHell). Pour rappel, un shell possède deux principaux aspects : Un aspect environnement de travail Un aspect langage de programmation L’environnement L’environnement de travail d’un shell doit être agréable et puissant (rappel CLI GUI), bash permet entre autres choses de : Rappeler des commandes précédentes (historique) Modifier en ligne du texte de la commande courante (bi, emacs, nano) Gestion des travaux lancés en arrières-plan (jobs) Initialisation adéquate des variables de configuration (chaîne d’appel de l’interpréteur, chemins de recherche par défaut) Pour illustrer ça, voyons que le shell permet d’exécuter une commande en mode interactif ou bien par l’intermédiaire de fichiers de commandes (scripts). En mode interactif, bash affiche à l’écran une chaîne d’appel (appelée prompt ou invite) qui se termine par défaut par le caractère # pour l’administrateur (root), et par le caractère $ pour les autres utilisateurs. Sous windows le prompt est souvent le nom du chemin où l’on se trouve, suivis de > , par exemple : “C:\Windows\System32>” Un langage de programmation Les shells ne sont pas uniquement des interpréteurs de commandes mais de véritables langages de programmation, un shell comme le bash intègre : les notions de variables les opérateurs arithmétiques les structures de contrôle les fonctions etc. Par exemple : $ mavariable=5 #=> affectation de la valeur 5 dans la variable qui a pour nom “mavariable” $ echo $((mavariable +3)) #=> affiche la valeur de l’expression mavariable 8 Avantages et inconvénients des shells L’étude d’un shell comme le bash dispose de plusieurs avantages : langage interprété, il est facile de trouver les erreurs et de les traiter modification rapide sans besoin de recompiler langage orienté chaîne de caractères (pas de pointeurs), moins de risque d’avoir des erreurs d’adressage. prototypage rapide d’application, il est facile de composer des programmes avec les commandes existantes et l’utilisation des tubes et substitution dans l’environnement Unix langage “glu”: on peut connecter des composants écrits dans des langages différents. Ils doivent juste respecter certains standards : lire sur l’entrée standard accepter des arguments et options éventuels, écrire ses résultats sur la sortie standard écrire les messages d’erreurs sur la sortie dédiée au erreur. Voyons maintenant certains inconvénients des shells : La syntaxe est “ésotérique” et d’accès difficile pour les débutants Suivant le contexte, l’ajout ou l’oubli d’un espace peut provoquer des erreurs de syntaxe ou de traitement Plusieurs syntaxes pour implanter la même fonctionnalité (principalement à cause de la compatibilité ascendante avec le Bourne Shell Le sens de certains caractères spéciaux, comme les parenthèses, change avec le contexte, elle peuvent définir : une liste de commandes une définition de fonction imposer un ordre d’évaluation une expression arithmétique Si vous voulez connaître le shell qui tourne actuellement, utilisez la commande ps, et si vous voulez connaître la version du bash : bash -- version Variables Ils existent différents types de variables utilisables dans le shell. Elles sont identifiées par un nom (suite de lettres, chiffres, caractères espace ou souligné ne commençant pas par un chiffre. la casse est gérée). On peut classer 3 groupes de variables : utilisateurs (ex: a, valeur) prédéfinies par le shell (ex; PS1, PATH, REPLY, IFS, HOME) prédéfinies pour les commandes unix (ex: TERM) Pour affecter une variable, on peut utiliser l’opérateur = ou bien la commande interne read (pour demander une saisie utilisateur) Les variables locales : Elles ne sont disponibles que dans l’instance du shell dans lesquelles elles ont été créées. (Elles ne sont pas utilisées par les commandes dans ce shell). Par défaut une variable est créée en tant que variable locale, on utilise couramment des lettres minuscules pour nommer ses variables locales. Exemple :  mavariablelocale = 1 Les constantes : Une constante est une variable en lecture seul d’une certaine manière, elle n’a pas pour but d’être modifié dans le programme (d’où son nom). Pour créer une constante, vous pouvez utiliser la commande declare -r. Exemple:  declare -r pi=3.14159 Les variables d’environnement : Les variables d’environnement existent dans le shell pour lequel elles sont créées, mais aussi pour toutes les commandes qui sont utilisées dans ce shell. On utilise couramment des majuscules pour nommer ses variables d’environnement. Exemple1 : #Transformer une variable ENVVAR=10 #Création d’une variable locale export ENVVAR #Transforme la variable locale en variable d’environnement Exemple 2: # Créer une variable d’environnement export ENVVAR2 = 11 # Première solution declare -x ENVVAR3 = 12 # Deuxième solution typeset -x ENVVAR4 = 13 # Troisième solution Commandes utiles pour les variables : echo : Vous pouvez utiliser la commande echo si vous souhaitez connaître le contenu d’une variable. Exemple :  echo $PATH permettra d’afficher le contenu de la variable d’environnement PATH qui contient les chemins de fichier de commande dans le shell. $ set param1 param2 $ echo $1 param1 $ set -- $ echo $1 $ #on a perdu les valeurs Pour connaître le nombre de variables de position, il existe une variable spéciale $# shift : permet de décaler les variables de position (sans toucher au $0) $ set a b c d e f g h i j # param 1 2 3 4 5 6 7 8 9 $ echo $1 $2 $# a b 9 $ shift 2 # variable deviennent c d e f g h i j $ echo $1 $2 $# c d 7 L’utilisation du shift sans argument équivaut à faire un  shift 1 unset : permet de supprimer une variable $ set myvar=1 $ echo $myvar 1 $ unset myvar $ echo $myvar $ Mon premier bash #!/bin/bash echo “Nom du programme : $0” echo “Nombre d’arguments : $#” echo “Source : $1” echo “Destination $2” cp $1 $2 $ chmod u+x monpremierbash.sh $ $ monpremierbash.sh /etc/passwd /root/copiepasswd Nom du programme : ./monpremierbash.sh Nb d’arguments : 2 Source : /etc/passwd Destination : /root/copiepasswd $ $ set un deux trois quatre $ $ echo $* # affiche tous les arguments un deux trois quatre $ echo $@ # affiche tous les arguments un deux trois quatre $ set un “deux trois” quatre # testons avec 3 paramètres et des guillemets $ set “$*” # équivalent à set “un deux trois quatre” $ echo $# 1 $ echo $1 un deux trois quatre $ set un “deux trois” quatre # testons $@ avec 3 paramètres et des guillemets $ set “$@” # équivalent à set “bonjour” “deux trois” “quatre” $ echo $# 3 $ echo $2 deux trois Si dans un bash on souhaite supprimer les ambiguïtés d’interprétation des paramètres de position, on utilise le ${paramètre}, comme dans l’exemple suivant. Exemple : $ x=bon $ x1=jour $ echo $x1 jour $ echo ${x}1 bon1 $ set un deux trois quatre cinq six sept huit neuf dix onze douze $ echo $11 un1 $ echo ${11} onze Indirections Bash offre la possibilité d’obtenir la valeur d’une variable v1 dont le nom est contenu “v1” dans une autre variable mavar. Il suffit pour cela d’utiliser la syntaxe de substitution : ${!mavar}. Exemple : $ var=v1 $ v1=un $ $ echo ${!var} un $ Ce mécanisme, appelé indirection,permet d’accéder de manière indirecte et par conséquent de façon plus souple, à la valeur d’un deuxième objet. Voyons un autre exemple d’utilisation : Exemple d’un fichier indir: #!/bin/bash agePierre=10 ageJean=20 read -p “Quel âge (Pierre ou Jean) voulez-vous connaître ? “ prenom rep=age$prenom #construction du nom de la variable echo ${!rep} $ indir Quel âge (Pierre ou Jean) voulez-vous connaître ? Pierre 10 $ indir Quel âge (Pierre ou Jean) voulez-vous connaître ? Jean 20 $ Ce mécanisme s’applique également aux deux autres types de paramètres : les paramètres de position et les paramètres spéciaux ($1, $2, , ...) Résultats, Code de retour et opérateur sur les code de retour Il ne faut pas confondre le résultat d’une commande et son code de retour : le résultat correspond à ce qui est écrit sur sa sortie standard; le code de retour indique uniquement si l’exécution de la commande s’est bien effectuée ou non. Parfois, on est intéressé uniquement par le code de retour d’une commande et non par les résultats qu’elle produit sur la sortie standard ou la sortie d’erreur. Exemple : $ grep toto pass > /dev/null 2>&1 #=> ou bien : grep toto pass &>/dev/null $ $ echo $? 1 #=> on en déduit que la chaîne toto n’est pas présente dans pass Les opérateurs && et || autorisent l’exécution conditionnelle d’une commande cmd suivant la valeur qu’a pris le code de retour de la dernière commande précédemment exécutée. Exemple pour && : $ grep toto pass > /dev/null 2>&1 #=> ou bien : grep toto pass &>/dev/null $ $ echo $? 1 #=> on en déduit que la chaîne toto n’est pas présente dans pass La chaîne de caractères daemon est présente dans le fichier pass, le code de retour renvoyé par l’exécution de grep est 0; par conséquent, la commande echo est exécutée. Exemple pour || : $ ls pass tutu ls : impossible d’accéder à tutu: Aucun fichier ou dossier de ce type pass $ rm tutu || echo tutu non effacé rm : impossible de supprimer tutu: Aucun fichier ou dossier de ce type tutu non effacé $ Le fichier tutu n’existant pas, la commande rm tutu affiche un message d’erreur et produit un code de retour différent de 0; la commande interne echo est exécutée. Exemple combiné || et || : $ ls pass || ls tutu || echo fin aussi pass $ Le code de retour ls pass est égal à 0 car pass existe, la commande ls tutu ne sera pas exécutée. D’autre part le code de retour de l’ensemble ls pass || ls tutu est le code de retour de la dernière commande exécutée, c’est-à-dire 0 (ls pass). donc echo fini aussi n’est pas exécutée. Exemple combiné && et || : $ ls pass || ls tutu || echo suite et && echo fin pass fin $ la commande ls pass a un code de retour égal à 0, donc la commande ls tutu ne sera pas exécutée; le code de retour de l’ensemble ls pass || ls tutu sera donc égal à 0. la commande echo suite et n’est pas exécutée donc le code de retour de l’ensemble reste 0 echo fin sera donc exécutée. Boucles et structure de contrôle case, structure de choix multiple Syntaxe : case mot in [modele [ | modele] ...) suite de commandes ;; ] ... esac Le shell va étudier la valeur de mot puis la comparer séquentiellement à chaque modèle. Quand un modèle correspond à mot, la suite de commandes associée est exécutée, terminant l’exécution de la commande interne case. Les mots case et esac sont des mots-clés; ils doivent être le premier mot d’une commande. suite de commandes doit se terminer par 2 caractères ; collés de manière à ce qu’il n’y ait pas d’ambiguïté avec l’enchaînement séquentiel de commande cmd1; cmd2; etc. Quand au modèle , il peut-être construit à l’aide de caractères et expressions génériques de bash (*, . , [], etc.). Dans ce contexte le symbole | signifiera OU. Pour indiquer le cas par défaut (si aucun des autres ne survient) on utilisera le modèle *. il doit être placé en dernier modèle. Le code de retour de la commande composée case est égal à 0, si aucun modèle n’a pu correspondre à la valeur de mot. Sinon, c’est celui de la dernière commande exécutée de suite de commandes. Exemple 1: Programme shell oui affichant OUI si l’utilisateur a saisi le caractère o ou O #!/bin/bash read -p “Entrez votre réponse : “ rep case $rep in o|O ) echo OUI ;; * ) echo Indefini esac Exemple 2 : Programme shell nombre prenant une chaîne de caractères en argument, et qui affiche cette chaîne si elle est constituée d’une suite de chiffres. ([:digit:] , [:upper:], [:lower:], [:alnum:] #!/bin/bash # on autorise l’utilisation des expressions générique shopt -s extglob case $1 in +([[:digit:]]) ) echo ′′$1 est une suite de chiffres′′ ;; esac Exemple 3 : Si l’on souhaite ignorer la casse on peut modifier le flash de shopt #!/bin/bash read -p “Entrez un mot : “ mot shopt -s nocasematch case $mot in oui ) echo ′′Vous avez écrit oui” ;; * ) echo “$mot n’est pas le mot oui” ;; esac While La commande interne while correspond à l’itération ‘faire - tant que’ présente dans de nombreux langage de programmation. Syntaxe : while suite_cmd1 do suite_cmd2 done La suite de commandes suite_cmd1 est exécutée, si son code de retour est égal à 0, alors la suite de commande suite_cmd2 est exécutée, puis suite_cmd1 est re-exécutée. Si son code de retour est différent de 0, la suite se termine. L’originalité de cette méthode est que le test ne porte pas sur une condition booléenne, mais sur le code de retour issu de l’exécution d’une suite de commandes. Une commande while, comme toutes commandes internes, peut être écrite directement sur la ligne de commande. Exemple : $ while who | grep root> /dev/null > do > echo “Utilisateur root est connecté” > sleep 5 > done Utilisateur root est connecté Utilisateur root est connecté Utilisateur root est connecté ^C $ Commande interne while est : La commande interne : associée à une itération while compose rapidement un serveur (démon) rudimentaire. Exemple : $ while : #=> Boucle infinie > do > who | cut -d’ ‘-f1 > fic #=> Traitement à effectuer > sleep 300 #=> Temporiser > done & [1] 1123 #=> pour arrêter l’exécution kill -15 1123 $ On peut parfois utilisée la commande while pour lire un fichier texte. La lecture se fait alors ligne par ligne. Pour cela, il suffit de : placer la commande read dans suite_cmd1 de placer les commandes de traitement de la ligne courante dans suite_cmd2 de rediriger l’entrée standard de la commande while avec le fichier lire Syntaxe : while read [var1 ...] do Commandes de traitements done < fichier à lire Exemple : #!/bin/bash who > tmp while read nom divers do echo $nom done < tmp rm tmp Notez que l’utilisation du while pour lire un fichier n’est pas très performante. On préférera en général utiliser une suite de filtre pour obtenir les résultats voulus (cut, awk, ...) Modificateur de chaîne Échappement Différents caractères particuliers servent en shell pour effectuer ses propres traitements ($ pour la substitution, > pour la redirection, * en joker). Pour utiliser ces caractères particuliers en tant que simple caractère, il faut les échapper en les précédant du caractère \ Exemple : $ ls tata toto $ echo * tata toto $ echo \* * $ echo \\ \ $ Autre particularité, le caractère \ peut aussi échapper les retours à la ligne. On peut donc aller à la ligne sans exécuter la commande. Comme nous l’avons déjà vu, les caractères “ et ‘ permettre une protection partielle, ou total (‘) d’une chaîne de caractères. Exemple : $ echo “< * $PWD ‘ >” < * /root ‘ > $ $ echo “\”$PS2\”” “> “ $ echo ‘< * $PWD “ >’ < * $PWD “ >’ $ echo c’est lundi > > ‘ cest lundi $ echo c\’est lundi c’est lundi $ echo “c’est lundi” c’est lundi Chaîne de caractères longueur Syntaxe :  ${#paramètre} Cette syntaxe permet d’obtenir la longueur d’une chaîne de caractères. Exemple : $ echo $PWD /root $ echo ${#PWD} 5 $ set “Bonjour à tous” $ echo ${#1} 14 $ ls > /dev/null $ $ echo ${#?} 1 #=> la longueur du code de retour (0) est de 1 caractère Chaîne de caractères modificateur On peut modifier les chaîne de caractères directement : Syntaxe : ${paramètre#modèle} pour supprimer la plus courte sous-chaîne à gauche Exemple : $ echo $PWD /home/christophe $ echo ${PWD#*/} home/christophe #=> le premier caractère / a été supprimé $ $ set “25b75b” $ $ echo ${1#*b} 75b #=> Suppression de la sous-chaîne 25b Syntaxe:  ${paramètre##modèle} pour supprimer la plus longue sous-chaîne à gauche Exemple : $ echo $PWD /home/christophe $ echo ${PWD##*/} christophe #=> suppression jusqu’au dernier caractère / $ $ set “25b75b” $ $ echo ${1##*b} b Pour la suppression par la droite, c’est la même chose en utilise le caractère % comme contrôle Syntaxe : ${paramètre%modèle} pour supprimer la plus courte sous-chaîne à droite ${paramètre%%modèle} pour supprimer la plus longue sous-chaîne à droite On peut extraire une sous-chaîne également : Syntaxe: ${paramètre:ind} : extrait la valeur de paramètre de la sous-chaîne débutant à l’indice ind. ${paramètre:ind:nb} : extrait nb caractères à partir de l’indice ind Exemple : $ lettres=”abcdefghijklmnopqrstuvwxyz” $ $ echo {$lettre:20} uvwxyz $ echo {$lettre:3:4} defg $ Remplacement dans une sous-chaîne Syntaxe: ${paramètre/mod/ch} bash recherchera dans paramètre la plus longue sous-chaîne satisfaisant le modèle mod puis remplacera cette sous-chaîne par la chaîne ch. Seule la première sous-chaîne trouvée sera remplacée. mod peut être des caractères ou expressions génériques. ${paramètre//mod/ch} : Pour replacer toutes les occurrences et pas seulement la première ${paramètre/mod/} : ${paramètre//mod/} : Supprime au lieu de remplacer Exemple : $ v=totito $ echo {$v/to/lo} lotito $ echo {$v//to/lo} lotilo Structure de contrôle for et if Itération et for Syntaxe 1: for var do suite_de_commandes done Syntaxe 2: for var in liste_mots do suite_de_commandes done Dans la première forme, la variable var prend successivement la valeur de chaque paramètre de position initialisé Exemple : $ cat for_args.sh #!/bin/bash for i do echo $i echo “next ...” done $ ./for_args.sh first second third first next ... second next ... third next ... Exemple 2: $ cat for_set.sh #!/bin/bash set $(date) for i do echo $i done $ ./for_set.sh samedi 29 Juin 2019, 12:09:21 (UTC+0200) $ La deuxième syntaxe permet à var de prendre successivement la valeur de chaque mot de liste_mots. Exemple : $ cat for_liste.sh #!/bin/bash for a in toto tata do echo $a done Si liste_mots contient des substitutions, elles sont préalablement traitées par bash Exemple 2: $ cat affiche_ls.sh #!/bin/bash for i in /tmp ${pwd} do echo “ --- $i ---” ls $i done $ ./affiche_ls.sh --- /tmp --- toto tutu --- /home/christophe for_liste.sh affiche_ls.sh alpha tmp If et le choix La commande interne if implante le choix alternatif Syntaxe : if suite_commande1 then suite_commande2 [elif suite_de_commandes; then suite_de_commande] ... [else suite_de_commandes] fi Le principe de fonctionnement est le même que pour le for, on test la valeur de retour d’une commande plutôt qu’une valeur booléenne simple. Donc dans notre exemple, suite_commande2 est exécuté, si suite_commande1 renvoi 0 (pas d’erreur). Sinon c’est elif ou bien else qui sera exécuté. Exemple : $ cat rm1.sh #!/bin/bash if rm “$1” 2> /dev/null then echo $1 a été supprimé else echo $1 n\’a pas été supprimé fi $ >toto $ rm1 toto toto a été supprimé $ $ rm1 toto toto n’a pas été supprimé $ Lorsque rm1 toto est lancé, si le fichier toto est effaçable, il le sera, et la commande rm renvoi 0. Notez qu’il est possible d’imbriquer les if ensembles Exemple : if... then.... if... then ... fi else ... fi Tests Dans les bash, vous retrouverez souvent une notation de commande interne [[ souvent utilisé avec le if. Elle permet l’évaluation de d’expressions conditionnelles portant sur des objets aussi différents que les permissions sur une entrée, la valeur d’une chaîne de caractères ou encore l’état d’une option de la commande interne set. Syntaxe:  [[ expr_conditionelle ]] Les deux caractères crochets doivent être collés et un caractère séparateur doit être présent de part et d’autre de expr_conditionelle. Les mots [[ et ]] sont des mots-clés. On a vu que le if fonctionne selon la valeur de retour d’une commande, et pas d’un booléen, cette syntaxe permet “d'exécuter un test” qui renverra 1 si le test est vrai, 0 sinon. Si l’expression contient des erreurs syntaxique une autre valeur sera retournée. La commande interne [[ offre de nombreuses expressions conditionnelles, c’est pourquoi seules les principales formes de exp_conditionnelle seront présentées, regroupées par catégories. Permission -r entrée vraie si entrée existe et est accessible en lecture par le processus courant -w entrée vraie si entrée existe et est accessible en écriture par le processus courant -x entrée vraie si entrée existe et est accessible en exécutable par le processus courant ou si le répertoire entrée existe et le processus courant possède la permission de passage Exemple : $ echo coucou > toto $ chmod 200 toto $ ls -l toto --w- --- --- 1 christophe christophe 29 juin 1 14:04 toto $ $ if [[ -r toto ]] > then cat toto > fi $ => rien ne ce passe $ echo $? 0 => code de retour de la commande interne if $ MAIS $ [[ -r toto ]] $ echo $? 1 => code de retour de la commande interne [[ $ Type d’une entrée -f entrée vraie si entrée existe et est un fichier ordinaire -d entrée vraie si entrée existe et est un répertoire Exemple : $ cat afficher.sh #!/bin/bash if [[ -f “$1” ]] then echo “$1” : fichier ordinaire cat “$1” elif [[ -d “$1” ]] then echo “$1” : répertoire ls “$1” else echo “$1” : type non traité fi $ ./afficher . : répertoire afficher.sh test.sh toto alpha rm1.sh $ Renseignement divers sur une entrée -a entrée vraie si entrée existe -s entrée vraie si entrée existe et sa taille est différente de 0 (un répertoire vide > 0) entrée 1 -nt entrée 2 vraie si entrée 1 existe et sa date de modification est plus récente que celle de entrée2 entrée1 -ot entrée 2 vraie si entrée1 existe et sa date de modification est plus ancienne que celle de entrée2 Exemple : $ > err $ $ ls -l err -rw-rw-r-- 1 christophe christophe 0 juin 29 14:30 err $ if [[ -a err ]] > then echo err existe > fi err existe $ if [[ -s err ]] > then echo err n’est pas vide > else err est vide > fi err est vide $ Longueur d’une chaîne de caractère -Z ch vraie si la longueur de ch est égale à 0 ch ou (-n ch) vraie si la longueur de ch est différente de 0 ch1 < ch2 vraie si ch1 précède ch2 ch1 > ch2 vraie si ch1 suit ch2 ch == mod vraie si la chaîne ch correspond au modèle mod ch != mod vraie si la chaîne ch ne correspond pas au modèle mod -o opt vraie si l’option interne opt est sur on Important : il existe un opérateur =~ qui permet de mettre en correspondance une chaîne de caractères ch avec une expression régulière. Exemple : $a=01/01/2010 $[[ $a =~ [0-9]{2}\/[0-9]{2}\/[0-9]{2,4} ]] $ echo $? 0 $ a=45/54/1 $[[ $a =~ [0-9]{2}\/[0-9]{2}\/[0-9]{2,4} ]] $ echo $? 1 Expressions conditionnelles ( cond ) vraie si cond est vraie ! cond vraie si cond est fausse cond1 && cond 2 vraie si cond1 et 2 sont vraie, l’évaluation s’arrête si cond1 est fausse cond1 || cond2 vraie si cond1 ou 2 sont vraie. Exemple : $ ls -l /etc/at.deny -rw-r----- 1 root daemon 144 oct. 25 2018 /etc/at.deny $ $ if [[ ! ( -w /etc/at.deny || -r /etc/at.deny ) ]] > then > echo OUI > else > echo NON > fi OUI Processus Une commande sous linux crée un processus en mémoire, ce processus est sous la responsabilité du kernel. Tous les traitements effectués par une commande sont en fait traitées par le processus qui est créé lors de l'exécution de cette commande. Un processus est exécuté (en général) par un utilisateur, il disposera donc des mêmes droits que l’utilisateur qui est responsable de son exécution. Et en général, un utilisateur ne pourra pas agir sur un processus lancé par un autre utilisateur, exception faite de root, évidemment. La commande qui permet de lister les processus est PS : PID : Numéro du processus (unique) TTY : Nom du terminal dans lequel se trouve le processus TIME : Le temps processeur utilisé par le processus CMD : La commande qui a créé le processus On peut déduire de cet exemple, qu’une même commande peut créer plusieurs processus. Avec la commande ps x on peut voir dans quel état sont les processus S: en sommeil D : Sommeil irréversible R : En cours d’exécution T : Stoppé Z : Zombie (processus terminé, mais pas encore totalement libéré) Pour l’instant, on ne visualise que les processus de l’utilisateur, pour obtenir la liste complète, on va utiliser plutôt la commande : ps -ef (-e tous les processus, et -f pour full détails) Processus Foreground Lorsque vous exécutez une commande comme ps -ef | less, le processus créé est foreground ou d’avant-plan. C’est-à-dire que le shell est bloqué durant l'exécution de la commande. L’utilisateur n’a donc plus la possibilité de faire autre chose. C’est pratique si le traitement est court, mais pas bon du tout si le traitement est long et coûteux en ressource. Lorsqu'un processus a besoin de lancer un autre processus pour ses traitements, le premier processus est appelé processus parent et le ou les processus créés par le parent sont appelés processus enfant. Lorsqu’un parent lancé en foreground crée un enfant, le processus enfant bloquera le parent jusqu’à la fin de ses traitements, puis à sa mort, le parent reprendra le relais. Par exemple, le bash est un processus. Quand on lance une commande dans le bash, le processus parent bash est bloqué jusqu’à la fin des traitements de son processus enfant (par exemple le ls) Si vous voulez éviter de bloquer le shell (ou le parent). Il est possible de lancer une commande en tâche de fond, dans ce cas, l’enfant rendra immédiatement les droits de continuer les opérations au parent, tout en continuant de faire ses traitements. Pour se faire, on utilisera le caractère &, Déplacer un processus Si l’on fait un script, dont une commande demande à dormir 10.000 secondes, mais malheureusement, j’ai oublié de demander à la commande du script de se lancer en tâche de fond - Le ctrl+z permet d'interrompre le processus (suspend) - on fait la commande bg, qui passe le processus en tâche de fond - on le remet en foreground avec la commande fg - le ctrl+c permet de lancer une interruption logiciel qui envoi un SIGTERM au processus en foreground Si vous voulez connaître la liste des jobs en cours de traitement, vous pouvez utiliser la commande jobs Signaux Un signal est un message envoyé à un processus pour altérer son état (par exemple stop, start, pause) Certains signaux peuvent s’envoyer avec un raccourcis clavier (ctrl+z stoppe un processus) Pour consulter la liste des signaux, kill -l Donc la commande kill permet d’envoyer un signal à un processus de plusieurs façons : - Kill -2 → envoi le signal 2 (SIGINT) à un processus - Kill -SIGINT → envoi le signal SIGINT à un processus Le SIGINT est l’équivalent du CTRL+Z (stoppe le processus mais ne le détruit pas) Pour tuer (détruire) un processus, on utilisera plutôt le SIGTERM (15) Killall - tuer un processus par user La commande killall -u permet de demander à tuer tous les processus appartenant à un utilisateur. killall -u root Supprimera tous les processus lancés par le compte root. Conserver un processus en quittant Quand un utilisateur se déconnecte de sa session, tous les processus rattachés à l’utilisateur reçoivent un SIGHUP (1) qui va finalement tuer tous les processus rattachés. Si l’opération de sauvegarde est très longue et que l’administrateur doit se déconnecter, sa sauvegarde s’arrêtera par exemple. Pour éviter ce phénomène, on utilisera la commande nohup Priorité d’un processus Un processus a besoin de temps processeur pour faire ses calculs. Certains d’entre eux ont droits à plus de CPU que d’autres, ceci se règle avec un mécanisme de priorité. Les processus lancés par le système auront en général plus de priorité que les autres. C’est le kernel qui s’occupe d’ajuster dynamiquement la priorité et essaie de fournir les bonnes priorités selon les besoins. L’utilisateur pourra influencer dans une certaines mesure cette priorité en faisant varier une valeur de “gentillesse” niceness ! niceness -20 => Donne la priorité la plus haute possible niceness 0 => valeur par défaut niceness 19 => priorité la plus basse Un utilisateur standard aura le droit de régler l’indice entre 19 et 0. Seul le root peut faire des réglages entre -1 et -20. Pour affecter un indice de gentillesse, on utilise la commande nice avec l’option -n (régler la gentillesse) et une valeur. Sudo Sudo (Parfois considéré comme l'abréviation de Super-user do) est un programme dont l'objectif de permettre à l'administrateur du système d'autoriser certains utilisateurs à exécuter des commandes en tant que superutilisateur (ou qu'un autre utilisateur). La philosophie qui sous-tend cela est de donner aussi peu que possible de droits, mais de permettre quand même aux utilisateurs de faire leur travail. Sudo est aussi un moyen efficace d'enregistrer qui a exécuté quelle commande et quand.  Notes pour les nouveaux utilisateurs de Debian Certains nouveaux utilisateurs de Debian, venant généralement de Ubuntu, sont choqués par les problèmes du type : « sudo ne fonctionne pas dans Debian ». Cette situation n'arrive cependant que si vous avez configuré un mot de passe superutilisateur (root) durant l'installation de Debian. Si vous aimez sudo que vous voulez l'installer (même si vous l'avez sauté durant l'installation de votre Debian), vous pouvez, devenir superutilisateur avec la commande su, l'installer, et vous ajouter votre propre nom d'utilisateur dans le groupe sudo et faire une déconnexion puis une reconnexion complète. Exemple : su - #Password: (entrez ici le mot de passe superutilisateur que vous avez défini dans l'installation de votre Debian et appuyez sur la touche #Entrée) apt install sudo sudo adduser USER sudo Puis veuillez effectuer une complète déconnexion et reconnexion.  Pourquoi pas sudo ? Notez que, historiquement, tous les systèmes de type Unix fonctionnaient parfaitement même avant que « sudo » ne doit inventé. De plus, avoir un système sans sudo pourrait apporter encore plus de sécurité car le paquet sudo pourrait être affecté par des bogues de sécurité, comme toute partie additionnel de votre système. Nombre d'utilisateur de Debian n'installent pas sudo. Ils ouvrent à la place un terminal en tant que supertulisateur (par exemple avec la commande su - à partir d'un utilisateur normal). Ainsi, vous n'avez pas placer « sudo » devant n'importe quelle commande.  Pourquoi sudo ? Utiliser sudo pourrait être un plus familier pour les nouveaux utilisateur et est meilleur (plus sûr) que d'ouvrir une session en tant que superutilisateur pour un certain nombre de raisons dont : Personne n'a à connaitre le mot de passe du superutilisateur ( sudo demande le mot de passe de l'utilisateur courant). Des droits supplémentaires peuvent être accordés temporairement à des utilisateurs puis retirés sans qu'il soit besoin de changer de mot de passe. Il est facile de n'exécuter que les commandes qui nécessitent des droits spéciaux avec sudo et le reste du temps, on travaille en tant qu'utilisateur non-privilégié, ce qui réduit les dommages que l'on peut commettre par erreur. Contrôler et enregistrer : quand une commande sudo est exécutée, le nom de l'utilisateur et la commande sont enregistrés. Pour toutes les raisons ci-dessus, la possibilité de basculer en superutilisateur en utilisant sudo -i (ou sudo su) est habituellement désapprouvée parce que cela annule la plupart les avantages cités ci-dessus. Commande Basiques Passer en super utilisateur. sudo -s Afficher le répertoire de travail courant. pwd Se déplacer dans un répertoire. cd (Dossier) Aller à la racine du disque dur. cd / Se déplacer dans le répertoire parent. cd .. Visualiser le contenu du répertoire. ls Permet de créer un répertoire. mkdir (Dossier) Supprimer un répertoire. rmdir (Dossier) Permet de supprimer un dossier avec des fichiers dedans. rm -rf dossier Affiche l’aide d’une commande. man (Logiciel) Permet d’afficher un fichier texte (page par page ou en entier). more (Fichier) cat (Fichier) Permet de modifier un fichier texte. nano (Fichier) vi (Fichier) Permet de copier un fichier ou un dossier. cp /etc/fichier (source) /tmp/fichier (destination) Permet de déplacer un fichier ou un dossier ou de le renommer mv /etc/fichier (source) /tmp/fichier (destination) mv fichier fichierrenommer Créer un fichier touch fichier Permet de supprimer un fichier. rm fichier Cron Le démon crond est le processus qui permet d’exécuter des tâches planifiées automatiquement à des instants précis prévus à l’avance (date, heure, minute) et en gérant une chronicité. Si par exemple je veux qu’une machine PC-560 s’éteigne tous les jours à 20h51, je peux le faire avec cron. Pour cela, il me faut une entrée dans la crontab de la machine qui indiquera la commande à exécuter pour éteindre la machine. Normalement, cron est installé par défaut sur les systèmes, sinon vous pouvez l’installer comme d’habitude. Toutes les configurations exécutées par cron vont se retrouver dans la table de cron (crontab). Seul la syntaxe particulière est complexe à utiliser. Utilisation de la crontab Pour paramétrer une tâche planifiée, il faut écrire une entrée dans la crontab. Cette entrée spécifie la (ou les) date d’exécution de cette tâche, ainsi que la tâche à exécuter et d’autres paramètres si nécessaire. Pour chaque utilisateur du système, on peut éditer un fichier de crontab, relatif aux tâches planifiées de ce dernier. Ces fichiers se trouvent en général dans “/var/spool/cron/crontabs/” ou un équivalent et portent le nom de l’utilisateur en question. L’édition du fichier ne se fait pas en direct dans le spool, on utilisera une commande dédié pour ça : - crontab -e pour éditer le fichier de crontab de l’utilisateur courant - crontab -e -u root pour éditer la crontab d’un utilisateur spécifique (root) - crontab -l pour afficher la crontab de l’utilisateur courant. - crontab -r qui va effacer la crontab de l’utilisateur En général au premier lancement, le système vous demandera quel moteur de texte vous souhaitez utiliser (nano, vi, ...) en fonction de ceux installé. En sortie du fichier, le système vérifiera que la syntaxe de vos entrées est correct. Il est important de noter, que le système dispose, en plus du crontab utilisateurs, de ses propres fichiers et tâches planifiées dans les répertoires “/etc/cron.*” l’étoile représente les différents dossiers utilisés (qui sont référencés dans /etc/crontab) : - cron.hourly toutes les heures - cron.daily tous les jours - cron.weekly toutes les semaines - cron.monthly tous les mois - cron.d contient des fichiers au format crontab pour des utilisations plus spécifiques. Syntaxe de cron Chaque entrée dans la crontab correspond à une tâche à exécuter. Et chaque entrée de la crontab est une ligne dans un des fichiers cités plus haut. Si nous regardons une ligne en détail : Exemple : 51 19 * * 0 root /usr/local/bin/backupbackup Cette ligne signifie de lancer le programme /usr/local/bin/backupbackup tous les dimanches à 19h51. La syntaxe générale d’écrit sous cette forme : mm hh jj MMM JDS commande mm : Codé sur 2 chiffres représente les minutes de 0 à 59, ou * pour décrire toutes les minutes hh : Codé sur 2 chiffres représente les heures de 0 à 23, ou * pour décrire toutes les heures jj : Codé sur 2 chiffres représente la date du jour de 1 à 31, * pour décrire tous les jours MMM : Codé sur 2 chiffres ou 3 lettres représente le mois de 1 à 12 ou de jan à dec, * pour décrire tous les mois JDS : représente le jour de la semaine codé par 1 chiffre ou 3 lettres (de 0 à 7 ou de sun à sun, le 0 et le 7 représente sunday) commande : la commande qui sera exécutée. On peut trouver des caractères spéciaux dans les champs prévus pour : - * : signifie tout ou chaque unité de temps. - , : permet de décrire une liste. Exemple 3,5,17 - - : permet de décrire un intervalle. Exemple de 1 à 10 se note 1-10 - */ : permet de décrire un intervalle avec des pas différents de 1. Par exemple : */10 signifie 0,10,20,30, ... - @reboot : permet de lancer la commande au démarrage de la machine - @yearly : tous les ans - @daily : tous les jours Vous pouvez également vous renseigner sur anacron, pour que les tâches soient exécutées même si la machine est éteinte (ou au moins au redémarrage de celle-ci). Système de fichiers Un système de fichiers est une façon d’organiser et de stocker une arborescence sur un support (disque, cd, ...). Chaque OS a sa propre organisation. Linux possède son système appelé ext2 mais peut en gérer d’autres. La liste se trouve en général dans /proc/filesystems. L’utilisateur peut donc accéder sous Linux à d’autres systèmes de fichiers (DOS, Vfat, NTFS, ...) provenant d’un périphérique ou importé par le réseau. Tout est fichier Comme nous l’avons vu précédemment, dans le système linux, tout est considéré comme un fichier : - Les fichiers - Les dossiers - Un disque dur - La mémoire - Un port USB aussi . Mais parmi ces fichiers, tous n’ont pas la même catégorie. On peut en effet retrouver : - fichiers normaux (texte, exécutables, ...); symbole “-” - fichiers répertoires, ce sont des fichiers conteneurs qui contiennent des références à d’autres fichiers. Véritable charpente de l’arborescence.; symbole “d” - fichiers spéciaux, ils sont situés dans /dev, ce sont les points d’accès préparés par le système aux périphériques. Le montage va réaliser une correspondance de ces fichiers spéciaux vers leur répertoire “point de montage”. Par exemple, le fichier /dev/hda permet l’accès et le chargement du 1er disque IDE. - Accès caractère par caractère; symbole “c” - Dispositif de communication ; symbole “p” - Accès par bloc ; symbole “b” - fichier lien symboliques, ce sont des fichiers qui ne contiennent qu’une référence (un pointeur) à un autre fichier. Cela permet d’utiliser un même fichier sous plusieurs noms sans avoir à le dupliquer sur le disque. ; symbole “l” Le processus de montage que l’on évoque pour les fichiers spéciaux, avec sa commande mount est le moyen de faire correspondre les parties de l’arborescence et les partitions physiques de périphérique. Il permet de plus d’affecter tout système extérieur (cd, zip, réseau) à un répertoire créé pour cela dans l’arborescence. Il suffira ensuite de se déplacer à ce répertoire, appelé point de montage, qui est en fait un répertoire “d’accrochage”, pour accéder à ses fichiers (bien sûr, conformément aux permissions que possède l’utilisateur). FHS (Filesystem hierarchy standard) C’est la standardisation des noms et des emplacements des dossiers, et de leurs contenus. Voici la structure qui est recommandée d’après les spécifications SI l’on détaille : - /bin : Les fichiers binaires les plus importants - /boot : le Kernel et le bootloader - /dev : les périphériques - /etc : les fichiers de configurations spécifiques à l’ordinateur - /home : Emplacement contenant les profils dossiers utilisateur - /mnt : Emplacement d’accès aux systèmes de fichiers montés dans l’OS - /lib : Bibliothèques de fonctions utilisées par les commandes /bin et /sbin - /proc : Le kernel place ici l’état en temps réel du fonctionnement du système et des processus - /root : Dossier du profil “root” - /sbin : Contient des exécutables - /tmp : à utiliser pour la création de fichiers temporaires - /usr : Applications installées par les utilisateurs (et souvent les données qui vont avec) souvent un des plus lourds! - /var/log : Fichiers logs - /var/spool : File d’attente d’impression - /var/tmp : Fichiers temporaires Gob et Jokers Le file globing, est l’opération qui transforme un caractère joker en une liste de chemins, et de fichiers correspondants qui formeront le résultat. Le file globing est l’ancêtre des expressions régulières. Sous Bash, les jokers possibles sont : - Le caractère * - Le caractère ? - Les caractères [] Le caractère * est utilisé pour obtenir la liste de tout le contenu Ex : ls => ls * Il est possible de préciser plus de caractéristiques : ls D* => Tous les fichiers commençant par un D ls d*v* => Tous les fichiers commençant par un d minuscule mais contenant aussi la lettre v Le caractère ?, est utilisé pour préciser que le résultat doit contenir un seul ou plusieurs caractères (un par joker ?) Exemple : ls ? => liste tout ce qui ne contient qu’un seul caractère ls ?? => liste tous les fichiers qui n’ont que 2 caractères ls w?? => liste tous les fichiers qui ont 3 caractères et commençant par w ls w??* => liste tous les fichiers qui commencent par w et contiennent au moins 3 caractères. Le joker [], est utilisé pour spécifier une plage de caractères admissibles. ls [a-f]?? => liste tous les fichiers dont la première lettre commence par a,b,c,d,e ou f et faisant 3 caractères. ls [w]* => liste tous les fichiers commençant par w ls [*] => ici l’étoile est son propre caractère, liste tous les fichiers commençant par * ls *[0-9][0-9]* => liste tous les fichiers contenant 2 chiffres ls [!a-y]* => ne liste que les fichiers commençant par autre chose que les lettres a à y. le ! inverse le résultat ls *[^3-9] => liste tous les fichiers excluant ceux contenant les chiffres 3 à 9 Droit d’accès et permissions Droits Un fichier est caractérisé par un certain nombre de droits d’utilisation. Lorsque que l’on fait un ls -l, on remarque les éléments suivants : le premiers bloc est définie comme suit : _ Type de fichier (d, -, p, l, ...) _ _ _ Droits du propriétaire du fichier (owner), dans l’ordre (lecture, écriture, exécution) _ _ _ Droits du groupe auquel appartient le fichier (group), dans l’ordre (lecture, écriture, exécution) _ _ _ Droits d’un utilisateur quelconque (user), dans l’ordre (lecture, écriture, exécution) Pour rappel : Permission Effet sur le fichier Effet sur le dossier r (read) Autorise la lecture ou la copie du fichier et son contenu Sans droit d'exécution : autorisation de liste les fichiers dans le dossier Avec droit d'exécution : autorisation de lister les fichiers de façon détaillée dans le dossier w (write) Autorise à supprimer ou modifier le contenu du fichier. Permet de supprimer le fichier Sur un dossier, il faut également l’attribut “execute” afin d’opérer des modifications x (execute) Autorise un fichier d’être lancé comme un processus Autorise un utilisateur à entrer dans ce dossier L’attribut suivant (1 par exemple) est le nombre de lien symbolique vers ce fichier Les 2 attributs d’après : root root définissent le propriétaire suivis par le groupe L’utilisateur qui crée le fichier est considéré comme son propriétaire. Il faut savoir que seul root est habilité à modifier le propriétaire d’un fichier, avec la commande “chown” Le groupe du fichier sera celui du groupe principal auquel appartient l’utilisateur qui crée ce fichier. la commande “id” indique l’identité de l’utilisateur actuel, son group principal, et tous les groupes auxquels il appartient. Pour changer le groupe d’un fichier, on utilise la commande “chgrp” seuls root et le propriétaire du fichier peuvent changer le groupe d’un fichier. Permissions Seul root et le propriétaire du fichier disposent de la possibilité de modifier les permissions d’un fichier au moyen de la commande chmod Exemples : Ajouter les droits d’exécution au propriétaire du fichier chmod u+x monfichier Supprimer les droits d’écriture pour le groupe : chmod g-w monfichier Assigner des droits à plusieurs sections des attributs ; chmod o=r,g-w,u+x monfichier Supprimer toutes les permissions chmod a=- monfichier La méthode octale reste la plus rapide pour l’attribution, avec r=4; w=2 et x=1 Pour donner les permissions rwx r-x r-x à un fichier, on va additionner les valeurs : Owner: 4+2+1 => 7 Group : 4+1 => 5 Other : 4+1 => 5 => chmod 755 monfichier Attribut spéciaux -setuid Cet attribut spécial permet d’appliquer à un fichier exécutable, d’autoriser d’autres utilisateurs à lancer l’exécutable, comme s’il étaient l’utilisateur root. chmod 4000 Exemple avec la commande passwd : s -> permissions x+setuids (s) S -> seule la permission setuid existe (pasx) Attribut spéciaux -setgid Même chose qu’avec setuid, mais pour le groupe utilisateur chmod 2000 - Appliqué à un fichier exécutable, afin de s’exécuter via le group du propriétaire, au lieu de celui de l'utilisateur qui lance l’exécutable - Appliqué à un dossier, fait en sorte que le contenu créé dans ce dossier appartient au groupe qui possède le dossier (et pas celui de l’utilisateur qui crée le contenu dans ce dossier) Attribut spéciaux -sticky chmod 1000 L’utilité de cet attribut est d’empêcher d’autres utilisateurs de supprimer le contenu d’un autre utilisateur. Pour supprimer un fichier, il faut les autorisations d’écriture sur le dossier parent. Ainsi, un admin crée un dossier accessible et modifiable par tous les utilisateurs. Tout le monde pourra supprimer le contenu de ce dossier ... L’utilisation de cette permission sticky permet de définir pour un dossier que : - L’utilisateur propriétaire d’un fichier, dans ce dossier, pourra supprimer le fichier - root et l’utilisateur propriétaire du dossier parent pourra aussi Héritage vs umask Lorsque l’on crée un sous-dossier sous windows, ce dernier hérite des droits d’accès du dossier parent (par défaut). Il faut savoir que sous linux : NON ! ce n’est pas le cas! En effet le sous-dossier aura les droits créés selon la valeur umask de l’utilisateur créant le sous dossier. Read vaut 4, write 2, execute 1, rien vaut 0. Dans le cas de umask, ces valeurs précisent les permissions à supprimer des permissions “maximum” à la création ! Sur un fichier, les permissions maximales sont : rw- rw- rw- soit 666 en octal. La valeur umask de l’utilisateur créant le fichier va donc permettre de supprimer certaines de ces valeurs! Cette valeur se code avec trois nombres de base en octale. Ex, Si l’on souhaite que par défaut l’utilisateur sisr, crée des fichiers avec les permissions rw- r-- --- : - Le premier nombre octal sera 0 (on ne change rien à rw-) - Le second nombre (groupe) sera 2 (on supprime la permission w, donc 2, il reste r--) - Le troisième nombre (others) sera 6 (on supprime r soit 4 et w soit 2, il reste ---) Le umask de l’utilisateur sisr doit donc être 026 Sur un dossier, sans droits d’exécution, il est impossible d’agir dans le dossier, et les éventuels droits en écriture dans ce dossier ne seront pas appliqués. De ce fait, les permissions “maximales” par défaut accordées à la création d’un dossier sont : rwx rwx rwx soit 777 en octal Exemple: Le propriétaire doit disposer des droits complets sur le dossier, seulement des droits d’exécution et lecture pour le groupe, et aucun droits pour les autres. Ceci se traduit par : rwx r-x --- Le umask de l’utilisateur devra retirer les droits en écriture sur le groupe (-2) et les droit rwx à others (-7). Le umask sera donc 027 Umask propose un comportement différent sur les fichiers et sur les dossiers. Mais cette valeur umask est la même pour les fichiers et les dossiers ! On utilise des valeurs “classiques” pour régler umask Jusqu’ici, nous avons précisé des valeurs sur trois chiffres en base octale. La commande umask affiche le umask de l’utilisateur actuel, mais sur 4 chiffres ! Le premier représente en faite les attributs spéciaux (setuid, setgid, sticky). Cependant, ces attributs spéciaux ne sont pas spécifiables par défaut (lors de la création d’un fichier ou dossier). Il n’est donc pas nécessaire de la préciser ou la calculer lors de l’utilisation de umask. /!\ Umask n’est utilisé qu’à la création, les fichier existant ne sont pas touchés! Gestion des archives Une archive est un fichier contenant un ou plusieurs fichiers ou dossiers, la plupart du temps “compressés” ce afin de diminuer la consommation d’espace disque. Il existe de nombreux algorithmes de compression et d’archivage, vous connaissez probablement le zip et le rar connu sous windows. Voyons certains des plus utilisés sous les système linux : Tar Tar est une très ancienne commande (Tape Archive), utilisée autrefois pour la sauvegarde de contenu sur des bandes magnétiques. Les premières versions permettaient uniquement l’archivage, mais depuis l'arrivée de gzip (-z) et bzip2(-j) c’est maintenant possible. Principaux attributs de tar (extension de fichier .tar en général): - tar -c : Créer une archive - tar -cf : Créer une archive et spécifier son nom - tar -cvf : Créer une archive et afficher un diagnostic à l’écran - tar -cvzf : Créer une archive, compresser avec gzip et afficher le diagnostic - tar -tf : Lister (option t) le contenu de l’archive en argument (option f) - tar -vtf : Lister (t) de façon détaillée (v) l’archive (f) - tar -xf : Extraire (option x) le contenu de l’archive (f) Gzip et gunzip Par défaut l’utilisation de gzip remplace un fichier par sa version compressée ! qui aura l’extension “.gz”. Pour éviter ce comportement si l’on veut conserver le fichier d’origine, on utilise l’option -c qui va rediriger le contenu extrait vers stdout !) il faudra donc faire soi-même la redirection vers un fichier : gzip -c monfichieraziper > monfichieraziper.gz gzip -cr /etc > etc.gz Gunzip quand à lui effectue l’opération inverse de gzip, il décompresse une archive gz. Et par défaut comme gzip, il remplace le fichier d’origine “.gz” par sa version décompressé. bzip2 et bunzip2 Le fonctionnement est similaire au gzip et gunzip, l'algorithme de compression utilisé est différent cependant. L’extension par défaut que l’on rencontrera sera : bz2. L’option de récursion -r n’est pas disponible non plus, on utilisera le * à la place. zip et unzip Même si ce format est surtout utilisé sous windows, linux dispose de son équivalent : zip ./test.zip ./test/* va compresser le contenu du dossier test dans le fichier test.zip zip -r /etc/etc.zip /etc va compresser tout le contenu du dossier /etc xz xz -z * permet de compresser des fichiers individuellement (autant d’archives que de fichiers) avec l’extension .xz xz -d permet de décompresser les fichier cpio cpio: copy-in copy-out En mode copy-out (option -o), les fichiers dans un dossier seront recopiés vers une archive En mode copy-in (option -i) le contenu d’une archive est listé ou copie les fichiers d’une archive vers un dossier. dd Permet d’effectuer la copie d’un fichier un d’une partition complète bit à bit. Cela permet de : - Cloner un disque ou une partition - Sauvegarder la MBR (master boot record) - Création d’un fichier d’une taille précise rempli de 0 Recherche de fichier grâce aux commandes locate et find locate et find sont les deux commandes principales pour chercher des fichiers dans la table d’inode de linux. Elles fonctionnent différemment mais permettent le même résultat. Nous verrons aussi les commandes whereis / which / type locate Cette commande utilise une base de données mise à jour quotidiennement par l’OS. Si vous désirez mettre à jour cette base de données, vous pouvez utiliser la commande updatedb Les particularités de cette commande : - N’affiche que les fichiers lisibles par l’utilisateur - Très rapide pour la recherche, mais les fichiers récents seront absent à moins d’utiliser l’updatedb - peut nécessité d’être installé apt-get install locate find La commande a besoin de plusieurs choses pour travailler : - Un nom de dossier comme point de départ de la recherche (sinon travail depuis le dossier courant) - Pour rechercher un fichier on utilise l’option -name - Plus lent que locate mais permet de se positionner où l’on veut et n’oubliera aucun fichier Vous remarquez qu’il y a beaucoup moins de fichiers, c’est qu’il faut utiliser le globing : exemple : find / -name *passwd* Voici différents options pour le find : Options Exemple Description -iname -iname Hello recherche les fichiers en ignorant la casse -mtime -mtime -7 Les fichiers modifiés il y a moins de 7 jours -mmin -mmin 5 Les fichiers modifiés il y a moins de 5 minutes -size -size +10M Les fichiers pesant plus de 10Mo -user -user sisr Les fichiers possédés par l’utilisateur sisr -empty -empty liste les fichiers vides -type -type d Liste les fichiers qui sont des dossiers -maxdepth -maxdepth 1 Profondeur de recherche limité à 1, ne parcourt pas les sous-dossiers Si l’on veut tous les fichiers créés par l’utilisateur sisr qui s’appelle hosts : find / -user sisr -name hosts Ou une syntaxe plus compliquée : find / -iname ‘ifconfig*’ -o \( -name hosts -user sisr \) cette commande trouvera à partir du dossier racine : - Tous les fichiers commençant par ifconfig - OU Tous les fichiers intitulés hosts appartenant à l’utilisateur sisr Pour définir sur quels attributs effectués un OU, il faut mettre les attributs entre parenthèses. Le problème c’est que le shell interprète la parenthèse comme un caractère spécial, il faut donc le protéger en utilisant \ devant chaque parenthèse pour dire au shell de ne pas l'interpréter mais de l’envoyer directement à la commande find. Le caractère \ est remplaçable par le ‘ find . -name host* -exec ls -l {} \; - Trouver tous les fichiers commençant par host dans le dossier actuel et ses sous-dossiers - Puis lancer la commande ls -l pour chaque fichier trouvé - le {} permet de passer, fichier par fichier, la main à la commande ls - Pour que ceci fonctionne, il faut rajouter un ; à la fin de chaque fichier passé en argument, donc \; whereis et which - whereis trouve deux binaire au nom de base - which nous indique que seul bash est utilisé quand on utilise la commande base et non pas bash.bashrc. Ce dernier est un script automatiquement lancé lorsqu'on se connecte à la ligne de commande en mode interactif. Swap Le swap est un espace d’échange qui recueille des données normalement en RAM lorsque l’utilisation de celle-ci dépasse un certain point. Gérer les espaces d’échange Voir l’utilisation des espaces d’échanges cat /proc/swaps Cela va donner quelque chose comme : Filename Type Size Used Priority /dev/dm-3 partition 3911676 3906776 -2 /var/swap file 5242876 310324 -3 Monter et démonter un espace d’échange Les termes de montage/démontage ne sont pas corrects car les espaces d’échange ne sont pas montés sur le système. Vous ne les verrez pas avec la commande mount. Pour ne plus utiliser un espace d’échange : swapoff /dev/dm-3 Cette commande peut prendre un peu de temps car le contenu de l’espace d’échange va être déplacé dans la RAM ou dans un autre espace d’échange, ou oublié par le système s’il n’y a plus de place disponible. Pour le réutiliser : swapon /dev/dm-3 L’option -a permet d’agir sur tous les espaces d’échanges connus du système (dans /etc/fstab la plupart du temps. Systemd a un truc pour ça aussi, mais je ne l’ai encore jamais rencontré). Exemple : swapoff -a swapon -a Modifier le recours aux espaces d’échange Les espaces d’échanges vont être utilisés avec plus ou moins d’agressivité selon la valeur de vm.swappiness de votre système (pour voir cette valeur : sysctl vm.swappiness). Cette valeur peut être comprise entre 0 et 100. Un nombre élevé veut dire que le noyau va avoir plus tendance à décharger la RAM dans les espaces d’échanges que dans un système avec un nombre bas. Pour modifier temporairement la valeur : sysctl -w vm.swappiness=10 Pour la modifier de façon permanente : echo "vm.swappiness = 10" > /etc/sysctl.d/99-swappiness.conf sysctl -p /etc/sysctl.d/99-swappiness.conf (le sysctl -p est là pour appliquer la valeur que vous venez de mettre dans le fichier) Les différents supports d’espaces d’échanges On peut avoir du swap avec une partition comme le propose Debian lors de l’installation ou via un fichier swap, comme le fait Ubuntu. On peut aussi avoir du swap… sur la RAM ! (voir plus bas) L’avantage du fichier sur la partition est sa manipulation plus facile. Je pense en particulier à la modification de la taille du swap. Créer un fichier swap C’est excessivement simple : on crée un fichier, on le prépare comme il faut, on le déclare dans /etc/fstab et on l’utilise. fallocate -l 2G /var/swap mkswap /var/swap chmod 600 /var/swap echo "/var/swap none swap sw 0 0" >> /etc/fstab swapon /var/swap Utiliser de la RAM pour l’espace d’échange Cela paraît contre-intuitif, mais c’est très simple : l’espace d’échange sera compressé et conservé en RAM. Le coût en performances de la compression/décompression des données est, avec nos processeurs actuels, généralement moindre que celui de l’utilisation d’un disque, fut-il SSD : la RAM permet des accès beaucoup, beaucoup plus rapides que n’importe quel disque. Comme les espaces d’échanges sont utilisés comme de la RAM supplémentaire, mais lente, avoir ceux-ci sur la RAM, mais compressés équivaut plus ou moins à une augmentation de taille de RAM au prix de quelques cycles CPU. Pour utiliser ce mécanisme, il suffit, sur Debian, d’installer le paquet zram-tools, de modifier /etc/default/zramswap à son goût et de relancer le service zramswap. Curl Ceci constitue un petit inventaire des commandes les plus utiles de curl. Utilisation de base curl http://example.org La commande curl télécharge la ressource demandée (qui n’est pas nécessairement une adresse web, car curl est capable de télécharger des ressources d’autres protocoles, comme ftp par exemple) et en affiche le contenu sur la sortie standard, si ce contenu n’est pas un contenu binaire. Rediriger la ressource vers un fichier curl http://example.org > fichier.html curl http://example.org --output fichier.html curl http://example.org -o fichier.html Réduire la verbosité de curl Lorsque la sortie est redirigée vers un fichier, curl affiche une barre de progression donnant certaines indications sur le téléchargement de la ressource (le temps restant, la taille…). Pour ne pas afficher ces informations, on utilise l’option --silent ou son abbréviation -s. curl --silent http://example.org -o fichier.html curl -s http://example.org -o fichier.html Faire autre chose qu’un GET Pour utiliser une autre méthode HTTP que GET, on utilise l’option --request ou son abbréviation -X. curl --request POST http://example.org curl -X POST http://example.org Faire une requête HEAD Si on tente de faire une requête HEAD avec l’option --request, curl affichera un message d’erreur : Warning: Setting custom HTTP method to HEAD with -X/--request may not work the Warning: way you want. Consider using -I/--head instead. Il convient d’utiliser l’option --head ou son abbréviation -I : curl --head http://example.org curl -I http://example.org Pour faire une requête avec authentification HTTP On spécifie l’identifiant et le mot de passe avec l’option --user ou son abbréviation -u, en les séparant par un caractère :. curl --user login:password http://example.org curl -u login:password http://example.org Forcer la connexion en IPv6 ou en IPv4 On utilise pour cela les options -6 et -4. curl -6 http://example.org curl -4 http://example.org Utilisation avancée Forcer la connexion sur une autre adresse IP Il est possible de dire à curl d’utiliser une adresse IP particulière au lieu de la véritable adresse IP d’un domaine. Il faut voir cela comme une alternative à la manipulation du fichier /etc/hosts. curl --resolve example.org:80:127.0.0.1 http://example.org curl --resolve "example.org:80:[::1]" http://example.org La syntaxe de l’option est host:port:addr. Le port est celui qui sera utilisé par le protocole. Spécifier le port 80 pour le protocole https serait inutile : il faut dans ce cas utiliser le port 443. Forcer la connexion sur une autre adresse IP et un autre port On utilise pour cela l’option --connect-to, relativement similaire à l’option --resolve. La syntaxe de l’option est host1:port1:host2:port2 curl --connect-to example.org:80:127.0.0.1:8080 http://example.org curl --connect-to "example.org:80:[::1]:8080" http://example.org Forcer la connexion depuis une certaine interface réseau On utilise pour cela l’option --interface suivi du nom d’une interface, d’une adresse IP ou d’un nom d’hôte. curl --interface wlo1 http://example.org curl --interface 203.0.113.42 http://example.org curl --interface example.com http://example.org Ne pas vérifier la sécurité du certificat du site Que ce soit parce qu’un certificat est expiré ou parce qu’on utilise un certificat autosigné, on peut avoir besoin que curl effectue bien la requête sans se préoccuper de la validité du certificat utilisé par le site. On utilise alors l’option --insecure ou son abbréviation -k. curl --insecure https://example.org curl -k https://example.org Utiliser un fichier d’autorités de certification spécifique Si on utilise, par exemple, un certificat autosigné, ou signé par une autorité de certification (AC) personnelle, et qu’on souhaite s’assurer que le certtificat utilisé par le site est bien valide, on peut donner à curl un fichier contenant le certificat public de l’AC (il est possible d’y mettre plusieurs certificats) au format PEM. On utilise l’option --cacert. curl --cacert fichier_AC.pem https://example.org On peut aussi utiliser l’option --capath dont l’argument est un dossier contenant des fichiers de certificats d’AC. curl --capath ~/ACs https://example.org Sed C’est l’outil absolu pour modifier du texte en le passant par un pipe ! Ou pour effectuer des changements en masses sur un fichier sans l’ouvrir. Il est possible de faire des trucs de tarés avec c’est pas juste un truc pour faire des substitutions à coup d’expressions rationnelles, c’est un vrai éditeur de texte, on peut se balader dans le texte, faire des copier/coller, etc. Syntaxe de base Avec un fichier : sed fichier.txt [fichier2.txt] [fichier3.txt] En utilisant la sortie d’une autre commande : find . -name \*.txt | sed NB : sed, par défaut, ne modifie pas le fichier utilisé. Il affichera sur la sortie standard le fichier modifié par la commande passée à sed. Si on souhaite que le fichier soit modifié, on utilise l’option --in-place ou son abbréviation -i (on peut indifféremment placer l’option avant ou après la commande) : sed --in-place fichier.txt sed -i fichier.txt Expression régulières Si sed est un éditeur de texte (son nom veut dire Stream EDitor) et qu’il est utilisable en lui donnant des commandes équivalentes à « Va à ligne 3, supprime 4 caractères, descend à la ligne suivante… », on l’utilise souvent avec des expressions régulières. Rappel sur les expressions régulières Les expressions régulières permettent de rechercher des correspondances avec un motif, écrit avec une syntaxe spéciale. Les éléments de syntaxe suivants appartiennent aux Perl Compatible Regular Expression (PCRE), qui sont le standard de la très grande majorité des langages de programmation. sed utilisant une syntaxe légèrement différente, certains caractères devront être échappés (voir plus bas). NB : les expressions régulières de cette section sont placé entre des / pour les distinguer des chaînes de caractères simples. . : correspond à un caractère, n’importe lequel. /./ correspondra à tout sauf à une chaîne vide ? : quantificateur, modifie la correspondance du caractère qui le précède : celui ci peut être présent zéro ou une fois. /a?/ correspondra à une chaîne vide ou à a + : quantificateur : le caractère précédent sera présent une ou plusieurs fois. /a+/ correspondra à a, aa, aaa… * : quantificateur : le caractère précédent sera présent zéro ou plusieurs fois. /a*/ correspondra à une chaîne vide, à a, aa, aaa… {n} : quantificateur : le caractère précédent sera présent n fois. /a{3}/ correspondra à aaa {n,m} : quantificateur : le caractère précédent sera présent de n à m fois. /a{3,5}/ correspondra à aaa, aaaa ou aaaaa {n,} : quantificateur : le caractère précédent sera présent au moins n fois. /a{3,}/ correspondra à aaa, aaaa, aaaaa, aaaaaa… | : séparateur d’expression. /bonjour|hello/ correspondra à bonjour ou à hello [^liste] : correspond aux caractères n’étant pas entre crochets. /[^ae]/ correspondra à n’importe quel caractère sauf à a et à e [liste] : correspond à un des caractères entre crochets. /[ae]/ correspondra à a ou à e. Pour que le caractère ^ soit un choix possible, il faut le placer à une autre place que la première place : [liste^], [lis^te]… On peut aussi spécifier des plages de caractères : [0-9a-zA-Z] ^ : ancre, correspond au début de la ligne. /^a/ correspondra à a si celui-ci est le premier caractère de la ligne $ : ancre, correspond à la fin de la ligne. /a$/ correspondra à a si celui-ci est le dernier caractère de la ligne (…) : groupe l’expression. On peut s’en servir, par exemple, pour capturer des éléments (ce qui permet de les réutiliser plus tard) ou faire des sous-expressions. /Bonjour (foo|bar), ça va \?/ correspondra à Bonjour foo, ça va ? et à Bonjour bar, ça va ? Pour utiliser les caractères de manière littérale (exemple : pour correspondre à un point), on les échappera avec un \. /\./ correspondra au caractère point ( .). Caractères à échapper dans sed La version GNU de sed utilise les Basic Regular Expression (BRE), qui ont une syntaxe légèrement différentes des PCRE. Certains caractères doivent donc être échappés dans les BRE, qui sont utilisables tels quels pour des PCRE : le quantificateur +. Exemple : /a\+/ le quantificateur ?. Exemple : /a\?/ le quantificateur {i}. Exemple : /a\{5\}/ les parenthèses (…). Exemple : /\(a\)/ le séparateur d’expressions régulières |. Exemple : /a\|b/ Effectuer une substitution de texte La commande à utiliser est 's/expression régulière/substitution/' : sed 's/foo/bar/' foo.txt Cette commande remplacera la 1ère occurrence de foo de chaque ligne du fichier par bar. Si on souhaite remplacer toutes les occurrences de chaque ligne, on emploie le modificateur g : sed 's/foo/bar/g' foo.txt Si on ne souhaite remplacer que l’occurrence n°X de chaque ligne : sed 's/foo/bar/X' foo.txt ## Exemple avec la 2e occurrence : sed 's/foo/bar/2' foo.txt Si on ne souhaite remplacer l’occurrence n°X de chaque ligne, ainsi que les suivantes : sed 's/foo/bar/gX' foo.txt ## Exemple avec la 2e occurrence et les suivantes : sed 's/foo/bar/g2' foo.txt Ajouter quelque chose au début de chaque ligne : sed 's/^/FooBar /' foo.txt Ajouter quelque chose à la fin de chaque ligne : sed 's/$/ BazQux/' foo.txt Si on souhaite que l’expression régulière soit insensible à la casse (ex : s qui correspond aussi à S), on emploie le modificateur i : sed 's/foo/bar/i' foo.txt On peut utiliser plusieurs modificateurs en même temps : sed 's/foo/bar/gi' foo.txt Pour réutiliser ce qui a correspondu à l’expression régulière dans la chaîne de substitution, on utilise le caractère & : sed 's/foo/& et bar/' foo.txt Pour réutiliser ce qui a correspondu à un groupe d’expression, on utilise \1 pour le 1er groupe, \2 pour le 2e groupe… : sed 's/Bonjour (foo|bar). Il fait beau./Bonsoir \1. À demain./' foo.txt NB : on peut utiliser d’autres séparateurs que le caractère /, ce qui rend l’écriture d’une commande plus simple si l’expression régulière ou la substitution comportent des / : plus besoin de les échapper. Exemple : sed 's@/home/foo@/var/bar@' foo.txt Supprimer des lignes Supprimer la ligne n : sed 'nd' foo.txt ## Exemple avec la 3e ligne : sed '3d' foo.txt Supprimer les lignes n à m : sed 'n,md' foo.txt ## Exemple : sed '3,5d' foo.txt Supprimer toutes les lignes sauf la ligne n : sed 'n!d' foo.txt ## Exemple : sed '6!d' foo.txt NB : attention, le caractère ! est un caractère spécial pour bash (et les autres shells). Si vous utilisez des apostrophes ( ') pour votre commande sed, tout ira bien, mais si vous utilisez des guillemets doubles ( "), il faut l’échapper avec un \. Supprimer toutes les lignes sauf les lignes n à m : sed 'n,m!d' foo.txt ## Exemple : sed '6,8!d' foo.txt Supprimer les lignes qui correspondent à une expression régulière : sed '/regex/d' foo.txt ## Exemple : sed '/foobar/d' foo.txt Pour supprimer les lignes vides, d’un fichier, il suffit d’utiliser l’expression régulière qui signifie que la ligne est vide : sed '/^$/d' foo.txt Pour supprimer la première ligne correspondant à une expression régulière, ainsi que toutes les lignes suivantes : sed '/regex/,$d' foo.txt ## Exemple : sed '/foobar/,$d' foo.txt NB : attention encore une fois aux guillemets doubles, il faudrait échapper $ dans cette commande car le shell essayerait d’interpréter $d comme une variable. AT Elle est utilisée pour planifier des actions qui doivent se réaliser ultérieurement et une seule fois. (Une sorte de tache planifié mais sans la répétition). Par défaut elle n’est pas forcément installé sur votre distribution, pour l’installer : apt install at Si ca ne marche pas , faites avant un apt-get update. Puis lancer le service avec : service atd start ou  systemctl start atd.service systemctl enable atd.service Exemple d’utilisation : at now +2 minutes Au prompt, entrer la commande désirée, par exemple : at> echo “A noter” > /root/exercicesAT.txt Pour sortir du prompt, faire un CTRL+D Le système vous renverra un message de la forme : Job 1 at JOUR MOI NUMJOUR HEURE ANNEE Avec la commande atq, vous pouvez visualiser la file de traitement, le premier numéro est le numéro du job dans la file de traitement, suivi de l’horodatage, puis de l’utilisateur ayant lancé le job. exemple 2 : at 4:00 AM tomorrow at> rm /root/exercicesAT.txt at> Pour supprimer un job at, il faut utiliser son numéro obtenu avec atq : atrm numjob Grâce à l’option -f, suivi du script puis de l’heure on peut lancé directement un bash : ex :  at -f /root/test.sh 10:30 PM Vous pouvez sécuriser la commande at, grâce au fichier /etc/at.allow pour placer dans ce fichier les utilisateurs autorisés (whitelist) Ex :  nano /etc/at.allow Awk Cette commande agit comme un filtre programmable, prenant une série de lignes en entrée (par fichier, ou via l’entrée standard) et écrivant sur la sortie standard (redirigeable). Awk prend en entrée les lignes une par une et choisit les lignes à traiter (ou non) par des expressions rationnelles ou des numéros de lignes. Une fois la ligne sélectionnée, elle est découpée en champs, selon un séparateur d’entrée indiqué dans le programme awk par le symbole FS (par défaut espace et tabulation). Puis les différents champs sont disponibles dans les variables ($1, $2, $3, $NF pour le dernier). Vous pourrez aussi trouver des fichiers .awk qui sont des scripts écrits dans ce langage. awk [-F] '{action-awk}' [ fichier1 fichier2 ..... fichiern ] La commande prend en paramètre la liste des fichiers à traiter, si des fichiers ne sont pas spécifiés, awk travaillera sur l’entrée standard. On peut donc placé la commande derrière un tube de communication. L’option “-F” permet d'initialiser si besoin la variable “FS” (Field Separator). Voici une liste des variables prédéfinies au lancement de awk: Variables Valeur par défaut Rôle RS Newline (\n) Record Separator : Caractère séparateur d’enregistrement (lignes) FS Suite d’espaces et ou de tabulation Field Separator : caractères séparateurs de champs. OFS Espace Output Field Separator: Séparateur de champ pour l’affichage ORS Newline (\b) Output Record Separator : Séparateur de ligne pour la sortie ARGV - Tableau initialisé avec les arguments de la ligne de commande (awk inclus) ARGC - Nombre d’arguments dans le tableau ARGV ENVIRON Variables d’environnement exportées par le shell Tableau contenant les variables d’environnement exportées par le shell. CONVFMT %.6g Format de conversion des nombres en string OFTM %.6g Format de sortie des nombres. SUBSEP \0.34 Caractère de séparation pour les routines internes de tableaux. Attention : Lorsque que la variable FS a plus de 2 caractères, elle sera interprété comme une expression régulière Voici les variables qui sont initialisées lors du traitement d’une ligne Variable Rôle $0 Valeur de l’enregistrement courant NF $1 contient la valeur du 1er champ, $2 du 2ème, ... et $NF le dernier $1,$2, .. $NF $1 contient la valeur du 1er champ, $2 du 2ème, ... et $NF le dernier NR Number : indice de l’enregistrement courant (NR vaut 1 quand la 1ère ligne est en cours de traitement) FNR File Number : indice de l’enregistrement courant relatif au fichier en cours de traitement FILENAME Nom du fichier en cours de traitement RLENGTH Longueur en string trouvé par la fonction match() RSTART Première position du string trouvé par la fonction match Exemple d’utilisation : ps -ef| awk ‘{print $1,$8}’ La partie en gras représente entre quote permet d’éviter l’interprétation par le shell et indique à awk quelle fonction exécuter sur le traitement du awk. Les instructions doivent être placées entre accolades. La fonction intégrée print va afficher à l’écran les champs 1 et 8 de chaque ligne. Voici un autre exemple : ps -ef | awk ‘{print “User : “, $1, “\tCommande : “, $8}’ Critères de sélection : Il est possible de sélectionner les enregistrements sur lesquels l’action doit être exécutée :  awk [-F] 'critère {action-awk}' [fichier1 fichier2 ... fichiern] Le critère de sélection peut s’exprimer de différentes manières. Expression régulières : awk -F’:’ ‘/\/bin\/false/ {print $0}’ /etc/passwd Par défaut, c’est le champ correspondant au $0 qui est mis en correspondance avec l’expression régulière., mais il est possible de le spécifier avec l’opérateur de concordance “~” ou de non concordance “!~”. awk -F ':' '$6 ~ /^\/usr/ {print $0}' /etc/passwd Test logiques : Le critère peut être une expression d’opérateurs renvoyant vrai ou faux. Par exemple, pour afficher uniquement les lignes impaires du fichier /etc/passwd awk -F':' 'NR%2 {print $0}' /etc/passwd Find Introduction Les exemples de ce tuto sont tous à faire en user sauf spécification. Cette commande permet de faire des recherches de fichier ou de dossier dans une hiérarchie de répertoires. Par exemple, je voudrais chercher le log messages, mais je sais pas où se trouve ce fichier, faites : find / -name 'messages' résultat de la commande précédente /var/log/messages Voilà la réponse : Il se trouve dans le répertoire /var/log. Nota Notez l'utilisation des apostrophes afin d'éviter que l'interpréteur de commande n'étende le motif. Elles sont inutiles dans ce cas-ci mais c'est une bonne pratique de toujours les utiliser afin d'éviter l'extension motif. Quelques options Options Fonctions -atime n ou +n ou -n trouve les fichiers auxquels on a accédé il y a strictement n jours, ou plus de n jours, ou moins de n jours -mtime n ou +n ou -n trouve les fichiers modifiés il y a strictement n jours, ou plus de n jours, ou moins de n jours -maxdepth n définit le niveau maximum de sous-répertoire à explorer -type l ou d ou f indique le type de fichier à rechercher (l pour lien symbolique, d pour répertoire (directory), f pour fichier) -name recherche par motif en respectant la casse -iname recherche par motif sans respecter la casse Recherche simple par nom Example simple : comment trouver un fichier portant le nom note ? find / -name 'note' Décomposition de la commande de l'exemple : “ /” indique que nous voulons chercher notre fichier à partir de la racine. “ -name ” est l'option qui indique ici que nous voulons spécifier le nom d'un fichier. Après un long délai d'attente, la recherche se faisant dans toute l'arborescence de la partition, la réponse finit par venir : résultat de la commande précédente /home/martin/note Si l'on n'est pas sûr de la casse (Majuscule ou minuscule) on utilise l'option -iname. Règle générale, on recherche rarement un fichier depuis la racine. Prenons un autre exemple. Pour chercher tous les fichiers commençant par note et définir à partir de quel répertoire on souhaite effectuer la recherche on utilise cette syntaxe : find /home/martin -name 'note*' Recherche par nom simple & multiple Maintenant, regardons, encore une fois à l'aide d'un exemple, la syntaxe de la commande find si l'on recherche plutôt un ou plusieurs répertoires. Je cherche à trouver les répertoires archives dans /media/homebis. Première chose à noter, il peut-être nécessaire de se mettre en root pour avoir accès à tous les répertoires. find /media/homebis -type d -name 'archives' Dans ce cas-ci, je demande donc à find de trouver les répertoires option : -type argument : “d” (comme “directory”) indiquant que l'on cherche un répertoire du nom de archives à partir du répertoire /media/homebis. La réponse : résultat de la commande précédente /media/homebis/martin/textes/mes_archives/Baseball/archives /media/homebis/martin/archives /media/homebis/Documents_gr/Mots_croises/archives /media/homebis/Documents_gr/archives /media/homebis/Documents_gr/mes_fichiers/archives Autre exemple un peu plus complexe cette fois. Je désire faire une recherche de tous les fichiers audio de type .mp3 et .ogg Il existe plus d'une façon d'y arriver. Voyons comment on peut s'y prendre. Première façon : find /home/martin/ \( -name '*.mp3' -o -name '*.ogg' \) On peut noter l'utilisation du -o qui correspond à l'opérateur ou (“or” en anglais) Cela me donnera toute une liste de fichiers /home/martin/… Deuxième façon : Une autre manière d'écrire la commande ci-dessus est la suivante : find -type f -name "*.mp3" -o -name "*.ogg" Si je tape cette commande en étant dans mon répertoire /home/martin, le résultat sera une liste de fichiers ./…. Il est intéressant de savoir que l'on peut étendre la recherche aux fichiers mp3 et mp4 en remplaçant le 3 par un ?2). La commande deviendrait donc : find -type f -name "*.mp?" -o -name "*.ogg" Rechercher pour supprimer Une fonction intéressante de find est de supprimer en lot les fichiers trouvés. Il n'est point rare de télécharger ou d'installer de nombreux fichiers qui ne nous servent plus, mais devant le travail pénible de devoir supprimer tous ces fichiers, on repousse au lendemain cette charge. Heureusement grâce à la fonction -delete de find, c'est un pur bonheur. Paramètre -delete Exemple, si dans votre home ou autre dossier vous avez beaucoup de fichier .tar.gz qui ne vous servent plus à rien. Il suffit de lancer la commande suivante : find -iname "*.tar.gz" -delete Attention, la fonction -delete ne vous demande pas de confirmation Supprimer avec demande de confirmation Pour une demande de confirmation avant suppression de chaque fichier “.tar.gz” trouvés : find -iname "*.tar.gz" -ok rm {} \; Merci à MicP pour cette trouvaille :) Filtrer en fonction des droits Une option très pratique est -perm qui permet de sélectionner des fichiers en fonctions de leurs droits. Les droits peuvent être donné en forme octale, par exemple 0755 ou littérale, u=rwx,g=rw,o=rw. Voici par exemple comment obtenir la liste de tout les fichiers dans le repertoire /bin qui ont le bit setuid valant 1 : find /bin -perm /5000 -user root résultat de la commande précédente /bin/su /bin/mount /bin/umount /bin/ping /bin/ping6 Cette option est intéressante pour la sécurité. Les fichiers listés dans la commande précédente sont tous exécuté avec les droits root. Trois notations avec perm, sans préfixe, précédé du signe – ou précédé du signe / sans préfixe : le mode du fichier doit être exactement celui passé à l’option -perm. Par exemple, si on cherche les fichiers ayant le mode u=rwx (0700), tous les fichiers que l’on trouvera auront exactement le mode u=rwx (0700). avec le signe – : le mode du fichier doit être au moins égal à celui passé à l’option -perm -u=r (-0400) → u=r ou u=rw ou u=rx ou u=rwx ou u=r,g=x … avec le signe / : un des modes (user, group ou other) doit être au moins égal à ceux passés à l’option -perm /u=w,g=w,o=w → u=w ou g=w ou o=w ou u=w,g=w,o=w ou u=rw,g=rwx … Recherche par motif Pour rechercher un motif, il faut utiliser la même option, et utiliser les REGEXP. Voici par exemple la recherche de tous les fichiers terminant par .java dans le dossier courant: find . -name '*.java' résultat de la commande précédente ./java/jdk1.5.0_06/demo/applets/Animator/Animator.java ./java/jdk1.5.0_06/demo/applets/ArcTest/ArcTest.java ./java/jdk1.5.0_06/demo/applets/BarChart/BarChart.java ./java/jdk1.5.0_06/demo/applets/Blink/Blink.java ./java/jdk1.5.0_06/demo/applets/CardTest/CardTest.java ... Rechercher les fichiers n'appartenant pas à l'utilisateur Il peut parfois être utile de rechercher les fichiers n'appartenant pas à l'utilisateur, en vue de corriger un problème rencontré avec une application (par exemple, un fichier peut appartenir à root au lieu d'appartenir à l'utilisateur ; ce dernier risque de ne pas avoir de droits dessus, ce que peut alors provoquer une erreur dans une application cherchant à modifier le dit fichier). Pour ce faire, il suffit d'exécuter là commande suivante, où « utilisateur » est à remplacer par votre nom d'utilisateur : find /home/utilisateur ! -user utilisateur ou bien, en utilisant des variables : find $HOME ! -user $USER Pour avoir davantage d'informations sur les fichiers ainsi trouvés, vous pouvez ajouter l'option ls : find $HOME ! -user $USER -ls -exec - Exécuter une commande La commande find permet d'effectuer toute sorte d'action avec les fichiers trouvés. Une action très utile est “ -exec” qui permet d'exécuter une commande sur les fichiers sélectionnés. La syntaxe de exec est particulière car il faut pouvoir fournir le nom du fichier trouvé. À la suite de la commande find habituelle, la syntaxe est : find /chemin/du/fichier/