Je confirme, ça me semble aussi pas très clair au premier abord et puis cette fonction a 2 ou 3 défauts.
Pour faire fonctionner cette fonction, il doit y avoir dans le script d'origine (ou dans un fichier de configuration inclus) des déclarations de variables correspondant à l'activation ou non de bibliothèques (c'est l'utilisation la plus probable, j'imagine que c'est dans un script ./configure de compilation ou similaire). Chaque variable est le nom d'une bibliothèque sans le préfixe "lib" et ça va rendre le nommage des variables potentiellement non explicite:
lapack="yes" # Pour liblapack, tout va bien. Maintenant 3 contres exemples: utils="yes" # pour libutils, et non pas "inclure les outils complémentaires ou non." c="yes" # Pour la libc, et non pas un bête compteur. libxml_plus_plus="no" # car on peut mettre l'opérateur + dans un nom de variable.
Ensuite ton appel devait être dans une fonction, seul endroit où l'on utilise return. Par exemple:
Comme te l'apprendra le man de Bash, ${name#lib} sera remplacé par la valeur de la variable name à laquelle on aura retiré le préfixe lib s'il existe. Donc l'appel est en fait "enabled lapack".
Maintenant, le fonctionnement de la fonction elle-même:
Ligne 1: test "${1#!}" = "1ドル" && op== || op=!=
${1#!} : C'est la même chose, on prend le premier argument de la fonction et on retire un point d'esclamation s'il y en a un. test "${1#!}" = "1ドル" : On teste si la valeur sans le point d'esclamation est la même qu'avec. Autrement dit, on teste s'il y a un point d'esclamation ou non.
Si la condition est vraie (&&), op== est exécuté. On peut l'écrire plus explicitement op = "=".
Si la condition est fausse (||), op=!= est exécuté. On peut l'écrire plus explicitement op = "!=".
Donc la ligne 1 stocke un opérateur d'égalité ou de différence on fonction de si l'argument commence par un point d'esclamation ou non. Donc la fonction enabled() sert aussi a tester si une librairie est désactivée, ça fait une fonction de moins mais ça peut être moins lisible quand on lit le code en diagonale.
Ligne 2: eval test "x\$${1#!}" $op "xyes"
On commence par la substitution des variables: ${1#!} devient "lapack" si 1ドル était "!lapack". $op devient != si j'avais un préfixe !, = sinon.
Donc la ligne est: eval test "x\$lapack" != "xyes"
Ensuite la commande eval est exécutée, elle exécute le code qui lui est donné donc, en ayant retiré un niveau de protection: test x$lapack != xyes. Pour faire cette exécution, il y a une dernière substitution de variable (d'où l'utilisation du eval), donc le test est xyes != xyes dans notre cas. test renvoi 1 à eval qui retourne à son tour cette valeur.
Ligne 3: }
La fonction ne contenait pas de return, c'est donc la valeur de la dernière ligne qui est retournée.
Donc dans notre cas, la fonction retourne le 1 du eval. La fonction example() a dit que liblapack n'est pas désactivée.
[^] # Re: Bel exercice
Posté par pma . En réponse au message signification d'un script. Évalué à 5.
Je confirme, ça me semble aussi pas très clair au premier abord et puis cette fonction a 2 ou 3 défauts.
Pour faire fonctionner cette fonction, il doit y avoir dans le script d'origine (ou dans un fichier de configuration inclus) des déclarations de variables correspondant à l'activation ou non de bibliothèques (c'est l'utilisation la plus probable, j'imagine que c'est dans un script ./configure de compilation ou similaire). Chaque variable est le nom d'une bibliothèque sans le préfixe "
lib" et ça va rendre le nommage des variables potentiellement non explicite:lapack="yes"# Pour liblapack, tout va bien. Maintenant 3 contres exemples:utils="yes"# pour libutils, et non pas "inclure les outils complémentaires ou non."c="yes"# Pour la libc, et non pas un bête compteur.libxml_plus_plus="no"# car on peut mettre l'opérateur + dans un nom de variable.Ensuite ton appel devait être dans une fonction, seul endroit où l'on utilise return. Par exemple:
example() {name="liblapack"enabled ${name#lib} || return 0return 1}Comme te l'apprendra le man de Bash, ${name#lib} sera remplacé par la valeur de la variable
nameà laquelle on aura retiré le préfixelibs'il existe. Donc l'appel est en fait "enabled lapack".Maintenant, le fonctionnement de la fonction elle-même:
Ligne 1:
test "${1#!}" = "1ドル" && op== || op=!=${1#!}: C'est la même chose, on prend le premier argument de la fonction et on retire un point d'esclamation s'il y en a un.test "${1#!}" = "1ドル": On teste si la valeur sans le point d'esclamation est la même qu'avec. Autrement dit, on teste s'il y a un point d'esclamation ou non.Si la condition est vraie (
&&),op==est exécuté. On peut l'écrire plus explicitementop = "=".Si la condition est fausse (
||),op=!=est exécuté. On peut l'écrire plus explicitementop = "!=".Donc la ligne 1 stocke un opérateur d'égalité ou de différence on fonction de si l'argument commence par un point d'esclamation ou non. Donc la fonction
enabled()sert aussi a tester si une librairie est désactivée, ça fait une fonction de moins mais ça peut être moins lisible quand on lit le code en diagonale.Ligne 2:
eval test "x\$${1#!}" $op "xyes"On commence par la substitution des variables:
${1#!}devient "lapack" si 1ドル était "!lapack".$opdevient!=si j'avais un préfixe!,=sinon.Donc la ligne est:
eval test "x\$lapack" != "xyes"Ensuite la commande
evalest exécutée, elle exécute le code qui lui est donné donc, en ayant retiré un niveau de protection:test x$lapack != xyes. Pour faire cette exécution, il y a une dernière substitution de variable (d'où l'utilisation dueval), donc le test estxyes != xyesdans notre cas.testrenvoi 1 àevalqui retourne à son tour cette valeur.Ligne 3:
}La fonction ne contenait pas de
return, c'est donc la valeur de la dernière ligne qui est retournée.Donc dans notre cas, la fonction retourne le 1 du
eval. La fonctionexample()a dit que liblapack n'est pas désactivée.