Comment puis-je connaître le nom du fichier script dans un script Bash?
Comment puis-je déterminer le nom du fichier de script Bash à l'intérieur du script lui-même?
comme si mon script est dans le fichier runme.sh
, alors comment le ferais-je pour afficher "You are running runme.sh" message sans code dur?
21 réponses
me=`basename ""151900920""`
pour lire à travers un lien symbolique, qui n'est généralement pas ce que vous voulez (vous ne voulez généralement pas confondre l'utilisateur de cette façon), essayez:
me="$(basename "$(test -L ""151910920"" && readlink ""151910920"" || echo ""151910920"")")"
IMO, qui va produire des résultats confus. "J'ai couru foo.sh mais ça dit que je cours bar.sh!? Ça doit être un insecte!"En outre, l'un des buts d'avoir des liens symboliques nommés différemment est de fournir des fonctionnalités différentes basées sur le nom sous lequel il est appelé (pensez gzip et gunzip sur certaines plateformes).
# ------------- SCRIPT ------------- #
#!/bin/bash
echo
echo "# arguments called with ----> ${@} "
echo "# $1 ----------------------> "
echo "# $2 ----------------------> "
echo "# path to me ---------------> "151900920" "
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'
# ----------------------> 'hello there'
# ----------------------> '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 ------------- #
avec bash >= 3 les œuvres suivantes:
$ ./s
0 is: ./s
BASH_SOURCE is: ./s
$ . ./s
0 is: bash
BASH_SOURCE is: ./s
$ cat s
#!/bin/bash
printf '"151900920" is: %s\n$BASH_SOURCE is: %s\n' ""151900920"" "$BASH_SOURCE"
si le nom du script comporte des espaces, une manière plus robuste est d'utiliser "" 151900920 ""
ou "$(basename "" 151910920 "")"
- ou sur MacOS: "$(basename \"" 151920920"\")"
. Cela empêche le nom de se mutilé ou interprété en aucune façon. En général, c'est une bonne pratique de toujours citer deux fois les noms de variables dans l'interpréteur de commandes.
$BASH_SOURCE
donne la bonne réponse lors de la recherche du script.
Cela inclut cependant le chemin pour obtenir le nom du fichier des scripts, utilisez:
$(basename $BASH_SOURCE)
si vous le voulez sans le chemin, alors vous utiliserez ${0##*/}
pour répondre À Chris Conway , sur Linux (au moins) vous voulez faire cela:
echo $(basename $(readlink -nf "151900920"))
readlink imprime la valeur d'un lien symbolique. Si ce n'est pas un lien symbolique, il imprime le nom de fichier. - n lui dit de ne pas imprimer une nouvelle ligne. -f lui dit de suivre le lien complètement (si un lien symbolique était un lien vers un autre lien, il résoudrait aussi celui-ci).
j'ai trouvé que cette ligne fonctionne toujours, indépendamment du fait que le fichier soit fourni ou exécuté sous forme de script.
echo "${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}"
si vous voulez suivre symlinks utilisez readlink
sur le chemin que vous obtenez ci-dessus, récursivement ou non-récursivement.
la raison pour laquelle les travaux à une seule doublure s'explique par l'utilisation de la variable d'environnement BASH_SOURCE
et de son associée FUNCNAME
.
BASH_SOURCE
une variable de tableau dont les membres sont les noms de fichier source où les noms de fonction de shell correspondants dans la variable de tableau FUNCNAME sont définis. La fonction shell ${FUNCNAME[$i]} est définie dans le fichier ${BASH_SOURCE[$i]} et appelée à partir de ${BASH_SOURCE[$i+1]}.
FUNCNAME
une variable de tableau contenant les noms de toutes les fonctions shell actuellement dans la pile d'appels d'exécution. L'élément d'index 0 est le nom de toute en cours d'exécution de la fonction shell. L'élément le plus bas (celui dont l'indice est le plus élevé) est "main". Cette variable n'existe que lorsqu'une fonction shell est exécutée. Les affectations à FUNCNAME n'ont aucun effet et retourner un code d'erreur. Si FUNCNAME est désactivé, il perd ses propriétés spéciales, même s'il est ensuite réinitialisé.
cette variable peut être utilisée avec BASH_LINENO et BASH_SOURCE. Chaque élément de FUNCNAME a des éléments correspondants dans BASH_LINENO et BASH_SOURCE pour décrire la pile d'appels. Par exemple, ${FUNCNAME[$i]} a été appelé à partir du fichier ${BASH_SOURCE[$i+1]} au numéro de ligne ${BASH_LINENO[$i]}. L'appelant builtin affiche la pile d'appel à l'aide de cette information.
[Source: manuel Bash]
ces réponses sont correctes pour les cas qu'elles déclarent mais il y a toujours un problème si vous exécutez le script à partir d'un autre script en utilisant le mot-clé "source" (de sorte qu'il tourne dans le même shell). Dans ce cas, vous obtenez le 0 $du script d'appel. Et dans ce cas, je ne pense pas qu'il est possible d'obtenir le nom du script lui-même.
C'est un cas de bord et ne doit pas être pris trop au sérieux. Si vous exécutez le script depuis un autre script directement (sans'source')), utiliser 0 $marchera.
Re: Réponse de Tanktalus (acceptée) ci-dessus, une façon légèrement plus propre est d'utiliser:
me=$(readlink --canonicalize --no-newline "151900920")
si votre script provient d'un autre script bash, vous pouvez utiliser:
me=$(readlink --canonicalize --no-newline $BASH_SOURCE)
je suis d'accord qu'il serait déroutant de déréférencier les liens symboliques si votre objectif est de fournir une rétroaction à l'utilisateur, mais il y a des occasions où vous avez besoin d'obtenir le nom canonique à un script ou un autre fichier, et c'est la meilleure façon, imo.
si vous invoquez le script shell comme
/home/mike/runme.sh
0 $ est le nom complet
/home/mike/runme.sh
basename $0 obtiendra le nom du fichier de base
runme.sh
et vous devez mettre ce nom de base dans une variable comme
filename=$(basename "151930920")
et ajouter votre texte supplémentaire
echo "You are running $filename"
donc vos scripts comme
/home/mike/runme.sh
#!/bin/bash
filename=$(basename "151950920")
echo "You are running $filename"
vous pouvez utiliser $0 pour déterminer votre nom de script (avec le chemin complet) - pour obtenir le nom de script seulement vous pouvez couper cette variable avec
basename "151900920"
this="$(dirname "$(realpath "$BASH_SOURCE")")"
ceci résout les liens symboliques (realpath fait cela), gère les espaces (guillemets doubles font cela), et trouvera le nom de script courant même s'il provient (. ./ myscript) ou appelé par d'Autres scripts ($BASH_SOURCE gère cela). Après tout cela, il est bon de sauvegarder ceci dans une variable d'environnement pour la réutiliser ou pour une copie facile ailleurs (ceci=)...
puisque certains commentaires ont été demandés au sujet du nom de fichier sans extension, voici un exemple pour accomplir cela:
FileName=${0##*/}
FileNameWithoutExtension=${FileName%.*}
Profitez-en!
Info grâce à Bill Hernandez. J'ai ajouté des préférences que j'adopte.
#!/bin/bash
function Usage(){
echo " Usage: show_parameters [ arg1 ][ arg2 ]"
}
[[ ${#2} -eq 0 ]] && Usage || {
echo
echo "# arguments called with ----> ${@} "
echo "# $1 -----------------------> "
echo "# $2 -----------------------> "
echo "# path to me ---------------> "151900920" " | sed "s/$USER/$USER/g"
echo "# parent path --------------> ${0%/*} " | sed "s/$USER/$USER/g"
echo "# my name ------------------> ${0##*/} "
echo
}
Cheers
dans bash
vous pouvez obtenir le nom du fichier de script en utilisant " 151920920"
. Généralement ,
etc sont d'accéder aux arguments CLI. De même
" 151920920 "
est d'accéder au nom qui déclenche le script(nom du fichier script).
#!/bin/bash
echo "You are running "151900920""
...
...
si vous invoquez le script avec le chemin comme /path/to/script.sh
alors " 151920920 "
donnera aussi le nom du fichier avec le chemin. Dans ce cas, vous devez utiliser $(basename "151980920")
pour obtenir seulement le nom du fichier script.
echo "$(basename "`test -L ${BASH_SOURCE[0]} \
&& readlink ${BASH_SOURCE[0]} \
|| echo ${BASH_SOURCE[0]}`")"
"151910920"
ne répond pas à la question (telle que je la comprends). Une démonstration:
$ cat script.sh #! /bin/sh echo `basename "151900920"` $ ./script.sh script.sh $ ln script.sh linktoscript $ ./linktoscript linktoscript
Comment obtenir ./linktoscript
pour imprimer script.sh
?
[MODIFIER] Par @ephemient dans les commentaires ci-dessus, bien que le lien symbolique chose peut sembler artificiel, il est possible de jouer avec les "151910920"
, de sorte qu'il ne représente pas un système de fichiers de ressources. L'opération est un peu ambiguë sur ce qu'il voulait.
DIRECTORY=$(cd `dirname "151900920"` && pwd)
j'ai obtenu ce qui précède d'une autre question de débordement de pile, un script Bash peut-il dire dans quel répertoire il est stocké? , mais je pense que c'est utile pour ce sujet aussi.
quelque chose comme ça?
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 ]
then
val="*** Unknown ***"
elif [ -n ]
then
# otherwise make first arg as val
val=
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