【问题标题】:bash scripting: how to find the absolute path of "symlink/.."?bash 脚本:如何找到“符号链接/..”的绝对路径?
【发布时间】:2011-06-07 15:35:28
【问题描述】:

给定两个文件:

generic/scripts/hello.sh
parent/scripts -> generic/scripts

在从任何位置调用parent/scripts/hello.sh 时,我希望(在脚本中)找到父目录的完整路径。在这种情况下parent

主要问题是 parent/scripts/.. 在 unix 中引用 generic。另一方面,涉及正则表达式的所有内容都不是通用的,并且可能容易出错。

不起作用的解决方案:

`dirname $0`/..
realpath  `dirname $0`/..
readlink -f `dirname $0`/..
`cd *something*/..; pwd`
`perl ... abs_path(...)`

由于符号链接,所有这些都将指向generic 而不是parent

所有涉及正则表达式的东西都不是适应性/通用的,对于更复杂的路径可能会失败。路径中可能还有其他.. 和符号链接,你想要祖父母,它是一个涉及.. 的目录名称,你通过$PATH 调用它...

此外,我希望它在任何情况下都能正常工作,即使它是通过$PATH 调用的。

对于这个简单的问题有什么简单安全的解决方案吗?我的意思是它毕竟只是获取父目录!

我用的是什么:

dir=$( dirname $( cd `dirname $0` >/dev/null; pwd ) )

不知道它是否完美,但它的表现似乎符合预期。

【问题讨论】:

  • 你怎么称呼这些脚本?
  • 理想情况下,不应限制它们的调用方式。
  • 只要您实际使用parent/scripts/hello.sh 调用脚本,您的第一个解决方案就可以工作。
  • "...毕竟只是获取父目录"generic 是 hello 的父目录,这就是为什么您使用的所有工具都给您的原因。如果parent/scripts$0 中不可见,您将不会得到它。在 linux 上,cd 到 parent/scripts 并执行 ls -l /proc/$$ 以查看操作系统知道你在哪里。
  • ...嗯...不知何故你有信息。它可以在 $0 中(当从“外部”或 $PATH 调用它时),或者如果您在使用相对路径的子目录之一中调用它,则可以与 pwd 组合。我只是觉得您必须手动处理几种不同的情况,并且您必须使用正则表达式来解析路径……我个人认为这相当丑陋……只是为了获得父级。

标签: linux bash shell unix filepath


【解决方案1】:

试试这个:

basename $(dirname $(dirname $0))

或者只是

$(dirname $(dirname $0))

目前还不清楚您是想要单独使用 parent 还是想要它的完整路径。

【讨论】:

  • double dirname 可以解决问题...唯一要添加的是将它与pwd 连接,当 $0 是相对路径时,还要考虑我们在其中一个子目录中的情况。
  • double dirname 不能解决问题:dirname $(dirname ../../../) 结果为 '..'。
  • @tstone2077 $0 不太可能等于../../../
【解决方案2】:

我会推荐 1) 使用pwd -P,它将始终为您提供物理路径,然后使用相对路径导航到另一个地方这是最安全的。

2) 使用pwd -L

【讨论】:

    【解决方案3】:
    pushd $(dirname $0)
    FOO=$(pwd)
    popd
    

    这为您提供了脚本运行所在目录的绝对路径。

    【讨论】:

      【解决方案4】:

      我用这个给我的 scipt 打电话:../script1,它有一个对../relative/script2的相对调用

      `(cd $0/.. && pwd)`/relative/script2
      

      在脚本1中

      【讨论】:

        【解决方案5】:

        在 bash 中,如果该变量可用,您可以在 $PWD 上执行一些 string manipulation

        对于父目录的路径名,使用:

        ${PWD%/*}
        

        其他例子:

        me@host:/tmp/bash_string/ma ni-pu_la/tion$ echo -e \
        "\$PWD or \${PWD} : " $PWD \
        "\n\${PWD##/*}     : " ${PWD##/*} \
        "\n\${PWD##*/}     : " ${PWD##*/} \
        "\n\${PWD#/*}      : " ${PWD#/*} \
        "\n\${PWD#*/}      : " ${PWD#*/} \
        "\n\${PWD%%/*}     : " ${PWD%%/*} \
        "\n\${PWD%%*/}     : " ${PWD%%*/} \
        "\n\${PWD%/*}      : " ${PWD%/*} \
        "\n\${PWD%*/}      : " ${PWD%*/} \
        "\n" # Gives :
        $PWD or ${PWD} :  /tmp/bash_string/ma ni-pu_la/tion 
        ${PWD##/*}     :  
        ${PWD##*/}     :  tion 
        ${PWD#/*}      :  tmp/bash_string/ma ni-pu_la/tion 
        ${PWD#*/}      :  tmp/bash_string/ma ni-pu_la/tion 
        ${PWD%%/*}     :  
        ${PWD%%*/}     :  /tmp/bash_string/ma ni-pu_la/tion 
        ${PWD%/*}      :  /tmp/bash_string/ma ni-pu_la 
        ${PWD%*/}      :  /tmp/bash_string/ma ni-pu_la/tion
        

        【讨论】:

          【解决方案6】:

          这个呢:

          echo `cd .. && pwd`
          

          【讨论】:

            猜你喜欢
            • 2015-06-10
            • 1970-01-01
            • 1970-01-01
            • 2016-01-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-03-14
            相关资源
            最近更新 更多