Ssenarinin özündən başlanğıc baş script scriptini alın

Baş skriptinin olduğu skriptə daxil olan qovluğa yol almaq necə?

Misal üçün, bash skriptini başqa bir tətbiq üçün bir başlanğıc kimi istifadə etmək istərdim. Bəş skriptinin yerləşdiyi yerə işçi qovluğu dəyişdirmək istəyirəm, belə ki, məsələn, bu kataloqdakı fayllarla işləyə bilərəm:

  $ ./application 
4222
12 сент. Jiaaro tərəfindən 12 Sentyabrda təyin olundu . 2008-09-12 23:39 '08 at 11:39 2008-09-12 23:39
@ 53 cavab
  • 1
  • 2
 #!/bin/bash DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>  pwd )" 

faydalı bir xəttdir, hansı ki, adlandırılacaq yerdən asılı olmayaraq script dizininin tam adını verəcəkdir.

Ssenarəti axtarmaq üçün istifadə olunan yolun sonuncu komponenti simvolik bir link deyildir (dizinlere bağlantılar yaxşıdır). Ayrıca, skriptin özünə hər hansı bir linkə icazə vermək istəsəniz, çox satırlı bir həll lazımdır:

 #!/bin/bash SOURCE="${BASH_SOURCE[0]}" while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>  pwd )" SOURCE="$(readlink "$SOURCE")" [[ $SOURCE != /* ]]  SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located done DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>  pwd )" 

Bu son birləşmə, source , bash -c , simvolik əlaqələr və s.

Diqqət: bu parçanı işlətməzdən əvvəl başqa bir cd varsa, nəticə səhv ola bilər!

Bundan əlavə, $CDPATH səhvləri və stderr çıxışının yan təsirləri, əgər istifadəçi $CDPATH çıxışını yönləndirmək üçün cd-nin ağıllı bir override varsa (məsələn, escape ardıcıllığı daxil olmaqla, Mac üçün update_terminal_cwd >> ). cd sonunda >/dev/null 2>> edərkən hər iki ehtimala diqqət yetirəcəksiniz.

Bunun necə işlədiyini anlamaq üçün bu daha ətraflı formu işləməyə çalışın:

 #!/bin/bash SOURCE="${BASH_SOURCE[0]}" while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink TARGET="$(readlink "$SOURCE")" if [[ $TARGET == /* ]]; then echo "SOURCE '$SOURCE' is an absolute symlink to '$TARGET'" SOURCE="$TARGET" else DIR="$( dirname "$SOURCE" )" echo "SOURCE '$SOURCE' is a relative symlink to '$TARGET' (relative to '$DIR')" SOURCE="$DIR/$TARGET" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located fi done echo "SOURCE is '$SOURCE'" RDIR="$( dirname "$SOURCE" )" DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>  pwd )" if [ "$DIR" != "$RDIR" ]; then echo "DIR '$RDIR' resolves to '$DIR'" fi echo "DIR is '$DIR'" 

Və belə bir şey yazacaq:

29 окт. Cavab 29 oktyabr ayına aiddir. 2008-10-29 11:36 '08 at 11:36 2008-10-29 11:36

dirname "$ 0" istifadə edin:

<Preliminary> <code> #! / Bin / Bash echo "Siz scriptin basename" başlanğıcını "$ 0", dirname` dirname '$ 0' '"echo"

pwd istifadə edərək, onun pwd bir skript istifadə etməyəcəksiniz.

border=0
  [matt @server1 ~] $pwd /Главная/матовый [matt @server1 ~] $./test2.sh script, который вы используете, имеет basename test2.sh, dirname. Настоящий рабочий каталог /home/matt [matt @server1 ~] $cd/tmp [matt @server1 tmp] $~/test2.sh script, который вы используете, имеет basename test2.sh, dirname/home/matt Настоящий рабочий каталог /tmp Код> 
722
12 сент. cavab mat b 12 sep verilir. 2008-09-12 23:49 '08 at 23:49 2008-09-12 23:49

Dirname əmri yalnız $ 0 (skript adı) ilə fayl adının yolunu təhlil edərək, ən sadədir.

 dirname "$0" 

Lakin Matt b tərəfindən göstərildiyi kimi, qayıtma yolu scriptin necə adlandırıldığına görə fərqlənir. pwd bu işi etməz, çünki yalnız cari qovluğun nə olduğunu deyir, scriptin olduğu yer deyil. Əlavə olaraq, skriptə simvolik bir əlaqə verilirsə, ehtimal ki, linkin olduğu yerə müqayisədə nisbi bir yol alacaqsınız.

Bəzi digərlər readlink komandanlığı qeyd etdilər, ancaq ən sadə formada istifadə edə bilərsiniz:

 dirname "$(readlink -f "$0")" 

Readlink, fayl sisteminin kökündən olan mütləq yola script yolunu verəcəkdir. Beləliklə, bir və ya ikiqat xal, tilde və / və ya simvolik linklər olan hər hansı bir yol tam yol üçün icazə veriləcəkdir.

Burada hər birini göstərən bir skriptdir , nədir.sh:

 #!/bin/bash echo "pwd: `pwd`" echo "\$0: $0" echo "basename: `basename $0`" echo "dirname: `dirname $0`" echo "dirname/readlink: $(dirname $(readlink -f $0))" 

Bu skripti mənim qovluğumda nisbi bir yolla çalıştırın:

 >>>$ /Users/phatblat/whatdir.sh pwd: /Users/phatblat $0: /Users/phatblat/whatdir.sh basename: whatdir.sh dirname: /Users/phatblat dirname/readlink: /Users/phatblat 

İndi dəyişən qovluqlar:

 >>>$ ln -s ~/whatdir.sh whatdirlink.sh >>>$ ./whatdirlink.sh pwd: /tmp $0: ./whatdirlink.sh basename: whatdirlink.sh dirname: . dirname/readlink: /Users/phatblat 
401
26 сент. Cavab verilir phatblat 26 sep . 2009-09-26 23:38 '09 at 11:38 PM 2009-09-26 23:38
 pushd . > /dev/null SCRIPT_PATH="${BASH_SOURCE[0]}" if ([ -h "${SCRIPT_PATH}" ]); then while([ -h "${SCRIPT_PATH}" ]); do cd 'dirname "$SCRIPT_PATH"'; SCRIPT_PATH='readlink "${SCRIPT_PATH}"'; done fi cd 'dirname ${SCRIPT_PATH}' > /dev/null SCRIPT_PATH='pwd'; popd > /dev/null 

Bütün versiyalar üçün çalışır

  • birdən çox dərinliyi olan yumşaq bir link vasitəsilə çağırıldığında,
  • zaman fayl
  • skriptə " source " əmri deyilir . (tam dayanma).
  • arg ardıcıldan $0 dəyişir.
  • "./script"
  • "/full/path/to/script"
  • "/some/path/../../another/path/script"
  • "./some/folder/script"

Alternativ olaraq, bash scriptinin özü nisbi bir sembolik link olsa, onu izləmək və əlaqəli scriptun tam yolunu qaytarmaq istəyirik:

 pushd . > /dev/null SCRIPT_PATH="${BASH_SOURCE[0]}"; if ([ -h "${SCRIPT_PATH}" ]) then while([ -h "${SCRIPT_PATH}" ]) do cd 'dirname "$SCRIPT_PATH"'; SCRIPT_PATH='readlink "${SCRIPT_PATH}"'; done fi cd 'dirname ${SCRIPT_PATH}' > /dev/null SCRIPT_PATH='pwd'; popd > /dev/null 

SCRIPT_PATH tam olaraq, nə olursa olsun çağırılır.
Ssenarinin başlanğıcında onu tapdığınıza əmin olun.

Bu şərh və copyleft kodu, seçilən lisenziya GPL2.0 və ya daha sonra və ya CC-SA 3.0 (CreativeCommons Share Alike) və ya daha sonra. (c) 2008. Bütün hüquqlar qorunur. Zəmanət yoxdur. Siz xəbərdarlıq oldunuz.
http://www.gnu.org/licenses/gpl-2.0.txt
http://creativecommons.org/licenses/by-sa/3.0/
18eedfe1c99df68dc94d4a94712a71aaa8e1e9e36cacf421b9463dd2bbaa02906d0d6656

171
07 окт. Cavab İstifadəçi25866 07 oktyabr tərəfindən verilir . 2008-10-07 19:12 '08 at 7:12 pm 2008-10-07 19:12

Qısa cavab:

 `dirname $0` 

və ya ( tercihen ):

 $(dirname "$0") 
97
03 дек. Cavab Fabien verildi 03 Dek 2008-12-03 15:57 '08 at 15:57 2008-12-03 15:57

$ BASH_SOURCE istifadə edə bilərsiniz

 #!/bin/bash scriptdir=`dirname "$BASH_SOURCE"` 

Bash uzantısı olduğundan #! / Bin / bash deyil, #! / Bin / sh istifadə etmək lazımdır

93
12 сент. Cavab 12 sentyabr cənab Shark'a verilir 2008-09-12 23:50 '08 at 11:50 pm 2008-09-12 23:50

Bunu etməlidir:

 DIR=$(dirname "$(readlink -f "$0")") 

Yolda simvolik əlaqələr və boşluqlar ilə işləyir. Dəynamereadlink üçün man səhifələrinə baxın.

Düzenle:

Şərh Mac OS ilə işləmək kimi görünmür. Niyə bunun belə olduğunu bilmirdim. Hər hansı bir təklif?

61
13 февр. Simon Rigetin 13 Fevralda verdiyi cavabı . 2016-02-13 02:40 '16 'da 2:40 ' də 2016-02-13 02:40 'da

pwd , mövcud iş dirname axtarmaq üçün istifadə edilə bilər və dirname xüsusi bir dirname qovluğunu axtarmaq üçün başlanır (başlanılan əmr $0 , belə ki dirname $0 sizə mövcud script dirname $0 verməlidir).

Lakin, dirname fayl adı dirname tam hissəsini verir, əksər hallarda mövcud iş qovluğuna istinad edir. Nə üçün ssenarinin dirname dəyişməsi lazımdırsa, dirname çıxan nəticə mənasız olur.

Aşağıdakıları təklif edirəm:

 #!/bin/bash reldir=`dirname $0` cd $reldir directory=`pwd` echo "Directory is $directory" 

Beləliklə, nisbi bir kataloq deyil, mütləqdir.

Ssenarinin bash ayrı bir örneğinde çalışacağından, iş pwd geri pwd ehtiyac yoxdur, amma əgər bir pwd ssenarinize geri dönmek isterseniz, gələcək istifadə üçün pwd dəyişdirmədən əvvəl pwd dəyərini bir dəyişənə asanlıqla təyin edə bilərsiniz.

Baxmayaraq ki

 cd `dirname $0` 

söz mövzusu xüsusi ssenari qərar verir, mən daha faydalı olan mütləq yolun adətən olduğuna inanıram.

55
15 сент. Cavab SpoonMeiser 15 sep tərəfindən verilir . 2008-09-15 22:55 '08 saat 10:55 'da 2008-09-15 22:55

Başqalarının bunu bacardığı qədər asan olduğunu düşünmürəm. pwd işləmir, çünki cari dizin script ilə mütləq deyil. 0 $ da həmişə məlumat içərisində deyil. Ssenari çağırmaq üçün aşağıdakı üç yola baxın.

 ./script /usr/bin/script script 

Birinci və üçüncü üsullarda $ 0 tam yol məlumatı yoxdur. İkinci və üçüncü hallarda, pwd işləmir. Üçüncü yolu dir almaq üçün yeganə yol yolu keçmək və düzgün oyunu ilə tapmaq. Prinsipcə, kod OS əməliyyatının nə olduğunu təkrarlamaq lazımdır.

Sizdən soruşduğunuz şeyi yerinə yetirmək üçün bir üsul, məlumatları / usr / share qovluğuna kopyalamaq və tam şəkildə göstərməkdir. Hər halda, məlumat / usr / bin qovluğunda olmayacaqdır, buna görə də ehtimal edilir.

33
13 сент. Cavab 13 sentyabr Cim tərəfindən verilir 2008-09-13 04:07 '08 'də 4:07' də 2008-09-13 04:07 'də
 SCRIPT_DIR=$( cd ${0%/*}  pwd -P ) 
32
07 окт. Cavab 07 oktyabrda verilir . 2010-10-07 20:34 '10 at 20:34 'da 2010-10-07 20:34

Mac OS X 10.6.6-da cari iş dizinini alır:

 DIR=$(cd "$(dirname "$0")"; pwd) 
27
30 дек. Cavab Pubquy 30 Dekabr. 2010-12-30 10:20 '11 saat 10:20 'da 2010-12-30 10:20

Bu xüsusi Linux, lakin istifadə edə bilərsiniz:

 SELF=$(readlink /proc/$$/fd/255) 
26
16 сент. Cavab 16 sentyabrda Steve Baker tərəfindən verilir . 2008-09-16 22:55 '08 saat 10:55 'da 2008-09-16 22:55
 $(dirname "$(readlink -f "$BASH_SOURCE")") 
26
27 июля '11 в 10:40 2011-07-27 10:40 Cavab verilir test11 27 iyul '10 saat 10:40 'da 2011-07-27 10:40

POSIX ilə uyğun bir xətt var:

 SCRIPT_PATH=`dirname "$0"`; SCRIPT_PATH=`eval "cd \"$SCRIPT_PATH\"  pwd"` # test echo $SCRIPT_PATH 
21
06 марта '13 в 22:07 2013-03-06 22:07 Cavab lamawithonel tərəfindən verilir 06 Mart 'da 10:07' da 2013-03-06 22:07

Onların hər birini sınamışam və heç biri işləməmişdi. Biri çox yaxın idi, ancaq onu çox narahat edən kiçik bir səhv vardı; onlar yolu quotes ilə bağlamaq unutdular.

Ayrıca, bir çoxları bir kabukdan bir skript istifadə etdiyinizə inanırlar, belə ki evinizi default olaraq yeni bir skript açarkən unutun.

Bu qovluğu ölçüsü üçün cəhd edin:

/ var / Heç kim / Düşüncə / Varlığın boşluqları / Dizindəki / Adı / Və burada .extext faylınız

Bu necə və harada çalışsanız da, bu doğru olur.

 #!/bin/bash echo "pwd: `pwd`" echo "\$0: $0" echo "basename: `basename "$0"`" echo "dirname: `dirname "$0"`" 

Beləliklə, burada həqiqətən faydalı olmaq üçün skript startup qovluğuna gedin:

 cd "`dirname "$0"`" 

Bu kömək edir

16
09 сент. 09 Sentyabrda Mike Bethany tərəfindən verilmiş cavab 2010-09-09 10:19 '10 at 10:19 2010-09-09 10:19

Bu kimi bir şey istifadə edərdim:

 # retrieve the full pathname of the called script scriptPath=$(which $0) # check whether the path is a link or not if [ -L $scriptPath ]; then # it is a link then retrieve the target path and get the directory name sourceDir=$(dirname $(readlink -f $scriptPath)) else # otherwise just get the directory name of the script path sourceDir=$(dirname $scriptPath) fi 
15
21 нояб. Cavab Nicolas 21 noyabr. 2012-11-21 06:57 '12 saat 06:57 'da 2012-11-21 06:57

Burada sadə, düzgün bir yol:

 actual_path=$(readlink -f "${BASH_SOURCE[0]}") script_dir=$(dirname "$actual_path") 

Şərhlər:

  • ${BASH_SOURCE[0]} - skriptə tam yol. Skriptin qaynağı, məsələn, əldə edilsə belə, bu parametrin dəyəri düzgün olacaq. source <(echo 'echo $0') bash yazır və onu ${BASH_SOURCE[0]} ilə əvəz etmək scriptin tam yolunu yazdırır. (Əlbəttə ki, bu, bəşə bir asılılığı alaraq yaxşı olduğunuzu düşünür.)

  • readlink -f - Belirtilen yol boyunca hər hansı bir simvolik readlink -f edir. Bu bir GNU uzantısıdır və (məsələn) BSD sistemi üçün mövcud deyil. Bir Mac istifadə edirsinizsə, Homebrew istifadə edə bilərsiniz GNU coreutils yüklemek və greadlink -f ilə supplant.

  • Və, əlbəttə, dirname yolun əsas kataloqunu alır.

15
19 февр. 19 Fevralda James Ko tərəfindən cavab verildi 2016-02-19 23:30 '16 saat 23:30 'də 2016-02-19 23:30' a qədər

E-tender və 3bcdnlklvc04a qərarının kiçik bir cavabı onların cavabında göstərilib

 SCRIPT_DIR='' pushd "$(dirname "$(readlink -f "$BASH_SOURCE")")" > /dev/null  { SCRIPT_DIR="$PWD" popd > /dev/null } 

Bu, sadalanan bütün hallarda işləməlidir.

EDIT: popd'un konsolebox sayəsində uğursuz pushd sayəsində qarşısını almaq

14
14 апр. 14 aprel tarixində Fuwjax tərəfindən verilmiş cavab 2010-04-14 01:12 '10 at 1:12 2010-04-14 01:12
 #!/bin/sh PRG="$0" # need this for relative symlinks while [ -h "$PRG" ] ; do PRG=`readlink "$PRG"` done scriptdir=`dirname "$PRG"` 
13
13 сент. Cavab Monkeyboy 13 Sentyabr verilir. 2008-09-13 04:28 '08 at 4:28 2008-09-13 04:28

$ _ $ 0-ə alternativ olaraq qeyd etmək lazımdır. Bir bas skripti istifadə edirsinizsə, qəbul edilən cavabı qısaltmaq olar:

 DIR="$( dirname "$_" )" 

Bu ssenarinizin ilk ifadəsi olmalıdır.

11
16 сент. Cavab 16 sentyabr tələsik verilir 2011-09-16 22:05 '11 saat 10:05 'da 2011-09-16 22:05

Yuxarıda göstərilən cavabların çoxunu müqayisə etdim və bir neçə daha kompakt həll yolları ilə gəldim. Göründüyü kimi, onlar sevimli birləşmədən yaranan bütün çılpaq üzləri idarə edirlər:

  • Mütləq yollar və nisbi yollar
  • Dosyalar və qovluqlar üçün proqram
  • Çağırış script , bash script , bash -c script , source script və ya . script . script
  • Spaces, sekmeler, newlines, unicode və s. kataloq və / və ya fayl adında
  • Dəfnə ilə başlayan fayl adları

Linux-da işləyirsəniz, proc təsvirindən istifadə etmək cari script üçün tam səlahiyyətli mənbənin tapılması üçün ən yaxşı həlldir (interaktiv sessiyada, link müvafiq /dev/pts/X ):

 resolved="$(readlink /proc/$$/fd/255  echo X)"  resolved="${resolved%$'\nX'}" 

Bir az deformasiya var, amma düzəldilmə kompakt və anlamaq asan. Yalnız bash ibtidai vasitələrindən istifadə etmirik, amma yaxşı olduğum üçün, readlink bu vəzifəni daha asan edir. echo X dəyişən xəttin sonuna echo X əlavə edər ki, filenada heç bir arxa boşluq readlink və xəttin sonunda ${VAR%X} parametrinin readlink yeni bir simli əlavə edər (bu, adətən komanda əvəzində bizim əvvəlki aldatmamız üçün deyil), biz də onu xilas etməliyik. Bu yeni sətirləri göstərmək üçün \n kimi qaçış sıralarından istifadə etməyə imkan verən $'' sətirinin sxemindən istifadə etmək üçün asandır (bu, həmçinin, hiyləgər şəkildə adlandırılmış qovluq və faylları necə asanlıqla yarada bilər).

Yuxarıda, Linux-dakı cari scripti tapmaq üçün ehtiyaclarınızı əhatə etməlisiniz, amma sizin ixtiyarınızdakı proc fayl sisteminə malik deyilsinizsə və ya başqa bir faylın tam həll yolunu tapmağa çalışarsanız, aşağıda faydalı olan kodu tapa bilərsiniz. Bu, yuxarıda göstərilən bir xəttin yalnız kiçik bir dəyişikliyidir. Qəribə kataloq / fayl adları ilə readlink ls və " readlink ilə çıxışları readlink , çünki ls "sadələşdirilmiş" yolları əvəz edəcəkdir ? yeni xəttlər kimi şeylərə.

 absolute_path=$(readlink -e -- "${BASH_SOURCE[0]}"  echo x)  absolute_path=${absolute_path%?x} dir=$(dirname -- "$absolute_path"  echo x)  dir=${dir%?x} file=$(basename -- "$absolute_path"  echo x)  file=${file%?x} ls -l -- "$dir/$file" printf '$absolute_path: "%s"\n' "$absolute_path" 
11
21 апр. Billyjmc tərəfindən verilmiş cavab Apr 21 2013-04-21 16:40 '13 saat 16:40 'da 2013-04-21 16:40

GNU coreutils readlink ilə sistemlər üçün (məsələn, linux):

 $(readlink -f "$(dirname "$0")") 

$0 script faylının adını ehtiva etdikdə BASH_SOURCE istifadə BASH_SOURCE ehtiyac yoxdur.

10
28 мая '14 в 10:16 2014-05-28 10:16 Cavab istifadəçi1338062 28 May 'da 10:16' də verilir 2014-05-28 10:16

Beləliklə ... İnanıram ki, məndə var. Bir tərəf üçün gecikdim, amma bəzilərinin bu mövzuya rast gəldiklərini təqdir etdiyini düşünürəm. Şərhlər şərh edilməlidir.

 #!/bin/sh # dash bash ksh # !zsh (issues). G. Nixon, 12/2013. Public domain. ## 'linkread' or 'fullpath' or (you choose) is a little tool to recursively ## dereference symbolic links (ala 'readlink') until the originating file ## is found. This is effectively the same function provided in stdlib.h as ## 'realpath' and on the command line in GNU 'readlink -f'. ## Neither of these tools, however, are particularly accessible on the many ## systems that do not have the GNU implementation of readlink, nor ship ## with a system compiler (not to mention the requisite knowledge of C). ## This script is written with portability and (to the extent possible, speed) ## in mind, hence the use of printf for echo and case statements where they ## can be substituded for test, though I've had to scale back a bit on that. ## It is (to the best of my knowledge) written in standard POSIX shell, and ## has been tested with bash-as-bin-sh, dash, and ksh93. zsh seems to have ## issues with it, though I'm not sure why; so probably best to avoid for now. ## Particularly useful (in fact, the reason I wrote this) is the fact that ## it can be used within a shell script to find the path of the script itself. ## (I am sure the shell knows this already; but most likely for the sake of ## security it is not made readily available. The implementation of "$0" ## specificies that the $0 must be the location of **last** symbolic link in ## a chain, or wherever it resides in the path.) This can be used for some ## ...interesting things, like self-duplicating and self-modifiying scripts. ## Currently supported are three errors: whether the file specified exists ## (ala ENOENT), whether its target exists/is accessible; and the special ## case of when a sybolic link references itself "foo -> foo": a common error ## for beginners, since 'ln' does not produce an error if the order of link ## and target are reversed on the command line. (See POSIX signal ELOOP.) ## It would probably be rather simple to write to use this as a basis for ## a pure shell implementation of the 'symlinks' util included with Linux. ## As an aside, the amount of code below **completely** belies the amount ## effort it took to get this right -- but I guess that coding for you. ##===-------------------------------------------------------------------===## for argv; do :; done # Last parameter on command line, for options parsing. ## Error messages. Use functions so that we can sub in when the error occurs. recurses(){ printf "Self-referential:\n\t$argv ->\n\t$argv\n" ;} dangling(){ printf "Broken symlink:\n\t$argv ->\n\t"$(readlink "$argv")"\n" ;} errnoent(){ printf "No such file: "$@"\n" ;} # Borrow a horrible signal name. # Probably best not to install as 'pathfull', if you can avoid it. pathfull(){ cd "$(dirname "$@")"; link="$(readlink "$(basename "$@")")" ## 'test and 'ls' report different status for bad symlinks, so we use this. if [ ! -e "$@" ]; then if $(ls -d "$@" 2>/dev/null) 2>/dev/null; then errnoent 1> exit 1; elif [ ! -e "$@" -a "$link" = "$@" ]; then recurses 1> exit 1; elif [ ! -e "$@" ]  [ ! -z "$link" ]; then dangling 1> exit 1; fi fi ## Not a link, but there might be one in the path, so 'cd' and 'pwd'. if [ -z "$link" ]; then if [ "$(dirname "$@" | cut -c1)" = '/' ]; then printf "$@\n"; exit 0; else printf "$(pwd)/$(basename "$@")\n"; fi; exit 0 fi ## Walk the symlinks back to the origin. Calls itself recursivly as needed. while [ "$link" ]; do cd "$(dirname "$link")"; newlink="$(readlink "$(basename "$link")")" case "$newlink" in "$link") dangling 1>  exit 1 ;; '') printf "$(pwd)/$(basename "$link")\n"; exit 0 ;; *) link="$newlink"  pathfull "$link" ;; esac done printf "$(pwd)/$(basename "$newlink")\n" } ## Demo. Install somewhere deep in the filesystem, then symlink somewhere ## else, symlink again (maybe with a different name) elsewhere, and link ## back into the directory you started in (or something.) The absolute path ## of the script will always be reported in the usage, along with "$0". if [ -z "$argv" ]; then scriptname="$(pathfull "$0")" # Yay ANSI l33t codes! Fancy. printf "\n\033[3mfrom/as: \033[4m$0\033[0m\n\n\033[1mUSAGE:\033[0m " printf "\033[4m$scriptname\033[24m [ link | file | dir ]\n\n " printf "Recursive readlink for the authoritative file, symlink after " printf "symlink.\n\n\n \033[4m$scriptname\033[24m\n\n " printf " From within an invocation of a script, locate the script " printf "own file\n (no matter where it has been linked or " printf "from where it is being called).\n\n" else pathfull "$@" fi 
8
21 дек. Cavab 21 dekabrda Geoff Nixon tərəfindən verilmişdir. 2013-12-21 20:47 '13 saat 20:47 'da 2013-12-21 20:47

Istifadə edin:

 real=$(realpath $(dirname $0)) 
8
06 февр. Cavab DarkPark verildi 06 Fevral. 2012-02-06 13:43 '12 at 13:43 2012-02-06 13:43

Bu səhifəyə təkrar-təkrar gələn bir cavabı qəbul edilmiş cavanlığa köçürmək üçün gələndən yoruldum. Problemi anlamaq və yadda saxlamaq asan deyil.

Burada sadə bir skriptdir:

 DIR=$(dirname "${BASH_SOURCE[0]}") # get the directory name DIR=$(realpath "${DIR}") # resolve its full path if need be 
8
07 нояб. Cavab Thamme Gowda tərəfindən 07 noyabr. 2018-11-07 07:30 '18 saat 07:30 'da 2018-11-07 07:30

Aşağıdakı qarşılıqlı həll edin:

 CWD="$(cd -P -- "$(dirname -- "$0")"  pwd -P)" 

realpathreadlink kimi həmişə mövcud deyil (əməliyyat sisteminə uyğun olaraq) və ${BASH_SOURCE[0]} yalnız bash qabığında mövcuddur.

Alternativ olaraq, bash-də aşağıdakı funksiyanı sınayabilirsiniz:

 realpath () { [[ $1 = /* ]]  echo "$1" || echo "$PWD/${1#./}" } 

Bu funksiya 1 arqument alır. Mübahisənin zatən mütləq bir yolu varsa, onu yazın, əksinə $PWD dəyişən + fayl adı yazın ( ./ prefiksisiz).

mövzuda:

7
28 нояб. Cavab noyabr ayının 28-də veriləcək 2013-11-28 15:05 '13 'da 15:05' də 2013-11-28 15:05

Hmm, basename və dirname yolları sadəcə küçülməyəcək və yola (əgər valideyn PATH ixrac etməmişsə) yol vermək çətindir. Bununla belə, qabığın ssenarisi üçün açıq sapı olmalıdır, bash isə # 255dir.

 SELF=`readlink /proc/$$/fd/255` 

mənim üçün çalışır.

7
24 янв. 24 yanvarda Joshua tərəfindən verilmiş cavab 2009-01-24 20:01 '09 saat 20:01 'da 2009-01-24 20:01

Bu, bash-3.2-də işləyir:

 path="$( dirname "$( which "$0" )" )" 

Burada istifadə nümunəsi:

Diyelim ki $ PATH'da olan ~ / bin qovluğunuz var. Bu kataloqda A scripti var. Bu ~ / bin / lib / B s scriptinin qaynağıdır. Ssenarinin qaynaq ( lib alt qovluğu) ilə müqayisə olunduğu yer, lakin istifadəçinin mövcud kataloquna aid olduğu yer deyil.

Bu ( A daxilində) aşağıdakı kimi həll olunur:

 source "$( dirname "$( which "$0" )" )/lib/B" 

Istifadəçi və ya scripti çağırdığı yerdən fərqli deyil, həmişə işləyəcəkdir.

6
14 окт. Matt Tardiff tərəfindən verilmiş cavab 14 oktyabr. 2008-10-14 19:39 '08 at 7:39 pm 2008-10-14 19:39

Bu etibarlılığa əmin olduğum bir yoldur.

 SCRIPT_DIR=$(dirname $(cd "$(dirname "$BASH_SOURCE")"; pwd)) 
5
14 апр. Apr 14-də BillTorpey tərəfindən verilmiş cavab 2009-04-14 19:00 '09 saat 19: 00-da, 2009-04-14 19:00

Ən yaxşı kompakt həll, mənim fikrimcə, olacaq:

 "$( cd "$( echo "${BASH_SOURCE[0]%/*}" )"; pwd )" 

Bəşdən başqa heç bir şeyə asılılıq yoxdur. readlink , readlinkbasename istifadə edərək nəticədə uyğunluq məsələlərinə yol açacaq, buna görə də mümkün olduqca yaxşı yola readlink .

5
08 окт. AsymLabs tərəfindən verilmiş cavab 08 oktyabr 2013-10-08 17:24 '13 at 17:24 2013-10-08 17:24
  • 1
  • 2

etiketi ilə bağlı digər suallar və ya sual verin