هل يمكنني الحصول على الطريق المطلق إلى البرنامج النصي الحالي في Kornshell؟
سؤال
هل من الممكن معرفة المسار الكامل إلى البرنامج النصي الذي يتم تنفيذه حاليا في Kornshell (KSH)؟
أي إذا كان البرنامج النصي في /opt/scripts/myscript.ksh
, ، هل يمكنني برمجيا داخل هذا البرنامج النصي اكتشف /opt/scripts/myscript.ksh
?
شكرا،
المحلول
يمكنك استخدام:
## __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 )
نصائح أخرى
في قذيفة Korn، تفشل كل هذه الحلول 0 دولار إذا كنت مصادر في البرنامج النصي في السؤال. الطريقة الصحيحة للحصول على ما تريده هو استخدام $ _
$ 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
لاحظ السطر الأخير هناك؟ استخدام $ _. على الأقل في كورن. YMMV في باش، CSH، وآخرون ..
كيف تم تخزين البرنامج النصي في المتغير 0 دولار. يمكنك استخدام readlink
للحصول على اسم الملف المطلق:
readlink -f "$0"
حسنا، استغرق الأمر مني بعض الوقت ولكن هذا واحد بسيط للغاية يصرخ.
_SCRIPTDIR=$(cd $(dirname $0);echo $PWD)
نظرا لأن القرص المضغوط يعمل في Shell Spawned مع $ () لا يؤثر على البرنامج النصي الحالي.
يحتوي المتغير $ rprath على المسار النسبي إلى الملف الحقيقي أو المسار الحقيقي لملف حقيقي.
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
وهذا هو ما فعلته:
if [[ $0 != "/"* ]]; then
DIR=`pwd`/`dirname $0`
else
DIR=`dirname $0`
fi
readlink -f
سيكون الأفضل إذا كان محملا، لأنه يحل كل ارتباطات موجودة لكل من الدلائل والملفات.
على ماك OS X لا يوجد readlink -f
(باستثناء ربما عبر macports)، لذلك يمكنك فقط استخدام readlink
للحصول على وجهة ملف ارتباط رمزي معين.
ال $(cd -P ... pwd -P)
تقنية لطيفة ولكن تعمل فقط لحل الروابط للحصول على الدلائل التي تؤدي إلى البرنامج النصي، لا يعمل إذا كان البرنامج النصي نفسه هو Symlink
أيضا، حالة واحدة لم يتم ذكرها: عند تشغيل برنامج نصي من خلال تمريره كوسيطة للقذيفة (/bin/sh /path/to/myscript.sh
), $0
غير قابل للاستخدام في هذه الحالة
أخذت نظرة على MySQL "الثنائيات"، الكثير منهم في الواقع البرامج النصية قذيفة؛ والآن أفهم لماذا يطلبون --basedir
الخيار أو يجب إطلاقه من دليل عمل معين؛ هذا لأنه لا يوجد حل جيد لتحديد موقع البرنامج النصي المستهدف
هذا يعمل أيضا، على الرغم من أنه لن يمنح المسار "الحقيقي" إذا كان رابطا. انها أبسط، ولكن أقل بالضبط.
SCRIPT_PATH="$(whence ${0})"
حاول أي أمر.
which scriptname
سوف تعطيك الاسم المؤهل الكامل للسيناريو جنبا إلى جنب مع طريقه المطلق
قمت بترقية إجابة إدوارد ستودت، لتتمكن من التعامل مع الروابط الرمزية المسار المطلقة، ومع سلاسل الروابط أيضا.
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
قبيح، ولكن يعمل ... بعد تشغيل هذا، المسار هو $ cpath والملف هو cfile $
باستخدام $ _ يوفر الأمر الأخير.
>source my_script
يعمل إذا قمت بإصدار الأمر مرتين:
>source my_script
>source my_script
إذا كنت تستخدم تسلسل مختلف من الأوامر:
>who
>source my_script
الإرجاع $ _ المتغير "من"
حاول استخدام هذا:
dir = $(dirname $0)