traduccion - eligiendo entre $ 0 y BASH_SOURCE
bash ubuntu (2)
¿Cómo se elige entre
"$0"
y
"${BASH_SOURCE[0]}"
Esta descripción de GNU no me ayudó mucho.
BASH_SOURCE
An array variable whose members are the source filenames where the
corresponding shell function names in the FUNCNAME array variable are
defined. The shell function ${FUNCNAME[$i]} is defined in the file
${BASH_SOURCE[$i]} and called from ${BASH_SOURCE[$i+1]}
Estas secuencias de comandos pueden ayudar a ilustrar. El script externo llama al script central, que llama al script interno:
$ cat outer.sh
#!/usr/bin/env bash
./middle.sh
$ cat middle.sh
#!/usr/bin/env bash
./inner.sh
$ cat inner.sh
#!/usr/bin/env bash
echo "/$0 = ''$0''"
echo "/${BASH_SOURCE[0]} = ''${BASH_SOURCE[0]}''"
echo "/${BASH_SOURCE[1]} = ''${BASH_SOURCE[1]}''"
echo "/${BASH_SOURCE[2]} = ''${BASH_SOURCE[2]}''"
$ ./outer.sh
$0 = ''./inner.sh''
$BASH_SOURCE[0] = ''./inner.sh''
$BASH_SOURCE[1] = ''''
$BASH_SOURCE[2] = ''''
Sin embargo, si cambiamos las llamadas del script a las declaraciones de
source
:
$ cat outer.sh
#!/usr/bin/env bash
source ./middle.sh
$ cat middle.sh
#!/usr/bin/env bash
source ./inner.sh
$ cat inner.sh
#!/usr/bin/env bash
echo "/$0 = ''$0''"
echo "/${BASH_SOURCE[0]} = ''${BASH_SOURCE[0]}''"
echo "/${BASH_SOURCE[1]} = ''${BASH_SOURCE[1]}''"
echo "/${BASH_SOURCE[2]} = ''${BASH_SOURCE[2]}''"
$ ./outer.sh
$0 = ''./outer.sh''
$BASH_SOURCE[0] = ''./inner.sh''
$BASH_SOURCE[1] = ''./middle.sh''
$BASH_SOURCE[2] = ''./outer.sh''
Nota: Para una solución compatible con POSIX, vea esta respuesta .
${BASH_SOURCE[0]}
(o, más simplemente,
$BASH_SOURCE
[1]
) contiene la ruta (potencialmente relativa) del script que lo contiene en
todos los
escenarios de invocación, especialmente cuando el script se
obtiene
, lo que no es cierto para
$0
.
Además, como señala
Charles Duffy
, la persona que llama puede establecer
$0
en un valor
arbitrario
.
Por otro lado,
$BASH_SOURCE
puede
estar vacío, si no hay ningún archivo con nombre;
p.ej:
echo ''echo "[$BASH_SOURCE]"'' | bash
El siguiente ejemplo lo ilustra:
Guión
foo
:
#!/bin/bash
echo "[$0] vs. [${BASH_SOURCE[0]}]"
$ bash ./foo
[./foo] vs. [./foo]
$ ./foo
[./foo] vs. [./foo]
$ . ./foo
[bash] vs. [./foo]
$0
es parte de la especificación de shell POSIX, mientras que
BASH_SOURCE
, como su nombre indica, es específico de Bash.
[1]
Lectura opcional:
${BASH_SOURCE[0]}
vs.
$BASH_SOURCE
:
Bash le permite hacer referencia al elemento
0
de una variable de
matriz
usando notación
escalar
: en lugar de escribir
${arr[0]}
, puede escribir
$arr
;
en otras palabras: si hace referencia a la variable
como si fuera un escalar
, obtiene el elemento en el índice
0
.
El uso de esta función oculta el hecho de que
$arr
es una matriz, por lo que la popular
interfaz de
código de shell
shellcheck.net
emite la siguiente advertencia (a partir de este escrito):
SC2128: Expandir una matriz sin un índice solo da el primer elemento.
En una nota al margen: Si bien esta advertencia es útil, podría ser más precisa, ya que no necesariamente obtendrá el
primer
elemento: es específicamente el elemento en el índice
0
que se devuelve, por lo que si el primer elemento tiene un índice más alto, que es posible en Bash: obtendrá la cadena vacía;
intente
''a[1]=''hi''; echo "$a"''
''a[1]=''hi''; echo "$a"''
.
(Por el contrario,
zsh
, siempre el renegado, de hecho devuelve el primer elemento, independientemente de su índice).
Puede optar por evitar esta función debido a su oscuridad, pero funciona de manera predecible y, pragmáticamente hablando, rara vez, si alguna vez, necesitará acceder a índices
distintos
de
0
de la variable de matriz
${BASH_SOURCE[@]}
.