2010-06-11 4 views
1

Je souhaite générer un script, imprimer la valeur d'une variable définie par ce script, puis attribuer cette valeur à une variable de la ligne de commande avec substitution de commande enveloppant les commandes source/print. Cela fonctionne sur ksh88 mais pas sur ksh93 et ​​je me demande pourquoi.Erreur inconnue lors de l'approvisionnement d'un script contenant 'typeset -r' enveloppé dans la substitution de commande

$ cat typeset_err.ksh 
#!/bin/ksh 
unset _typeset_var 
typeset -i -r _typeset_var=1 
DIR=init # this is the variable I want to print 

Lorsqu'il est exécuté sur ksh88 (dans ce cas, une boîte AIX 6.1), la sortie se présente comme suit:

$ A=$(. ./typeset_err.ksh; print $DIR) 
$ echo $A 
init 

Lorsqu'il est exécuté sur ksh93 (dans ce cas, une machine Linux), le sortie est la suivante:

$ A=$(. ./typeset_err.ksh; print $DIR) 
-ksh: _typeset_var: is read only 
$ print $A 

($ A est non définie)

Ce qui précède est juste un exemple de script. La chose réelle que je souhaite accomplir est de source un script qui définit des valeurs à beaucoup de variables, de sorte que je puisse imprimer juste une de ses valeurs, par ex. $DIR, et ont $A égal à cette valeur. Je ne sais pas à l'avance la valeur de $DIR, mais j'ai besoin de copier des fichiers à $DIR lors de l'exécution d'un script batch différent. Par conséquent, l'idée que j'ai eu était de trouver le script afin de définir ses variables, d'imprimer celui que je voulais, puis d'affecter la sortie de cette impression à une autre variable via la syntaxe $(...). Certes un peu un hack, mais je ne veux pas trouver le sous-script entier dans l'environnement du script batch car j'ai seulement besoin d'une de ses variables.

Le code -r au début est l'erreur. Le script que j'utilise contient ceci afin de fournir un sémaphore - pour éviter que le script ne soit trouvé plus d'une fois dans l'environnement. (Il y a une instruction if dans le vrai script qui vérifie _typeset_var = 1, et se termine si elle est déjà définie.) Donc je sais que je peux sortir ceci et obtenir $DIR pour imprimer correctement, mais les contraintes du problème incluent garder le typeset -i -r.

Dans l'exemple de script, j'ai placé un unset en premier, pour m'assurer que _typeset_var n'est pas déjà défini. Par ailleurs, je sais qu'il n'est pas possible d'annuler la variable, d'après la page de manuel de ksh93 pour ksh.

Il existe plusieurs façons de contourner cette erreur. Le favori est maintenant de ne pas utiliser la composition, mais de définir le sémaphore sans composer (par exemple _typeset_var=1), mais l'erreur avec le code tel quel est toujours une curiosité pour moi, et je veux voir si quelqu'un peut expliquer pourquoi cela se produit . Par ailleurs, une autre idée que j'ai abandonnée était grep la variable dont j'ai besoin en dehors de son script contenant, puis j'imprime cette variable pour $A; cependant, la variable ($DIR dans l'exemple ci-dessus) peut être définie sur la valeur d'une autre variable (par exemple DIR=$dom/init), et cette autre variable peut être définie plus tôt dans le script; par conséquent, j'ai besoin de source le script entier pour m'assurer que toutes les variables sont définies de sorte que $DIR est correctement défini lors de l'approvisionnement.

Répondre

1

Cela fonctionne très bien pour moi dans ksh93 (Version JM 93t + 2009-05-01). Si je fais cela, cependant:

$ . ./typeset_err.ksh 
$ A=$(. ./typeset_err.ksh; print $DIR) 
-ksh: _typeset_var: is read only 

Il est peut-être que vous obtenez cette variable typeset -r dans l'environnement actuel en quelque sorte.

+1

@Bernard: Les appels répétés pour moi imprimer "init" à chaque fois. –

+0

Excuses de ne jamais suivre cela avec certitude. Je l'ai revisité à nouveau et dans mon exemple simple sur ksh88 et ksh93 cela fonctionne. Mais si je trouve d'abord le script puis l'exécute, sur les deux shells ksh88 et ksh93, il échoue: je pense donc que l'hypothèse de Dennis était correcte, à savoir que j'avais trouvé le script à l'avance et que je ne m'en rendais pas compte. J'étais tellement sûr de ne pas l'avoir fait à ce moment-là! –

1

Essayez cette

A=$(ksh -c "./typeset_err.ksh && print \$DIR") 

ou

A=$(env -i ksh -c "./typeset_err.ksh && print \$DIR") 
+0

Ces deux appels ne provoquent pas d'erreur mais produisent un $ A vide. Si je mets A à quelque chose à l'avance et que j'exécute l'une de ces commandes, $ A finit par être vide. –

Questions connexes