Por que sh (não bash) está reclamando de funções definidas no meu .bashrc?

11

Estou recebendo este quando abro uma sessão de terminal:

sh: erro ao importar a definição da função para `read.json '

sh: erro ao importar a definição da função para `ts-project '

sh não gosta dessas funções porque elas se parecem com:

read.json(){
   ::
}

e

ts-project(){
   ::
}

a verdadeira questão é: por que shtocar / interpretar esses arquivos? Estou no MacOS e já vi isso antes, é um mistério. Eu acho que apenas o bash estaria carregando esses arquivos.

update : bash e sh não são nada fora do comum. quando digito bash no terminal, recebo o seguinte:

alex$ bash
beginning to load .bashrc
finished loading .bashrc
bash-3.2$ 

quando digito sho terminal, recebo o seguinte:

alex$ sh
sh: error importing function definition for `read.json'
sh: error importing function definition for `ts-project'
sh-3.2$ 
Alexander Mills
fonte
1
Talvez o / bin / sh seja bash nesse sistema?
Jeff Schaller
1
nenhum deles se fonte, descobri que era uma prática ruim da maneira mais difícil. no entanto, ~ / .profile está adquirindo um arquivo bash compartilhado, então talvez shseja o que origina o arquivo .profile?
Alexander Mills
1
As informações sobre ter um arquivo ~ / .profile que origina o arquivo compartilhado parecem importantes para mim.
Jeff Schaller
3
O que eu quis dizer com / bin / sh bash é que é possível que ele esteja vinculado ou vinculado ao bash. O Bash emula sh, mas também fontes ~ / .profile. Eu simplesmente não sei como os pacotes OSX se misturam.
Jeff Schaller
3
Eles são construídos a partir da mesma bashfonte, uma com STRICT_POSIXa outra sem ela.
mosvy

Respostas:

20

Esse erro ocorre quando o bashdisfarce como um shell POSIX tenta importar essas funções do ambiente, não ao carregá-las, interpretando um arquivo como ~/.bashrcesse. Exemplo simplificado:

foo.bar(){ true; }; export -f foo.bar; bash --posix -c true
bash: error importing function definition for `foo.bar'

Eu esperava bashnão carregar funções do ambiente quando estava no modo posix, mas sim , e só reclama quando seus nomes contêm caracteres engraçados.

Observe que bashtambém será executado no modo posix quando a variável de ambiente POSIXLY_CORRECTou POSIX_PEDANTICestiver definida ou quando foi compilada com --enable-strict-posix-default/ STRICT_POSIX.

Este último parece ser o caso para /bin/shno MacOS (olhar aqui para PRODUCT_NAME = sh), onde eu espero que este erro também gatilho quando usando funções de biblioteca como popen(3)ou system(3).

mosvy
fonte
3
A correção: não exporte funções no ambiente. É o anti-recurso do bash que levou ao (ou melhor, foi simplesmente) o Shellshock e deveria ter sido removido, mas não foi porque as pessoas o estão usando tolamente. Não seja um deles.
R .. GitHub Pare de ajudar o gelo
O fato de o bash importar funções, mesmo quando chamado, shé o que tornou a vulnerabilidade do shellshock / bashdoor muito pior.
Stéphane Chazelas 27/08/19
Veja também SHELLOPTS=posixe -o posixpara outras formas de ativar o modo posix.
Stéphane Chazelas 27/08/19
Observe também que set -a/ set -o allexporttambém faz com que bash para exportar todas as funções (e se invocado como sh, provoca POSIXLY_CORRECTa ser definido e exportados!)
Stéphane Chazelas
( sh -acausas POSIXLY_CORRECTa serem definidas e exportadas; set -adepois que o shsem -afoi iniciado não exporta POSIXLY_CORRECTporque foi definido antes -aestava em vigor).
Stéphane Chazelas 27/08/19
5

Para responder à parte sobre o porquê read.jsone ts-projectnão são nomes de funções portáteis:

De acordo com o POSIX, uma definição de função deve ser nomeada por

uma palavra que consiste apenas de sublinhados, dígitos e alfabéticos do conjunto de caracteres portátil. O primeiro caractere de um nome não é um dígito.

Também conhecido como identificador , na linguagem C. Ou no regex:[_a-zA-Z][0-9_a-zA-Z]*

user2394284
fonte
Mas o POSIX não proíbe as implementações de aceitar outros nomes para funções, portanto, o bash não precisou impor essas restrições no modo POSIX. nomes de função compartilham o mesmo espaço de nomes como argumentos do comando, então não há nenhuma razão para aceitar apenas qualquer coisa (como zsh/ rc/ fish...)
Stéphane Chazelas
@ StéphaneChazelas: Eu sei, mas o que significa estar no modo POSIX, se não "derramou todas as extensões", como em "não as aceite silenciosamente"?
user2394284
@ user2394284 certamente não significa que em bash, ou que seria funções não importação do ambiente, enquanto no modo POSIX, o que não é exigido pelo POSIX especificação ;-)
mosvy
@mosvy: Sim, é evidente que o bash falhou em algum lugar ao longo do caminho - eu diria que é um shell POSIX simples, o que seria um bug.
user2394284
0

Então, o que causou foi que eu estou fornecendo alguns scripts bash no meu arquivo ~ / .bashrc da seguinte forma:

for f in "$HOME/.oresoftware/bash/"*; do
   . "$f"
done;

então eu mudei para:

for f in "$HOME/.oresoftware/bash/"*; do
  if [[ "$(basename "$0")" != 'sh' ]]; then
      # source only if not using sh
      . "$f"
  fi
done;

portanto, em teoria, se for chamado até shentão, ele não tentará obter esses arquivos, mas não tem certeza se isso funciona 100% do tempo.

Alexander Mills
fonte