Stations de travail en ligne OnWorks Linux et Windows

Logo

Hébergement gratuit en ligne pour les postes de travail

<Précédent | Table des matières | Suivant>

IFS

Normalement, le shell effectue le fractionnement des mots sur l'entrée fournie à lire. Comme nous l'avons vu, cela signifie que plusieurs mots séparés par un ou plusieurs espaces deviennent des éléments distincts sur la ligne d'entrée et sont affectés à des variables distinctes par lire. Ce comportement est configuré par une variable shell nommée IFS (pour le séparateur de champ interne). La valeur par défaut de IFS contient un espace, une tabulation et un caractère de nouvelle ligne, chacun séparant les éléments les uns des autres.

Nous pouvons ajuster la valeur de IFS pour contrôler la séparation des champs entrés lire. Par exemple, le / Etc / passwd Le fichier contient des lignes de données qui utilisent le caractère deux-points comme séparateur de champ. En changeant la valeur de IFS à un seul deux-points, nous pouvons utiliser lire pour saisir le contenu de / Etc / passwd et séparez avec succès les champs en différentes variables. Ici, nous avons un script qui fait exactement cela :



#! / Bin / bash

# read-ifs : lit les champs d'un fichier FILE=/etc/passwd

#! / Bin / bash

# read-ifs : lit les champs d'un fichier FILE=/etc/passwd


read -p "Entrez un nom d'utilisateur > " user_name file_info=$(grep "^$user_name:" $FILE) if [ -n "$file_info" ]; alors

IFS=":" read user pw uid gid name home shell <<< "$file_info" echo "User = '$user'"

echo "UID = '$uid'"

echo "GID = '$gid'" echo "Nom complet = '$nom'" echo "Home Dir. = '$home'" echo "Shell = '$shell'"

d'autre

echo "Aucun utilisateur de ce type '$user_name'" >&2 exit 1

fi

read -p "Entrez un nom d'utilisateur > " user_name file_info=$(grep "^$user_name:" $FILE) if [ -n "$file_info" ]; alors

IFS=":" read user pw uid gid name home shell <<< "$file_info" echo "User = '$user'"

echo "UID = '$uid'"

echo "GID = '$gid'" echo "Nom complet = '$nom'" echo "Home Dir. = '$home'" echo "Shell = '$shell'"

d'autre

echo "Aucun utilisateur de ce type '$user_name'" >&2 exit 1

fi


Ce script invite l'utilisateur à saisir le nom d'utilisateur d'un compte sur le système, puis affiche les différents champs présents dans la fiche de l'utilisateur dans le / Etc / passwd déposer. Le script contient deux lignes intéressantes. Le premier est :

file_info=$(grep "^$user_name :" $FILE)

Cette ligne affecte les résultats d'un grep commande à la variable info_fichier. L'expression régulière utilisée par grep garantit que le nom d'utilisateur ne correspondra qu'à une seule ligne dans le / Etc / passwd fichier.

La deuxième ligne intéressante est celle-ci :

IFS=":" read user pw uid gid name home shell <<< "$file_info"

La ligne se compose de trois parties : une affectation variable, une lire commande avec une liste de noms de variables comme arguments et un nouvel opérateur de redirection étrange. Nous examinerons d'abord l'affectation des variables.

Le shell permet à une ou plusieurs affectations de variables d'avoir lieu juste avant une commande. Ces affectations modifient l'environnement de la commande qui suit. L'effet de la cession est temporaire; ne changeant l'environnement que pendant la durée de la commande. Dans notre cas, la valeur de IFS est remplacé par un caractère deux-points. Alternativement, nous aurions pu le coder de cette façon:

OLD_IFS="$IFS" IFS=":"

read user pw uid gid name home shell <<< "$file_info" IFS="$OLD_IFS"

où nous stockons la valeur de IFS, attribuez une nouvelle valeur, effectuez la lire commande, puis restaurer IFS à sa valeur d'origine. Il est clair que placer l'affectation de variable devant


la commande est une manière plus concise de faire la même chose.

La << l'opérateur indique un ici chaîne. Une chaîne here est comme un document here, seulement plus court, composé d'une seule chaîne. Dans notre exemple, la ligne de données du

Le fichier /etc/passwd est envoyé à l'entrée standard de la commande de lecture. Nous pourrions gagner-

der pourquoi cette méthode plutôt oblique a été choisie plutôt que :

echo "$info_fichier" | IFS=":" read user pw uid gid name home shell

image

Eh bien, il y a une raison...


Vous ne pouvez pas lire la pipe

Tandis que le lire commande prend normalement l'entrée de l'entrée standard, vous ne pouvez pas faire ceci :

echo "toto" | lire

Nous nous attendrions à ce que cela fonctionne, mais ce n'est pas le cas. La commande semblera réussir mais le RÉPONDRE variable sera toujours vide. Pourquoi est-ce?

L'explication a à voir avec la façon dont le shell gère les pipelines. Dans bash (et d'autres coquillages comme sh), les pipelines créent sous-coquilles. Ce sont des copies du shell et de son environnement qui sont utilisées pour exécuter la commande dans le pipeline. Dans notre exemple ci-dessus, lire est exécuté dans un sous-shell.

Les sous-shells dans les systèmes de type Unix créent des copies de l'environnement que les processus utiliseront pendant leur exécution. Lorsque les processus se terminent, la copie de l'environnement est détruite. Cela signifie que un sous-shell ne peut jamais modifier l'environnement de son processus parent. lire attribue des variables, qui font alors partie de l'environnement. Dans l'exemple ci-dessus, lire attribue la valeur "foo" à la variable RÉPONDRE dans l'environnement de son sous-shell, mais lorsque la commande se termine, le sous-shell et son environnement sont détruits et l'effet de l'affectation est perdu.

L'utilisation de chaînes ici est une façon de contourner ce problème. Une autre méthode est discutée au chapitre 36.


Meilleur système d'exploitation Cloud Computing chez OnWorks :