我正在写一个脚本来编译代码。源位于许多不同的目录中。我将发布源代码,并希望其他许多人对其进行编译。因此,在我的脚本中,我使用相对路径。
如果有人在其计算机上运行脚本,则从脚本所在的目录(如./script)运行就可以了。但是,如果脚本是从另一个目录(如./path/to/script)运行的,则路径不正确,脚本将不起作用。
我该如何克服呢?

最佳答案

一个简单的起点可能是将其添加到脚本的顶部:

#!/bin/bash
scriptdir="$(dirname "$0")"
cd "$scriptdir"

以下所有代码都将像在脚本目录中运行一样发生。

请注意,这是关于使脚本运行
  • 从脚本所在的文件夹
  • 无论最初从哪里调用脚本

  • 考虑到这是一个用于编译的脚本,因此我怀疑您要使用的是什么,因此它将被放置在src树的非常特定的文件夹中(例如configure脚本或makefile的形式)

    基本原理
  • $0是正在运行的脚本的完整路径。
  • 来自bash人(我添加的格式):

  • dirname返回其参数
  • 的路径
  • cd更改当前目录

  • 因此,将在每个脚本中位于顶部的该脚本运行,就像当前在该目录中键入./script一样。

    从另一个 Angular 来看

    对于质量控制和冗余错误检查的措施,您可能需要实现一个包装器功能,该功能检查特定的文件夹结构或某些文件的存在,这些文件指示一切正确。 (出于种种原因说出dirnamecd命令都不起作用的原因-在这篇文章的底部,我有一个Mac的示例)。这个概念有两个方面:
  • 您正在做一些工作来设置当前目录
  • 您正在检查所做的工作是否正常。

  • 例如:
    runcheck () {
    versioncheck () {
    
    head -n1 version | grep -q "### myapp V"
    
    }
    
    backout () {
    echo "Problem verifying source paths.  Are you sure your archive is complete?"
    exit
    }
    
    [ -d ./src ] && [ -d ./docs ] && [ -d ../myapp ] && (versioncheck) || backout
        return
    }
    

    该代码将检查以下内容:
  • 目录src与可执行脚本
  • 存在于同一路径中
  • 目录docs与可执行脚本
  • 存在于同一路径中
  • 目录myapp位于可执行脚本
  • 下一级路径中
  • 在与可执行脚本相同的路径中有一个名为version的文件,并且它是的第一行包含字符串### myapp V(例如,对于version文件,其顶行可能显示为:### myapp V1.4 ###)

  • 然后,您可以将runcheck命令放在脚本中任何重要的位置,以确保您位于正确的位置:

    完整的实现示例:
    #!/bin/bash
    
    scriptdir="$(dirname "$0")"
    cd "$scriptdir"
    
    runcheck () {
    versioncheck () {
        head -n1 version | grep -q "### myapp V"
    }
    
    backout () {
        echo "Problem verifying source paths.  Are you sure your archive is complete?"
        exit
    }
    
    [ -d ./src ] && [ -d ./docs ] && [ -d ../myapp ] && (versioncheck) || backout
        return
    }
    
    runcheck #initial check at start of script
    
    ## bunch of code
    ## goes here
    
    runcheck #just checking again
    
    ## bunch of code
    ## goes here
    
    runcheck #final check before really doing something bad
    
    ## end of script
    

    旁注/补充:当不需要进行彻底检查以解决脚本文件的符号链接(symbolic link)等问题时,这将适用于bash。(再次...在便携式源代码tarball等中,我非常怀疑是案件)。

    我建议阅读此线程:Getting the source directory of a Bash script from within
    如果您希望或曾经需要对此主题有透彻的了解,以更全面地应用它。

    同样,我会根据您的需求量身定制您所知道的内容,例如,通常认为使用dirname "$(readlink -f "$0")"会更“健壮” ,但是,在Mac OS X上,这会为您提供readlink: illegal option -- f,并不是真正的有益于可移植脚本,但更适用于引用可能被符号链接(symbolic link)和/或包含在$ PATH目录中的已安装二进制文件的位置

    07-24 09:48
    查看更多