Est-il possible de connaître le chemin d'accès complet au script en cours d'exécution dans KornShell (ksh)?
c.-à-d. si mon script est dans /opt/scripts/myscript.ksh
, puis-je programmer par programmation à l'intérieur de ce script découvrir /opt/scripts/myscript.ksh
?
Merci,
Vous pouvez utiliser:
## __SCRIPTNAME - name of the script without the path
##
typeset -r __SCRIPTNAME="${0##*/}"
## __SCRIPTDIR - path of the script (as entered by the user!)
##
__SCRIPTDIR="${0%/*}"
## __REAL_SCRIPTDIR - path of the script (real path, maybe a link)
##
__REAL_SCRIPTDIR=$( cd -P -- "$(dirname -- "$(command -v -- "$0")")" && pwd -P )
Dans Korn Shell, toutes ces solutions $ 0 échouent si vous utilisez le script en question. La bonne façon d’obtenir ce que vous voulez est d’utiliser $ _
$ cat bar
echo dollar under is $_
echo dollar zero is $0
$ ./bar
dollar under is ./bar
dollar zero is ./bar
$ . ./bar
dollar under is bar
dollar zero is -ksh
Remarquez la dernière ligne là-bas? Utilisez $ _. Au moins à Korn. YMMV dans bash, csh et al ..
Ça m’a pris du temps mais celui-ci est si simple qu’il crie.
_SCRIPTDIR=$(cd $(dirname $0);echo $PWD)
puisque le CD fonctionne dans le shell engendré avec $ (), cela n’affecte pas le script actuel.
Comment le script a été appelé est stocké dans la variable $ 0. Vous pouvez utiliser readlink
pour obtenir le nom de fichier absolu:
readlink -f "$0"
La variable $ RPATH contient le chemin relatif du fichier réel ou le chemin réel d’un fichier réel.
CURPATH=$( cd -P -- "$(dirname -- "$(command -v -- "$0")")" && pwd -P )
CURLOC=$CURPATH/`basename $0`
if [ `ls -dl $CURLOC |grep -c "^l" 2>/dev/null` -ne 0 ];then
ROFFSET=`ls -ld $CURLOC|cut -d ">" -f2 2>/dev/null`
RPATH=`ls -ld $CURLOC/$ROFFSET 2>/dev/null`
else
RPATH=$CURLOC
fi
echo $RPATH
readlink -f
serait le meilleur s'il était portable, car il résout tous les liens trouvés à la fois pour les répertoires et les fichiers.
Sur mac os x, il n'y a pas readlink -f
(sauf peut-être via macports), vous ne pouvez donc utiliser que readlink
pour obtenir la destination d'un fichier de lien symbolique spécifique.
La technique $(cd -P ... pwd -P)
est agréable, mais ne fonctionne que pour résoudre les liens des répertoires menant au script. Elle ne fonctionne pas si le script lui-même est un lien symbolique.
En outre, un cas qui n'a pas été mentionné: lorsque vous lancez un script en le transmettant comme argument à un shell (/bin/sh /path/to/myscript.sh
), $0
n'est pas utilisable dans ce cas.
J'ai jeté un coup d'oeil à mysql "les binaires", beaucoup d'entre eux sont en fait des scripts Shell; et maintenant je comprends pourquoi ils demandent une option --basedir
ou doivent être lancés à partir d’un répertoire de travail spécifique; c'est parce qu'il n'y a pas de bonne solution pour localiser le script ciblé
C'est ce que j'ai fait:
if [[ $0 != "/"* ]]; then
DIR=`pwd`/`dirname $0`
else
DIR=`dirname $0`
fi
Cela fonctionne aussi, bien qu'il ne donne pas le "vrai" chemin s'il s'agit d'un lien. C'est plus simple, mais moins exact.
SCRIPT_PATH="$(whence ${0})"
Essayez quelle commande.
which scriptname
vous donnera le nom qualifié complet du script avec son chemin absolu
J'ai amélioré la réponse d'Edward Staudt afin de pouvoir traiter les liens symboliques de chemin absolu, ainsi que les chaînes de liens.
DZERO=$0
while true; do
echo "Trying to find real dir for script $DZERO"
CPATH=$( cd -P -- "$(dirname -- "$(command -v -- "$DZERO")")" && pwd -P )
CFILE=$CPATH/`basename $DZERO`
if [ `ls -dl $CFILE | grep -c "^l" 2>/dev/null` -eq 0 ];then
break
fi
LNKTO=`ls -ld $CFILE | cut -d ">" -f2 | tr -d " " 2>/dev/null`
DZERO=`cd $CPATH ; command -v $LNKTO`
done
Moche, mais ça marche ... Après avoir exécuté ceci, le chemin est $ CPATH et le fichier est $ CFILE
Utiliser $ _ fournit la dernière commande.
>source my_script
Fonctionne si j'émets la commande deux fois:
>source my_script
>source my_script
Si j'utilise une séquence de commandes différente:
>who
>source my_script
La variable $ _ renvoie "qui"