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”.
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
# 親側export MY_ENV="hoge"sh -c "./sample.sh"echo "$MY_ENV"Résultats
- Couverture si exporté (
hogeapparaî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 fichier | Chargé ? | Raison |
|---|---|---|
.zshenv | OUI | Seulement lire. Valable dans tous les modes. |
.zprofile | NON | Ignoré car il ne s’agit pas d’un “shell de connexion”. |
.zshrc | NON | **Ignoré car il ne s’agit pas d’un “shell interactif”. ** |
.zlogin | NON | Ignoré 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 zshsource ~/.zshrc # 無理やり読み込む
my_alias_commandCependant, 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.
hsb.horse