Organizaremos o comando sh -c e o comportamento ao chamar um script a partir dele, especialmente como os arquivos de configuração em torno do zsh (.zshrc, etc.) são lidos.
Este é o ponto onde você pode facilmente se conectar aos pontos de entrada do Docker, configurações de CI/CD e chamadas de ferramentas externas.
O que é sh-c?
Resumindo, ele “interpreta a sequência de argumentos como um comando e o executa”.
sh -c "echo Hello World"Estou falando sobre como é diferente de digitar um comando normalmente, mas é necessário principalmente nas cenas a seguir.
Quando você deseja redirecionar com sudo
sudo echo "text" > /etc/file resulta em um erro de permissão. Isso ocorre porque o redirecionamento é executado com privilégios gerais de usuário.
sudo sh -c "echo 'text' > /etc/file" é bem-sucedido porque todo o shell é executado como root.
Quando você quiser usar && ou | com Docker/K8s
Se você deseja conectar vários comandos ou usar um canal com CMD ou ENTRYPOINT, a sintaxe não será analisada a menos que você passe pelo shell.
Quando você deseja executar binários Go etc. via sh
sh ./my-binary causa um erro porque “tenta ler o binário como um script de shell.”
sh -c ./my-binary diz “Execute o comando nesse caminho”, então ele pode ser executado mesmo em binário.
Regras de herança de variáveis de ambiente
As variáveis de ambiente são passadas para o script chamado com sh -c?
código de verificação
# 親側export MY_ENV="hoge"sh -c "./sample.sh"echo "$MY_ENV"Resultados
- Capa se exportada (
hogeaparece) - Não passa se não for exportado (ficará vazio)
A variável export é herdada do processo filho (sh -c) para o processo neto (sample.sh). Claro, você precisa estar ciente de que sh -c iniciará um processo separado.
Shebang é eficaz?
Ao chamar o script para zsh de main.sh via sh -c.
principal.sh```sh sh -c ”./sample.sh”
**amostra.sh**```sh#!/usr/bin/env zsh# zsh特有の処理...Resultados
**Funciona corretamente como zsh. **
sh funciona simplesmente como um iniciador, e o sistema operacional olha para a primeira linha (Shebang) de sample.sh e inicia o zsh.
Porém, ao ler com fonte (ou .), é NG.
- ✅
sh -c "./sample.sh"→ zsh inicia e executa (Shebang habilitado) - ❌
sh -c ". ./sample.sh"→ Carregado como sh (Shebang ignorado = erro de sintaxe)
O arquivo de configuração zsh foi lido?
Quando sample.sh (script zsh) é executado, .zshrc e .zprofile são carregados?
Conclusão: dificilmente carregado
| Nome do arquivo | Carregado? | Motivo |
|---|---|---|
.zshenv | SIM | Apenas leia. Válido em todos os modos. |
.zprofile | NÃO | Ignorado porque não é um “shell de login”. |
.zshrc | NÃO | **Ignorado porque não é um “shell interativo”. ** |
.zlogin | NÃO | Ignorado porque não é um “shell de login”. |
Ao executar um script (modo não interativo), .zshrc é ignorado para evitar saídas ou aliases desnecessários.
Esta é a razão pela qual o alias escrito em .zshrc não funciona no script.
Se você realmente deseja carregá-lo
A única opção é explicitamente source no script.
#!/usr/bin/env zshsource ~/.zshrc # 無理やり読み込む
my_alias_commandNo entanto, se .zshrc contiver saída como echo, ela será misturada com a saída do script, portanto, isso não é recomendado.
A resposta correta é escrever as variáveis de ambiente exigidas pelo script em .zshenv (independentemente de serem boas ou ruins).
resumo
sh -c é conveniente, mas pode ficar confuso se você não entender os limites do processo e as regras de carregamento do arquivo de configuração.
Principalmente em ambientes Docker e CI/CD, mesmo que funcione localmente, pode não funcionar dentro do contêiner. Isso geralmente é causado pelo esquecimento da variável de ambiente export ou pela dependência de .zshrc.
É seguro consolidar as configurações usadas em scripts em .zshenv e usar funções e scripts em vez de aliases.
hsb.horse