¿Por qué sh (no bash) se queja de las funciones definidas en mi .bashrc?

11

Recibo este cuando abro una sesión de terminal:

sh: error al importar la definición de función para `read.json '

sh: error al importar la definición de la función para 'ts-project'

A sh no le gustan estas funciones porque se ven así:

read.json(){
   ::
}

y

ts-project(){
   ::
}

La verdadera pregunta es: ¿por qué shtocar / interpretar estos archivos? Estoy en MacOS y he visto esto antes, es un misterio. Creo que solo bash estaría cargando estos archivos.

actualización : bash y sh no son nada fuera de lo común. cuando escribo bash en la terminal, obtengo esto:

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

cuando escribo shen la terminal, obtengo esto:

alex$ sh
sh: error importing function definition for `read.json'
sh: error importing function definition for `ts-project'
sh-3.2$ 
Alexander Mills
fuente
1
¿Quizás / bin / sh es bash en ese sistema?
Jeff Schaller
1
ninguno de ellos se buscaban, descubrí que era una mala práctica de la manera más difícil. sin embargo, ~ / .profile está obteniendo un archivo bash compartido, entonces, sh¿cuál es la fuente del archivo .profile?
Alexander Mills el
1
La información sobre tener un archivo ~ / .profile que genera el archivo compartido me parece importante.
Jeff Schaller
3
Lo que quise decir con / bin / sh como bash es que es posible que esté vinculado o enlazado a bash. Bash luego emula sh, pero también genera ~ / .profile. Simplemente no sé cómo los paquetes de OSX sh y bash.
Jeff Schaller
3
Están construidos a partir de la misma bashfuente, uno con STRICT_POSIXel otro sin él.
mosvy

Respuestas:

20

Ese error ocurre cuando se hace pasar bashpor un shell POSIX que intenta importar esas funciones del entorno, no cuando las carga interpretando un archivo como ~/.bashrco tal. Ejemplo simplificado:

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

Esperaba bashno cargar funciones del entorno cuando estaba en modo posix, pero lo hace , y solo se queja cuando sus nombres contienen caracteres divertidos.

Tenga en cuenta que bashtambién se ejecutará en modo POSIX cuando el POSIXLY_CORRECTo POSIX_PEDANTICse establece la variable de entorno, o cuando se compila con --enable-strict-posix-default/ STRICT_POSIX.

Este último parece ser el caso para /bin/shel MacOS (ver aquí para PRODUCT_NAME = sh), donde espero que este error también gatillo cuando el uso de funciones de biblioteca como popen(3)o system(3).

Mosvy
fuente
3
La solución: no exportar funciones en el entorno. Es la anti-característica de bash que condujo a (o más bien, simplemente fue) Shellshock y debería haberse eliminado, pero no fue porque la gente lo esté usando tontamente. No seas uno de ellos.
R .. GitHub DEJA DE AYUDAR AL HIELO
El hecho de que las funciones de importación de bash incluso cuando llaman como shes lo que hizo la shellshock / bashdoor vulnerabilidad de un montón peor.
Stéphane Chazelas
Consulte también SHELLOPTS=posixy -o posixotras formas de habilitar el modo posix.
Stéphane Chazelas
También tenga en cuenta que set -a/ set -o allexporttambién hace que bash exporte todas las funciones (y si se invoca como sh, hace POSIXLY_CORRECTque se configuren y exporten)
Stéphane Chazelas
( sh -ahace POSIXLY_CORRECTque se establezca y se exporte; set -adespués de que se inició shsin, -ano se exporta POSIXLY_CORRECTporque se estableció antes de que -aestuviera vigente).
Stéphane Chazelas
5

Para responder la parte sobre por qué read.jsony ts-projectno son nombres de funciones portátiles:

Según POSIX, una definición de función debe ser nombrada por

una palabra que consiste únicamente en guiones bajos, dígitos y alfabéticos del juego de caracteres portátil. El primer carácter de un nombre no es un dígito.

También conocido como identificador , en C lingo. O en expresiones regulares:[_a-zA-Z][0-9_a-zA-Z]*

usuario2394284
fuente
Pero POSIX no prohíbe que las implementaciones acepten otros nombres para funciones, por lo que bash no tuvo que imponer esas restricciones cuando estaba en modo POSIX. nombres de las funciones comparten el mismo espacio de nombres como argumentos de comandos, así que no hay razón para aceptar simplemente nada (como zsh/ rc/ fish...)
Stéphane Chazelas
@ StéphaneChazelas: Lo sé, pero ¿qué significa estar en modo POSIX, si no "eliminar todas las extensiones", como en "no aceptarlas en silencio"?
user2394284
@ user2394284 ciertamente no significa que en bash, o no importaría funciones del entorno mientras está en modo POSIX, que no es requerido por la especificación POSIX ;-)
mosvy
@mosvy: Sí, es evidente que bash falló en algún lugar del camino; diría que es un shell POSIX simple, lo que sería un error.
user2394284
0

Entonces, lo que causó fue que obtuve algunos scripts de bash en mi archivo ~ / .bashrc de esta manera:

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

así que lo cambié a:

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

así que, en teoría, si se llama para shentonces, no intentará obtener esos archivos, pero no estoy seguro si funciona el 100% del tiempo.

Alexander Mills
fuente