J'ai essayé ce qui suit mais cela ne semble pas fonctionner:
$ cat script.sh
#!/bin/env -i /bin/sh
/bin/env
$ script.sh
/bin/env: invalid option -- ' '
Try `/bin/env --help' for more information.
bash
shell-script
env
balki
la source
la source
Réponses:
La raison pour laquelle cela ne fonctionne pas est qu'il considère
-i /bin/sh
comme un argument unique àenv
. Habituellement, ce serait 2 arguments,-i
et/bin/sh
. Ce n'est qu'une limitation du shebang. Pas question.Cependant, vous pouvez toujours effectuer cette tâche, d'une manière différente.
Si vous voulez que cette tâche soit exécutée par le script lui-même et que vous n'ayez pas à faire quelque chose comme cela
env -i script.sh
, vous pouvez demander au script de se réexécuter lui-même.Cela entraînera le script à se réexécuter si la
CLEANED
variable d'environnement n'est pas définie. Ensuite, lors de la réexécution, il définit la variable pour s'assurer qu'elle n'entre pas dans une boucle.la source
env
des coreutils GNU ont maintenant une option-S
pour contourner les problèmes similaires à celui-ci mais pas exactement les mêmes. Par exemple#!/usr/bin/env -S perl -T
.#!/usr/bin/env -S -i /bin/sh
. Soyez conscient des problèmes de portabilité.Exécutez votre script avec
env -i
:Et le script comme d'habitude:
Si vous voulez exécuter avec un environnement propre sans le dire explicitement lorsque vous exécutez. Eduardo Ivanec donne quelques idées dans cette réponse , vous pouvez appeler récursivement votre script
exec
lorsque l'environnement n'est pas propre (par exemple $ HOME est défini):la source
Avec bash, vous pouvez le faire comme ceci:
Les commandes
set -e
etset -u
ne sont pas strictement nécessaires, mais je les inclue pour démontrer que cette approche ne repose pas sur l'accès aux variables non définies (comme par exemple le[ "$HOME" != "" ]
ferait) et est compatible avec unset -e
paramètre.Le test de la
HOME
variable doit être sûr car bash exécute des scripts en mode non interactif, c'est-à-dire que les fichiers de configuration comme~/.bashrc
(où les variables d'environnement peuvent être définies) ne sont pas fournis lors du démarrage.Exemple de sortie:
la source
Malheureusement, cela ne fonctionnera pas de cette façon - Linux considère
-i /bin/sh
comme un argument à passerenv
(voir Shebang ).la source
La limitation de shebang à 2 arguments Linux (interpètre + argument unique) est notée dans la plupart des réponses, mais dire que cela ne peut pas être fait est incorrect - il vous suffit de passer à un interpréteur qui peut faire quelque chose d'utile avec un seul argument:
Ce que cela fait, c'est invoquer
perl
avec un script à une ligne (-e
) qui efface%ENV
(moins cher queenv -i
) et invoqueexec /bin/sh
, en citant correctement les arguments. Plus loinperl
logique peut être ajoutée, si nécessaire (mais pas beaucoup sur Linux car vous êtes limité auxBINPRM_BUF_SIZE
caractères, ce qui est probablement 128)Malheureusement, ceci est spécifique à Linux, cela ne fonctionnera pas sur un système qui autorise plusieurs arguments shebang: - /
perl
traite cette chaîne comme un seul argument, elle n'est donc pas citée ci-dessus comme vous le feriez normalement avecperl -e ...
la ligne de commande (si vous deviez ajouter des guillemets, ceux-ci sont conservés, perl ne voit qu'une chaîne littérale, avec des avertissements dessus, il se plaindra d'une inutilité constant).Notez également qu'il y a un léger changement de comportement lorsqu'il est utilisé de cette façon,
@ARGV
contient normalement uniquement les arguments et$0
contient le script, mais avec ce shebang$ARGV[0]
est le nom du script (et$0
est-e
) ce qui le rend un peu plus facile.Vous pouvez également résoudre ce problème avec un interpréteur qui "retire" sa ligne de commande (sans
-c
argument supplémentaire ) que l'ancien AT&Tksh93
fait:mais peut-être
ksh
n'est - pas aussi courant de nos jours ;-)(
bash
a une fonctionnalité similaire avec--wordexp
, mais il est "non documenté" dans les versions où il fonctionne, et n'est pas activé au moment de la compilation dans les versions où il est documenté: - / Il ne peut pas non plus être utilisé pour cela car il a besoin de deux arguments. ..)Aussi, effectivement une variation sur les réponses de @Patrick et @ maxschlepzig:
Plutôt que d'utiliser une nouvelle variable, cela utilise la variable spéciale "
_
", si elle n'est pas définie sur exactement "bash", remplacez le script enexec
utilisant-a
pour faireARGV[0]
(et donc$_
) juste "bash", et en utilisant-c
pour effacer l'environnement.Alternativement, s'il est acceptable de nettoyer l'environnement au début du script (bash uniquement):
Qui utilise
compgen
(aide à l'achèvement) pour répertorier les noms de toutes les variables d'environnement exportées, etunset
s en une seule fois.Voir aussi Arguments multiples dans shebang pour plus de détails sur le problème général du comportement de shebang.
la source