logo hsb.horse
← Voltar para o índice do blog

Blog

Comportamento de sh -c e regras para leitura de arquivos de configuração zsh

Organizou o comportamento do comando sh -c, as regras de herança de variáveis ​​de ambiente, a validade do shebang e como os arquivos de configuração zsh (.zshrc, .zshenv, etc.) são lidos quando os scripts são executados.

Publicado:

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”.

Terminal window
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

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

Resultados

  • Capa se exportada (hoge aparece)
  • 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 arquivoCarregado?Motivo
.zshenvSIMApenas leia. Válido em todos os modos.
.zprofileNÃOIgnorado porque não é um “shell de login”.
.zshrcNÃO**Ignorado porque não é um “shell interativo”. **
.zloginNÃOIgnorado 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 zsh
source ~/.zshrc # 無理やり読み込む
my_alias_command

No 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.