web-dev-qa-db-fra.com

$ {BASH_SOURCE [0]} équivalent en zsh?

Le titre devrait tout dire. Je cherche un équivalent de ${BASH_SOURCE[0]} dans zsh.

Note: Je continue de trouver "$0 est équivalent à ${BASH_SOURCE[0]}" sur Internet, mais cela semble être faux: $0 semble être le nom de la commande en cours d'exécution. (C'est argv[0], ce qui a du sens.) L'écho de $ 0 dans mon script (.zshrc) donne zsh pour $0, ce qui n'est pas la même chose que ${BASH_SOURCE[0]}. En fait, ${BASH_SOURCE[0]} semble fonctionner dans zsh, à l'exception des fichiers .zshrc.

Ce que je fais vraiment dans mon .zshrc (ça ne marche pas):

echo ${BASH_SOURCE[0]}
source `dirname $0`/common-Shell-rc.sh

La source échoue ($0 est zsh) et la echo affiche une ligne vide.

Modifier:  apparemment, pour que $0 fonctionne, j’ai besoin de l’option FUNCTION_ARGZERO définie. Un moyen de vérifier si cela est défini dans un script? (afin que je puisse le régler temporairement) Apparemment, il est activé, sauf si vous définissez nofunction_argzero, et il est activé dans mon shell. Toujours rien obtenir pour $0. (Je pense que b/c je ne suis pas dans une fonction.)

46
Thanatos

${BASH_SOURCE[0]} équivalent dans zsh est ${(%):-%N}, NOT $0 (comme OP l'a dit, ce dernier a échoué dans .zshrc)

Ici % indique une expansion rapide de la valeur, %N indique "Le nom du script, du fichier source, Ou de la fonction shell en cours d’exécution par zsh,

selon ce qui a été commencé le plus récemment. S'il n'y en a pas, cela équivaut au paramètre $ 0. "(From man zshmisc)

38
Hui Zheng

${(%):-%x} est la variable zsh la plus proche équivalente au $BASH_SOURCE de bash (et au ${.sh.file} de ksh) - pas$0.

Coup de chapeau à Hui Zheng pour avoir fourni le pointeur crucial et des informations générales dans sa réponse .

Il retourne le chemin (potentiellement relatif) du script inclus,

  • indépendamment du fait que le script soit source ou non .
    • plus précisément, cela fonctionne également dans les fichiers d'initialisation/profils tels que ~/.zshrc (contrairement à $0, qui renvoie inexplicablement le chemin d'accès Shell).
  • indépendamment du fait qu'il soit appelé depuis l'intérieur d'une fonction définie dans le script ou non (contrairement à $0, qui renvoie le nom fonction dans une fonction).

La seule différence par rapport à $BASH_SOURCE que j’ai trouvée se trouve dans le scénario obscur suivant, qui peut même être un bogue (observé dans zsh 5.0.5): dans une fonction imbriquée dans une autre fonction dans une source script, ${(%):-%x} ne pas retourne le chemin du script qui l'entoure lorsque cette fonction imbriquée est appelée (encore une fois) plus tard, après ayant été obtenue (ne renvoie rien ou zsh ') .


Informations générales sur ${(%):-%x}:

  • (%):- au lieu d'un nom de variable dans un paramètre (variable), expansion (${...}) permet de disposer des séquences d'échappement normalement utilisées pour représenter les informations environnementales dans les chaînes Prompt, telles qu'elles sont utilisées dans la variable PS1 pour déterminer la chaîne. affiché comme l’invite interactive principale.

    • % est une instance d'un indicateur d'expansion de paramètre, qui sont tous répertoriés dans man zshexpn sous la rubrique Parameter Expansion Flags.
  • %x est l'une des séquences d'échappement pouvant être utilisées dans les chaînes d'invite et fonctionne comme décrit ci-dessus; il y en a beaucoup plus, comme %d pour représenter le répertoire actuel.

    • man zshmisc répertorie toutes les séquences disponibles sous l'en-tête SIMPLE Prompt ESCAPES.
23
mklement0

$0 est correct. Dans un script source, il s'agit du nom d'un script, tel qu'il a été transmis à la commande intégrée . ou source (ainsi, si l'option path_dirs est définie, vous devrez peut-être effectuer une recherche $path pour trouver l'emplacement réel du script. ).

.zshrc n'est pas source, ce qui explique pourquoi $0 n'est pas défini sur .zshrc. De toute façon, vous connaissez le nom du fichier et son emplacement: c'est ${ZDOTDIR-~}/.zshrc.

10
Gilles

Si vous faites un lien symbolique vers .zshrc dans un répertoire dotfiles et souhaitez référencer d'autres fichiers du répertoire, essayez ceci:

SOURCE=${(%):-%N}
while [ -h "$SOURCE" ]; do
  DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
  SOURCE="$(readlink "$SOURCE")"
  [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"
done
DOTFILES_DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"

(J'ai eu le script de boucle de ici .)

9
Francis Potter

Peut-être cherchez-vous $_?

# foo.sh
source foo2.sh

et

# foo2.sh
echo $_

les rendements

# ./foo.sh
foo2.sh
2
Coderer

Si vous voulez rendre votre script compatible avec bash et zsh, vous pouvez utiliser ${BASH_SOURCE[0]:-${(%):-%x}}. La valeur résultante sera extraite de BASH_SOURCE[0] lorsqu'elle est définie et de ${(%):-%x}} lorsque BASH_SOURCE[0] n'est pas défini.

0
dols3m