هل يمكنني الحصول على الطريق المطلق إلى البرنامج النصي الحالي في Kornshell؟

StackOverflow https://stackoverflow.com/questions/760110

سؤال

هل من الممكن معرفة المسار الكامل إلى البرنامج النصي الذي يتم تنفيذه حاليا في 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)
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top