logo hsb.horse
← Retour au blog

Blog

Comportement de sh -c et règles de lecture des fichiers de configuration zsh

Organisé le comportement de la commande sh -c, les règles d'héritage des variables d'environnement, la validité de shebang et la manière dont les fichiers de configuration zsh (.zshrc, .zshenv, etc.) sont lus lors de l'exécution des scripts.

Publié:

Nous organiserons la commande sh -c et le comportement lors de l’appel d’un script à partir de celle-ci, notamment la façon dont les fichiers de configuration autour de zsh (.zshrc, etc.) sont lus.

C’est à ce stade que vous pouvez facilement devenir accro aux points d’entrée Docker, aux paramètres CI/CD et aux appels provenant d’outils externes.

Qu’est-ce que sh -c ?

En bref, il “interprète la chaîne d’argument comme une commande et l’exécute”.

Terminal window
sh -c "echo Hello World"

Je parle de la différence avec la saisie normale d’une commande, mais c’est principalement requis dans les scènes suivantes.

Quand vous souhaitez rediriger avec sudo

sudo echo "text" > /etc/file entraîne une erreur d’autorisation. En effet, la redirection est effectuée avec les privilèges utilisateur généraux.

sudo sh -c "echo 'text' > /etc/file" réussit car l’intégralité du shell s’exécute en tant que root.

Lorsque vous souhaitez utiliser && ou | avec Docker/K8s

Si vous souhaitez connecter plusieurs commandes ou utiliser un tube avec CMD ou ENTRYPOINT, la syntaxe ne sera analysée que si vous passez par le shell.

Lorsque vous souhaitez exécuter des binaires Go, etc. via sh

sh ./my-binary provoque une erreur car il « tente de lire le binaire en tant que script shell ».

sh -c ./my-binary dit « Exécutez la commande dans ce chemin », afin qu’elle puisse être exécutée même en binaire.

Règles d’héritage des variables d’environnement

Les variables d’environnement sont-elles transmises au script appelé avec sh -c ?

le code de vérification

Terminal window
# 親側
export MY_ENV="hoge"
sh -c "./sample.sh"
sample.sh
echo "$MY_ENV"

Résultats

  • Couverture si exporté (hoge apparaît)
  • Ne passe pas s’il n’est pas exporté (sera vide)

La variable export est héritée du processus enfant (sh -c) vers le processus petit-enfant (sample.sh). Bien sûr, vous devez savoir que sh -c lancera un processus distinct.

Shebang est-il efficace ?

Lors de l’appel du script pour zsh à partir de main.sh via sh -c.

main.sh```sh sh -c ”./sample.sh”

**échantillon.sh**```sh
#!/usr/bin/env zsh
# zsh特有の処理...

Résultats

**Cela fonctionne correctement en tant que zsh. **

sh fonctionne simplement comme un lanceur, et le système d’exploitation examine la première ligne (Shebang) de sample.sh et démarre zsh.

Cependant, lors de la lecture avec la source (ou .), c’est NG.

  • sh -c "./sample.sh" → zsh démarre et s’exécute (Shebang activé)
  • sh -c ". ./sample.sh" → Chargé en tant que sh (Shebang ignoré = erreur de syntaxe)

Le fichier de configuration zsh est-il lu ?

Lorsque sample.sh (script zsh) est exécuté, .zshrc et .zprofile sont-ils chargés ?

Conclusion : À peine chargé

Nom du fichierChargé ?Raison
.zshenvOUISeulement lire. Valable dans tous les modes.
.zprofileNONIgnoré car il ne s’agit pas d’un “shell de connexion”.
.zshrcNON**Ignoré car il ne s’agit pas d’un “shell interactif”. **
.zloginNONIgnoré car il ne s’agit pas d’un “shell de connexion”.

Lors de l’exécution d’un script (mode non interactif), .zshrc est ignoré pour éviter les sorties ou alias inutiles.

C’est la raison pour laquelle l’alias écrit dans .zshrc ne fonctionne pas dans le script.

Si vous voulez vraiment le charger

La seule option consiste à explicitement source dans le script.

#!/usr/bin/env zsh
source ~/.zshrc # 無理やり読み込む
my_alias_command

Cependant, si .zshrc contient une sortie telle que echo, elle sera mélangée à la sortie du script, ce n’est donc pas recommandé.

La bonne réponse est d’écrire les variables d’environnement requises par le script dans .zshenv (peu importe si elles sont bonnes ou mauvaises).

résumé

sh -c est pratique, mais cela peut prêter à confusion si vous ne comprenez pas les limites du processus et les règles de chargement des fichiers de configuration.

Surtout dans les environnements Docker et CI/CD, même s’il fonctionne localement, il peut ne pas fonctionner à l’intérieur du conteneur. Ceci est souvent dû à l’oubli de la variable d’environnement export ou à la dépendance à .zshrc.

Il est prudent de consolider les paramètres utilisés dans les scripts dans .zshenv et d’utiliser des fonctions et des scripts au lieu d’alias.