scripts script resueltos programacion pasar parametros español ejercicios ejemplos comandos linux bash shell scripting

linux - resueltos - ¿Cómo puedo saber el nombre del archivo de script en un script de Bash?



shell script linux español (21)

¿Cómo puedo determinar el nombre del archivo de script Bash dentro del propio script?

Como si mi script runme.sh en el archivo runme.sh , entonces, ¿cómo lo haría para mostrar el mensaje "Está ejecutando runme.sh" sin codificarlo?


Con bash> = 3 los siguientes trabajos:

$ ./s 0 is: ./s BASH_SOURCE is: ./s $ . ./s 0 is: bash BASH_SOURCE is: ./s $ cat s #!/bin/bash printf ''$0 is: %s/n$BASH_SOURCE is: %s/n'' "$0" "$BASH_SOURCE"


Dado que algunos comentarios preguntaron sobre el nombre de archivo sin extensión, aquí hay un ejemplo de cómo lograrlo:

FileName=${0##*/} FileNameWithoutExtension=${FileName%.*}

¡Disfrutar!


En bash puedes obtener el nombre del archivo de script usando $0 . Generalmente, $1 , $2 etc. son para acceder a los argumentos de la CLI. De manera similar, $0 es acceder al nombre que activa el script (nombre del archivo de script).

#!/bin/bash echo "You are running $0" ... ...

Si invoca el script con la ruta como /path/to/script.sh , $0 también le dará el nombre del archivo con la ruta. En ese caso, debe usar $(basename $0) para obtener solo el nombre del archivo de script.


Estas respuestas son correctas para los casos que indican, pero aún existe un problema si ejecuta la secuencia de comandos desde otra secuencia de comandos usando la palabra clave ''fuente'' (para que se ejecute en el mismo shell). En este caso, obtienes los $ 0 del script de llamada. Y en este caso, no creo que sea posible obtener el nombre del script en sí.

Este es un caso de borde y no debe tomarse DEMASIADO en serio. Si ejecuta el script desde otro script directamente (sin ''fuente''), el uso de $ 0 funcionará.


He encontrado que esta línea siempre funciona, independientemente de si el archivo se está obteniendo o se ejecuta como un script.

echo "${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}"

Si desea seguir los enlaces simbólicos, use el readlink de readlink en la ruta que aparece arriba, recursivamente o no recursivamente.

El motivo por el que funciona una línea se explica por el uso de la variable de entorno BASH_SOURCE y su FUNCNAME asociado.

BASH_SOURCE

Una variable de matriz cuyos miembros son los nombres de archivo de origen donde se definen los nombres de función de shell correspondientes en la variable de matriz FUNCNAME. La función de shell $ {FUNCNAME [$ i]} se define en el archivo $ {BASH_SOURCE [$ i]} y se llama desde $ {BASH_SOURCE [$ i + 1]}.

Nombre de pila

Una variable de matriz que contiene los nombres de todas las funciones de shell actualmente en la pila de llamadas de ejecución. El elemento con índice 0 es el nombre de cualquier función de shell que se esté ejecutando actualmente. El elemento que está más abajo (el que tiene el índice más alto) es "principal". Esta variable existe solo cuando se está ejecutando una función de shell. Las asignaciones a FUNCNAME no tienen efecto y devuelven un estado de error. Si FUNCNAME no está configurado, pierde sus propiedades especiales, incluso si se reinicia posteriormente.

Esta variable se puede utilizar con BASH_LINENO y BASH_SOURCE. Cada elemento de FUNCNAME tiene elementos correspondientes en BASH_LINENO y BASH_SOURCE para describir la pila de llamadas. Por ejemplo, se llamó a $ {FUNCNAME [$ i]} desde el archivo $ {BASH_SOURCE [$ i + 1]} en el número de línea $ {BASH_LINENO [$ i]}. El integrante de la persona que llama muestra la pila de llamadas actual con esta información.

[Fuente: manual de Bash]


Información gracias a Bill Hernández. He añadido algunas preferencias que estoy adoptando.

#!/bin/bash function Usage(){ echo " Usage: show_parameters [ arg1 ][ arg2 ]" } [[ ${#2} -eq 0 ]] && Usage || { echo echo "# arguments called with ----> ${@} " echo "# /$1 -----------------------> $1 " echo "# /$2 -----------------------> $2 " echo "# path to me ---------------> ${0} " | sed "s/$USER//$USER/g" echo "# parent path --------------> ${0%/*} " | sed "s/$USER//$USER/g" echo "# my name ------------------> ${0##*/} " echo }

Aclamaciones


Para responder a Chris Conway , en Linux (al menos) harías esto:

echo $(basename $(readlink -nf $0))

readlink imprime el valor de un enlace simbólico. Si no es un enlace simbólico, imprime el nombre del archivo. -n le dice que no imprima una nueva línea. -f le dice que siga el enlace completamente (si un enlace simbólico fuera un enlace a otro enlace, también lo resolvería).


Puede usar $ 0 para determinar el nombre de su script (con la ruta completa): para obtener el nombre del script solo puede recortar esa variable con

basename $0


Re: la respuesta de Tanktalus (aceptada) arriba, una forma un poco más limpia es usar:

me=$(readlink --canonicalize --no-newline $0)

Si su script se ha obtenido de otro script de bash, puede usar:

me=$(readlink --canonicalize --no-newline $BASH_SOURCE)

Estoy de acuerdo en que sería confuso desreferenciar los enlaces simbólicos si su objetivo es proporcionar comentarios al usuario, pero hay ocasiones en las que necesita obtener el nombre canónico de un script u otro archivo, y esta es la mejor manera, imo.


Si el nombre del script tiene espacios en él, una forma más sólida es usar "$0" o "$(basename "$0")" o en MacOS: "$(basename /"$0/")" . Esto evita que el nombre se dañe o se interprete de cualquier manera. En general, es una buena práctica siempre citar los nombres de las variables en el shell.


Si lo desea sin la ruta, usaría ${0##*/}


algo como esto?

export LC_ALL=en_US.UTF-8 #!/bin/bash #!/bin/sh #---------------------------------------------------------------------- start_trash(){ ver="htrash.sh v0.0.4" $TRASH_DIR # url to trash $MY_USER $TRASH_SIZE # Show Trash Folder Size echo "Would you like to empty Trash [y/n]?" read ans if [ $ans = y -o $ans = Y -o $ans = yes -o $ans = Yes -o $ans = YES ] then echo "''yes''" cd $TRASH_DIR && $EMPTY_TRASH fi if [ $ans = n -o $ans = N -o $ans = no -o $ans = No -o $ans = NO ] then echo "''no''" fi return $TRUE } #----------------------------------------------------------------------- start_help(){ echo "HELP COMMANDS-----------------------------" echo "htest www open a homepage " echo "htest trash empty trash " return $TRUE } #end Help #-----------------------------------------------# homepage="" return $TRUE } #end cpdebtemp # -Case start # if no command line arg given # set val to Unknown if [ -z $1 ] then val="*** Unknown ***" elif [ -n $1 ] then # otherwise make first arg as val val=$1 fi # use case statement to make decision for rental case $val in "trash") start_trash ;; "help") start_help ;; "www") firefox $homepage ;; *) echo "Sorry, I can not get a $val for you!";; esac # Case stop


echo "estas corriendo $ 0"


si tu invocación de shell script como

/home/mike/runme.sh

$ 0 es el nombre completo

/home/mike/runme.sh

nombre base $ 0 obtendrá el nombre del archivo base

runme.sh

y necesitas poner este nombre básico en una variable como

filename=$(basename $0)

y agrega tu texto adicional

echo "You are running $filename"

a tus scripts les gusta

/home/mike/runme.sh #!/bin/bash filename=$(basename $0) echo "You are running $filename"


$0 no responde la pregunta (como yo la entiendo). Una demostración:

$ cat script.sh #! /bin/sh echo `basename $0` $ ./script.sh script.sh $ ln script.sh linktoscript $ ./linktoscript linktoscript

¿Cómo se obtiene ./linktoscript para imprimir script.sh ?

[EDITAR] Según @ephemient en los comentarios anteriores, aunque el enlace simbólico puede parecer ideado, es posible jugar con $0 para que no represente un recurso del sistema de archivos. El OP es un poco ambiguo sobre lo que quería.


$BASH_SOURCE da la respuesta correcta al obtener el script.

Sin embargo, esto incluye la ruta para obtener solo el nombre de archivo de los scripts, usar:

$(basename $BASH_SOURCE)


# ------------- SCRIPT ------------- # #!/bin/bash echo echo "# arguments called with ----> ${@} " echo "# /$1 ----------------------> $1 " echo "# /$2 ----------------------> $2 " echo "# path to me ---------------> ${0} " echo "# parent path --------------> ${0%/*} " echo "# my name ------------------> ${0##*/} " echo exit # ------------- CALLED ------------- # # Notice on the next line, the first argument is called within double, # and single quotes, since it contains two words $ /misc/shell_scripts/check_root/show_parms.sh "''hello there''" "''william''" # ------------- RESULTS ------------- # # arguments called with ---> ''hello there'' ''william'' # $1 ----------------------> ''hello there'' # $2 ----------------------> ''william'' # path to me --------------> /misc/shell_scripts/check_root/show_parms.sh # parent path -------------> /misc/shell_scripts/check_root # my name -----------------> show_parms.sh # ------------- END ------------- #



echo "$(basename "`test -L ${BASH_SOURCE[0]} / && readlink ${BASH_SOURCE[0]} / || echo ${BASH_SOURCE[0]}`")"


me=`basename "$0"`

Para leer a través de un enlace simbólico, que generalmente no es lo que quieres (normalmente no quieres confundir al usuario de esta manera), prueba:

me="$(basename "$(test -L "$0" && readlink "$0" || echo "$0")")"

OMI, eso producirá resultados confusos. "Corrí foo.sh, pero está diciendo que estoy ejecutando bar.sh !? ¡Debe ser un error!" Además, uno de los propósitos de tener enlaces simbólicos con nombres diferentes es proporcionar una funcionalidad diferente basada en el nombre que se llama (piense gzip y gunzip en algunas plataformas).


this="$(dirname "$(realpath "$BASH_SOURCE")")"

Esto resuelve los enlaces simbólicos (realpath lo hace), maneja los espacios (las comillas dobles lo hacen) y encontrará el nombre del script actual incluso cuando se obtenga (./myscript) o sea llamado por otros scripts ($ BASH_SOURCE lo maneja). Después de todo eso, es bueno guardar esto en una variable de entorno para reutilizarlo o para copiarlo fácilmente en otro lugar (esto =) ...