【问题标题】:Reliable way for a Bash script to get the full path to itself [duplicate]Bash脚本获取自身完整路径的可靠方法[重复]
【发布时间】:2011-06-14 00:41:23
【问题描述】:

我有一个需要知道其完整路径的 Bash 脚本。我试图找到一种广泛兼容的方式来做到这一点,而不会以相对或时髦的路径结束。我只需要支持 Bash,不需要支持 sh、csh 等。

到目前为止我发现了什么:

  1. Getting the source directory of a Bash script from within 接受的答案解决了通过 dirname $0 获取脚本路径的地址,这很好,但可能会返回 相对 路径(如.),如果您想更改脚本中的目录并且路径仍指向脚本的目录,这是一个问题。不过,dirname 将成为难题的一部分。

  2. Bash script absolute path with OS X 接受的答案(特定于 OS X,但答案无论如何都有效) 提供了一个函数来测试 $0 是否看起来是相对的,如果是这样,将在它前面加上 $PWD。但是结果中仍然可以包含相对位(尽管总体而言它是绝对的)——例如,如果脚本是目录 /usr/bin 中的 t 并且您在 /usr 中并且您键入 bin/../bin/t 来运行它(是的,这很复杂),你最终会得到/usr/bin/../bin 作为脚本的目录路径。哪个有效,但是...

  3. readlink 解决方案on this page,如下所示:

    # Absolute path to this script. /home/user/bin/foo.sh
    SCRIPT=$(readlink -f $0)
    # Absolute path this script is in. /home/user/bin
    SCRIPTPATH=`dirname $SCRIPT`
    

    readlink 不是 POSIX,显然该解决方案依赖于 GNU 的 readlink,其中 BSD 因某种原因无法工作(我无法访问类似 BSD 的系统来检查)。

所以,有各种方法,但它们都有自己的警告。

有什么更好的方法?其中“更好”的意思是:

  • 给我绝对路径。
  • 即使在以复杂的方式调用时也能去掉时髦的位(参见上面对#2 的评论)。 (例如,至少适度规范化路径。)
  • 仅依赖于 Bash 主义或几乎可以肯定是最流行的 *nix 系统(GNU/Linux、BSD 和类似 BSD 的系统,如 OS X 等)的东西。
  • 尽可能避免调用外部程序(例如,首选 Bash 内置程序)。
  • 已更新,感谢您的提醒,wich)它不必解析符号链接(事实上,我更希望它不理会它们,但这不是要求)。

【问题讨论】:

  • 请看BashFAQ/028
  • 上述解决方案#3 中的链接已失效。谁有更新的?
  • $(readlink -f $0) - 不适用于 Mac OS 10.9.2
  • (1.) link you give in your own question 有大约 10 次问题投票,10 次收藏,>15 次回答投票。 (2.) 你的总结有些虚伪。 (您提供的链接的第一个修订答案是“DIRECTORY=$(cd dirname $0 && pwd)”......这与您的摘要“通过 dirname $0 获取脚本的路径”不匹配,并且不符合您所说的“返回相对路径”。)
  • 这不完全是 stackoverflow.com/questions/59895/… 的副本。该问题要求源目录,其中还可能包括相对路径(正如一些建议$0 的答案所证明的那样)。这个问题具体是绝对路径,不一样。

标签: bash path


【解决方案1】:

这是我想出的(编辑:加上sfstewmanlevigrokerKyle StrandRob Kennedy 提供的一些调整),这似乎最符合我的“更好”标准:

SCRIPTPATH="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"

SCRIPTPATH 行似乎特别迂回,但为了正确处理空格和符号链接,我们需要它而不是 SCRIPTPATH=`pwd`

包含输出重定向 (>/dev/null 2>&1) 可以处理罕见的 (?) 情况,在这种情况下,cd 可能会产生会干扰周围 $( ... ) 捕获的输出。 (如切换到cd being overridden to also ls a directory后。)

另请注意,那里(或在我的任何其他答案中)不适合深奥的情况,例如执行根本不是来自可访问文件系统中的文件的脚本(这是完全可能的)见过)。

cd 之后和"$0" 之前的-- 以防目录以- 开头。

【讨论】:

  • 仍然无法分辨文件本身的名称是什么?
  • 如果脚本位于$PATH 的目录中并且您将其称为bash scriptname,则此方法不起作用。在这种情况下,$0 不包含任何路径,只是 scriptname
  • -1(请不要私信,只是为了让真正的答案猫可能更接近顶部):我曾经做过类似的事情(我用过:"$(cd -P "$(dirname "$0")" && pwd)"直到今天,但 Andrew Norrie 的答案涵盖了更多案例(即:PATH="/some/path:$PATH" ; bash "script_in_path" :仅适用于他的答案,而不适用于您的答案(因为 $0 仅包含 "script_in_path" 而没有指示(在 $PATH 中)bash 找到它的位置)。正确的是:ABSOLUTE_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/$(basename "${BASH_SOURCE[0]}")"(即,@andrew-norrie 的答案:涵盖所有情况,imo)
  • 我希望您使用dirname "${BASH_SOURCE[0]}" 而不是dirname "$0" 来增加对源脚本的支持。
  • 最后调整:cd -- "$(dirname "$0")" 以避免以连字符开头的目录出现问题。
【解决方案2】:

也许以下问题的公认答案可能会有所帮助。

How can I get the behavior of GNU's readlink -f on a Mac?

鉴于您只想规范化从连接 $PWD$0 获得的名称(假设 $0 不是绝对开头),只需使用一系列正则表达式替换 @987654325 @ 之类的。

是的,我知道它看起来很糟糕,但它会起作用并且是纯 Bash。

【讨论】:

  • 谢谢。重新链接的问题,它仍然依赖于更改目录和使用pwd,这是我觉得我的解决方案很笨重的地方。正则表达式很有趣。不过,我不禁担心边缘情况。
  • 是的,它需要一些很好的测试,但据我所知,没有便携式的一次性解决方案可以为您规范化名称。
  • 哦,当然,正则表达式只能在 *nix 上运行,它会在 cygwin 环境或类似环境中运行。
【解决方案3】:

为了它,我已经对一个纯文本、纯在 Bash 中执行操作的脚本进行了一些修改。我希望我抓住了所有的边缘情况。

请注意,我在另一个答案中提到的 ${var//pat/repl} 不起作用,因为您不能让它仅替换最短的匹配项,这是替换 /foo/../ 的问题,例如/*/../ 将在它之前获取所有内容,而不仅仅是单个条目。而且由于这些模式并不是真正的正则表达式,我不知道如何使它起作用。所以这是我想出的非常复杂的解决方案,享受吧。 ;)

顺便说一句,如果您发现任何未处理的边缘情况,请告诉我。

#!/bin/bash

canonicalize_path() {
  local path="$1"
  OIFS="$IFS"
  IFS=$'/'
  read -a parts < <(echo "$path")
  IFS="$OIFS"

  local i=${#parts[@]}
  local j=0
  local back=0
  local -a rev_canon
  while (($i > 0)); do
    ((i--))
    case "${parts[$i]}" in
      ""|.) ;;
      ..) ((back++));;
      *) if (($back > 0)); then
           ((back--))
         else
           rev_canon[j]="${parts[$i]}"
           ((j++))
         fi;;
    esac
  done
  while (($j > 0)); do
    ((j--))
    echo -n "/${rev_canon[$j]}"
  done
  echo
}

canonicalize_path "/.././..////../foo/./bar//foo/bar/.././bar/../foo/bar/./../..//../foo///bar/"

【讨论】:

    【解决方案4】:

    接受的解决方案(对我来说)不方便,不能“来源”:
    如果您从“source ../../yourScript”调用它,$0 将是“bash”!

    以下函数(对于 bash >= 3.0)为我提供了正确的路径,但是可能会调用脚本(直接或通过 source,使用绝对或相对路径):
    (“正确路径”是指被调用脚本的完整绝对路径,即使是从另一个路径直接调用或使用“source”调用)

    #!/bin/bash
    echo $0 executed
    
    function bashscriptpath() {
      local _sp=$1
      local ascript="$0"
      local asp="$(dirname $0)"
      #echo "b1 asp '$asp', b1 ascript '$ascript'"
      if [[ "$asp" == "." && "$ascript" != "bash" && "$ascript" != "./.bashrc" ]] ; then asp="${BASH_SOURCE[0]%/*}"
      elif [[ "$asp" == "." && "$ascript" == "./.bashrc" ]] ; then asp=$(pwd)
      else
        if [[ "$ascript" == "bash" ]] ; then
          ascript=${BASH_SOURCE[0]}
          asp="$(dirname $ascript)"
        fi  
        #echo "b2 asp '$asp', b2 ascript '$ascript'"
        if [[ "${ascript#/}" != "$ascript" ]]; then asp=$asp ;
        elif [[ "${ascript#../}" != "$ascript" ]]; then
          asp=$(pwd)
          while [[ "${ascript#../}" != "$ascript" ]]; do
            asp=${asp%/*}
            ascript=${ascript#../}
          done
        elif [[ "${ascript#*/}" != "$ascript" ]];  then
          if [[ "$asp" == "." ]] ; then asp=$(pwd) ; else asp="$(pwd)/${asp}"; fi
        fi  
      fi  
      eval $_sp="'$asp'"
    }
    
    bashscriptpath H
    export H=${H}
    

    关键是检测“source”的情况,并使用${BASH_SOURCE[0]}取回实际的脚本。

    【讨论】:

      【解决方案5】:

      我发现在 Bash 中获得完整规范路径的最简单方法是使用 cdpwd

      ABSOLUTE_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/$(basename "${BASH_SOURCE[0]}")"
      

      使用${BASH_SOURCE[0]} 代替$0 会产生相同的行为,无论脚本是以&lt;name&gt; 还是source &lt;name&gt; 调用。

      【讨论】:

      • 如果最初指定的文件是符号链接,这似乎不起作用。我认为您需要在循环中使用诸如 readlink (或 ls)之类的东西,以确保您找到了最终的非符号链接文件。我一直在寻找更简洁的东西,但无论如何您都可以在dalvik/dx/etc/dx 下找到我在 Android 代码库中使用的解决方案的最新版本。
      • @danfuzz 见丹尼斯威廉姆森评论,关于使用 -P 密码。它应该做你想做的事。
      • @over_optimistic 我不相信 -P 在这里有帮助:如果 $0 命名符号链接,那么 cd $(dirname $0); pwd -P 仍然只是告诉您符号链接所在的目录,而不是实际脚本所在的物理目录居住。您确实需要在脚本名称上使用 readlink 之类的东西,除了 readlink 实际上不是 POSIX 并且它在操作系统之间的实践中似乎有所不同。
      • @danfuzz:linux.die.net/man/8/symlinks 看起来是个好东西,既有“更干净”的符号链接,又能找到它们的完整路径
      • +1 在 Mac 上的所有合理场景中都能很好地工作。没有外部依赖,并且在 1 行中执行。我用它来获取脚本的目录,如下所示: SCRIPTPATH=$(cd `dirname "${BASH_SOURCE[0]}"` && pwd)
      【解决方案6】:

      我很惊讶这里没有提到realpath 命令。我的理解是它具有广泛的便携性/移植性。

      您的初始解决方案变为:

      SCRIPT=`realpath $0`
      SCRIPTPATH=`dirname $SCRIPT`
      

      并根据您的喜好保留未解析的符号链接:

      SCRIPT=`realpath -s $0`
      SCRIPTPATH=`dirname $SCRIPT`
      

      【讨论】:

      • @bolinfest:自Jan 2012 / v8.15 以来,realpath 是 GNU coreutils 的一部分。如果您正在运行一个包含 coreutils(基本上应该是所有这些)的最新 Linux 发行版并且缺少 realpath,那么打包程序肯定已经不遗余力地将 realpath 分离到另一个包中。 (当前的 coreutils 版本是 8.21,发布于 2013 年 2 月 4 日。我正在运行的版本(在 Arch Linux 上)似乎是这个版本,8.21,并且该软件包包括 realpath,就像任何有想法的软件包一样;)
      • 使用真实路径,甚至更短:SCRIPT_PATH=$(dirname $(realpath -s $0))
      • 它也是 Debian Wheezy 上的一个额外包。 coreutils 版本是 8.13,还没有包含它。
      • realpath 在 POSIX 标准中是 not mentioned
      • 当给定带有空格的文件名时,这些答案中的许多(如果不是大多数)都是错误的。 SCRIPT_PATH=$(dirname "$(realpath -s "$0")") 是 GuySoft 答案的固定版本,尽管使用 $BASH_SOURCE 仍然比 $0 更可靠(这取决于安装了 realpath,一个非 POSIX 工具)。
      【解决方案7】:

      获取shell脚本的绝对路径

      它不使用 readlink 中的-f 选项,因此它应该可以在 BSD/Mac OS X 上运行。

      支持

      • source ./script(当被.点运算符调用时)
      • 绝对路径/path/to/script
      • ./script 等相对路径
      • /path/dir1/../dir2/dir3/../script
      • 从符号链接调用时
      • 当符号链接嵌套时,例如)foo-&gt;dir1/dir2/bar bar-&gt;./../doe doe-&gt;script
      • 当调用者更改脚本名称时

      我正在寻找此代码不起作用的极端情况。请告诉我。

      代码

      pushd . > /dev/null
      SCRIPT_PATH="${BASH_SOURCE[0]}";
      while([ -h "${SCRIPT_PATH}" ]); do
          cd "`dirname "${SCRIPT_PATH}"`"
          SCRIPT_PATH="$(readlink "`basename "${SCRIPT_PATH}"`")";
      done
      cd "`dirname "${SCRIPT_PATH}"`" > /dev/null
      SCRIPT_PATH="`pwd`";
      popd  > /dev/null
      echo "srcipt=[${SCRIPT_PATH}]"
      echo "pwd   =[`pwd`]"
      

      已知问题

      脚本必须在磁盘上的某个地方。让它通过网络。 如果您尝试从 PIPE 运行此脚本,它将无法正常工作

      wget -o /dev/null -O - http://host.domain/dir/script.sh |bash
      

      从技术上讲,它是未定义的。实际上,没有理智的方法可以检测到这一点。 (协程无法访问父进程的环境。)

      【讨论】:

      • 如其他地方所述,我认为这不是一个极端情况,但 readlink -f 不是标准参数,而且很可能不可用,例如在我的 BSD 上。
      • 我遇到了一个无法正常工作的角落案例。我在~/scripts/myscript 下有一个脚本,在~/bin/myscript 有一个符号链接,它指向../scripts/myscript。从~/ 运行~/bin/myscript 导致它认为脚本的位置是~/。解决方案here 运行良好,看起来与您的解决方案非常相似
      【解决方案8】:

      由于我的 Linux 系统上没有默认安装 realpath,因此以下对我有用:

      SCRIPT="$(readlink --canonicalize-existing "$0")"
      SCRIPTPATH="$(dirname "$SCRIPT")"
      

      $SCRIPT 将包含脚本的真实文件路径,$SCRIPTPATH 将包含脚本所在目录的真实路径。

      在使用之前阅读this answer的cmets。

      【讨论】:

      • OP 已经注意到了这个解决方案,并因为它不是 POSIX 而忽略了它——但这至少对于基于 GNU 的系统来说是很好和整洁的。其主要特点是它解析符号链接
      【解决方案9】:

      我今天刚重温这个问题,发现Get the source directory of a Bash script from within the script itself

      DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
      

      链接的答案有更多变体,例如对于脚本本身是符号链接的情况。

      【讨论】:

      【解决方案10】:

      用途:

      SCRIPT_PATH=$(dirname `which $0`)
      

      which 将在 shell 提示符下输入传递的参数时执行的可执行文件的完整路径打印到标准输出(这是 $0 包含的内容)

      dirname 从文件名中去除非目录后缀。

      因此,无论是否指定了路径,您最终都会得到脚本的完整路径。

      【讨论】:

      • dirname ./myscript 返回.。这可能不是您想要的。
      • @BobbyNorton 是的,因为此时的非目录后缀就是.。但是,如果您在脚本名称上运行which 并将其存储在变量中,例如a=$(which ./myscript),它将返回完整路径,例如/tmp/myscript,如果传递给dirname,它将返回路径。有趣的是,如果您运行which ./myscript 而不将其分配给变量,它只会返回./myscript。我怀疑这是因为当将它分配给一个变量时,它会在另一个 shell 中执行并将完整路径传递给 bash。
      • 不幸的是,这似乎不适用于 OS X。如果可以的话,这将是一个很好的解决方案!
      • @Matt 我不会使用“which”命令,除非该命令位于当前路径中。仅搜索路径中的命令。如果您的脚本不在路径中,它将永远找不到。
      • 如果这个脚本是 source 的,$0 将引用 'sourcing' 脚本,可能不会给你你想要的
      【解决方案11】:

      我们已将我们自己的产品 realpath-lib 放在 GitHub 上,供社区免费且不受阻碍地使用。

      无耻的插件,但有了这个 Bash 库,你可以:

      get_realpath <absolute|relative|symlink|local file>
      

      这个函数是库的核心:

      function get_realpath() {
      
      if [[ -f "$1" ]]
      then 
          # file *must* exist
          if cd "$(echo "${1%/*}")" &>/dev/null
          then 
              # file *may* not be local
              # exception is ./file.ext
              # try 'cd .; cd -;' *works!*
              local tmppwd="$PWD"
              cd - &>/dev/null
          else 
              # file *must* be local
              local tmppwd="$PWD"
          fi
      else 
          # file *cannot* exist
          return 1 # failure
      fi
      
      # reassemble realpath
      echo "$tmppwd"/"${1##*/}"
      return 0 # success
      
      }
      

      它不需要任何外部依赖,只需要 Bash 4+。还包含get_dirnameget_filenameget_stemnamevalidate_path validate_realpath 的函数。它是免费的、干净的、简单的和有据可查的,所以它也可以用于学习目的,毫无疑问可以改进。跨平台尝试。

      更新:经过一些审查和测试,我们已将上述函数替换为达到相同结果(不使用 dirname,仅使用纯 Bash)但效率更高的函数:

      function get_realpath() {
      
          [[ ! -f "$1" ]] && return 1 # failure : file does not exist.
          [[ -n "$no_symlinks" ]] && local pwdp='pwd -P' || local pwdp='pwd' # do symlinks.
          echo "$( cd "$( echo "${1%/*}" )" 2>/dev/null; $pwdp )"/"${1##*/}" # echo result.
          return 0 # success
      
      }
      

      这还包括一个环境设置no_symlinks,它提供了将符号链接解析到物理系统的能力。默认情况下,它会保持符号链接完整。

      【讨论】:

      • 谢谢本。网站新手(作为贡献者),我已根据需要修改了条目。我不认为这里有任何商业问题,因为我们无限制地提供代码。我们也将其视为一个很好的学习工具,并为此目的对其进行了详尽的记录。
      • 不幸的是,更新后的get_realpath 中的符号链接解析不适用于输入路径的最后(基本名称)部分,仅适用于较早的(目录名称)部分。我在 Github 存储库中为此打开了一个问题。希望有一个解决方案,这样我们就可以获得readlink -f 的纯 bash 等价物。 github.com/AsymLabs/realpath-lib/issues/1
      • @Mikael Auno 您提供了一个出色的测试用例。我们已经在 github 上进行了讨论,并将对其进行查看。
      • 请注意,第二个版本也是 100% POSIX 兼容的,并且至少在 dash 中未经修改即可工作! :+1:
      • 您可以在自述文件中添加一些安装说明。我尝试安装它,但无法让它工作。
      【解决方案12】:

      再次考虑这个问题:这个线程中引用了一个非常流行的解决方案,它的起源是here

      DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
      

      由于使用了 dirname,我一直远离这个解决方案 - 它可能会带来跨平台的困难,特别是如果出于安全原因需要锁定脚本时。但作为纯 Bash 替代方案,如何使用:

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

      这会是一个选择吗?

      【讨论】:

      • BASH_SOURCE 似乎是使用PATH=/path/to/your/script:$PATH yourscript.sh 运行脚本所必需的。不幸的是,这需要 bash
      【解决方案13】:

      您可以尝试定义以下变量:

      CWD="$(cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
      

      或者你可以在 Bash 中尝试以下功能:

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

      这个函数接受一个参数。如果参数已经有绝对路径,则按原样打印,否则打印$PWD变量+文件名参数(不带./前缀)。

      相关:

      【讨论】:

      • 你的方法都不能遵循递归符号链接
      【解决方案14】:

      简单地说:

      BASEDIR=$(readlink -f $0 | xargs dirname)
      

      不需要花哨的运算符。

      【讨论】:

        【解决方案15】:

        回答这个问题很晚,但我使用:

        SCRIPT=$( readlink -m $( type -p ${0} ))      # Full path to script handling Symlinks
        BASE_DIR=`dirname "${SCRIPT}"`                # Directory script is run in
        NAME=`basename "${SCRIPT}"`                   # Actual name of script even if linked
        

        【讨论】:

        • 提供的完整路径正是我想要的。紧凑、高效、可靠。干得好!
        • 并非所有 readlink 的实现都有 -m 我相信 OP 正在寻找一种不依赖于 GNU readlink 扩展功能的解决方案。
        • 我刚刚尝试了很多这些解决方案,当我在 PATH 中有一个指向脚本的符号链接并将其称为“ bash -e my_script"
        • 如果你必须去sudo -s source somescript.sh(即fat32分区没有机会设置+x位)这不起作用(而${BASH_SOURCE[0]}仍然有效)
        【解决方案16】:

        如果我们使用 Bash,我相信这是最方便的方式,因为它不需要调用任何外部命令:

        THIS_PATH="${BASH_SOURCE[0]}";
        THIS_DIR=$(dirname $THIS_PATH)
        

        【讨论】:

        • $(dirname 调用 dirname(1)。
        【解决方案17】:

        我已经成功使用了以下方法一段时间(但不是在 OS X 上),据我所知,它只使用内置的 shell 并处理“source foobar.sh”的情况。

        下面(匆忙拼凑的)示例代码的一个问题是该函数使用了 $PWD,它在函数调用时可能正确也可能不正确。所以需要处理。

        #!/bin/bash
        
        function canonical_path() {
          # Handle relative vs absolute path
          [ ${1:0:1} == '/' ] && x=$1 || x=$PWD/$1
          # Change to dirname of x
          cd ${x%/*}
          # Combine new pwd with basename of x
          echo $(pwd -P)/${x##*/}
          cd $OLDPWD
        }
        
        echo $(canonical_path "${BASH_SOURCE[0]}")
        
        type [
        type cd
        type echo
        type pwd
        

        【讨论】:

          【解决方案18】:

          试试这个:

          cd $(dirname $([ -L $0 ] && readlink -f $0 || echo $0))
          

          【讨论】:

          • readlink 在 BSD 上(因此在 OS X 上)不能这样工作,问题是指替代方案。
          • 在 Linux CentOS 7 上,当使用完整路径 (/home/me/script.sh) 执行脚本时可以正常工作,但使用 sh script.sh./script.sh 执行脚本时仅返回 .
          【解决方案19】:

          另一种方法:

          shopt -s extglob
          
          selfpath=$0
          selfdir=${selfpath%%+([!/])}
          
          while [[ -L "$selfpath" ]];do
            selfpath=$(readlink "$selfpath")
            if [[ ! "$selfpath" =~ ^/ ]];then
              selfpath=${selfdir}${selfpath}
            fi
            selfdir=${selfpath%%+([!/])}
          done
          
          echo $selfpath $selfdir
          

          【讨论】:

            【解决方案20】:

            一个班轮

            `dirname $(realpath $0)`
            

            【讨论】:

            • 这似乎对我有用,我认为它可能因为没有任何额外的评论来解释它的工作原理而被否决。
            • FWIW 我喜欢这个解决方案的简洁性,它在 Ubuntu 16.04 LTS 上开箱即用。
            • 真实路径在 Mac OS 上不存在
            【解决方案21】:

            易于阅读?下面是一个替代方案。它忽略符号链接

            #!/bin/bash
            currentDir=$(
              cd $(dirname "$0")
              pwd
            )
            
            echo -n "current "
            pwd
            echo script $currentDir
            

            自从我几年前发布上述答案以来,我已经将自己的实践发展为使用这种 linux 特定的范例,它可以正确处理符号链接:

            ORIGIN=$(dirname $(readlink -f $0))
            

            【讨论】:

            • 我收到bash: currentDir: command not found
            • 这只会解析目录的符号链接。它将无法解析路径的符号链接。考虑 $0 何时是指向同一目录中脚本的链接。
            【解决方案22】:

            Bourne shell (sh) 兼容方式:

            SCRIPT_HOME=`dirname $0 | while read a; do cd $a && pwd && break; done`
            

            【讨论】:

            • 为什么我们需要while read a 部分?为什么不直接cd $(dirname $a) &amp;&amp; pwd
            • 因为$( ... ) 在 no-bash shell 中不起作用。我看到使用$( ... ) 表达式并多次以#!/bin/sh 开头的错误脚本。我建议在开头写#!/bin/bash 或停止使用$( ... ) 表达式。此示例为第一条推荐。
            • 抱歉有错。 "此示例用于第二次推荐"
            【解决方案23】:

            更简单地说,这对我有用:

            MY_DIR=`dirname $0`
            source $MY_DIR/_inc_db.sh
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2017-04-17
              • 1970-01-01
              • 2023-03-07
              • 2018-10-24
              • 2010-11-25
              • 2011-11-01
              相关资源
              最近更新 更多