使用另一个目录的相对路径运行脚本

时间:2017-05-06 17:45:04

标签: linux bash relative-path

我正在编写一个脚本来编译代码。这些来源位于许多不同的目录中。我将发布源代码,我希望它可以被许多其他人编译。因此,在我的脚本中,我使用相对路径 如果有人在他的机器上运行脚本,则从脚本所在的目录开始,例如./script一切正常。但是,如果脚本是从另一个目录运行的,例如./path/to/script,则路径不正确,脚本不起作用。
我怎么能克服这个?

1 个答案:

答案 0 :(得分:6)

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

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

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

请注意,这是关于导致脚本运行

  • 从脚本所在的文件夹
  • 无论从最初调用脚本的位置

这是我怀疑你想要的,因为它是一个用于编译的脚本,因此它将被放置在src树中的一个非常特定的文件夹中(例如configure脚本或makefile的形式)

原理

  • $0是正在运行的脚本的完整路径。

    • 来自bash人(我添加的格式):
        

      特殊参数

           

      shell专门处理几个参数。这些参数可能          只被引用;不允许分配给他们。         
      ....   

      0 扩展为shell或shell脚本的名称。这是设置为   shell初始化。
      如果使用命令文件调用bash,   $ 0 设置为该文件的名称

      如果使用-c选项启动bash,则设置$ 0   到了要执行的字符串之后的第一个参数,如果是   当下。否则,它被设置为用于调用bash的文件名
      ,   由零参数给出。   

  • dirname返回其参数的路径

  • cd更改当前目录

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

从另一个角度来看

对于质量控制和冗余错误检查的度量,您可能希望实现一个包装函数,该函数检查特定文件夹结构或某些文件的存在,以指示一切正确。 (无论出于何种原因,dirnamecd命令都不起作用 - 我在本文的底部有一个Mac示例。这个概念有两个方面:

  1. 您正在设置当前目录
  2. 您正在检查您所做的事情是否有效。
  3. 例如:

    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(例如,对于{{} 1}}文件,其顶行可能为: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 起作用,因为不需要彻底检查脚本文件的符号链接等。(再次......)便携式源代码tarball等,我非常怀疑是这样的。)

    我建议阅读此主题:Getting the source directory of a Bash script from within  如果您想要或者需要彻底了解这个主题,可以更全面地应用它。

    我再次使用您所知道的为您所需的内容量身定制 - 例如,使用bash可能会被认为通常更强“健壮”,但是,在Mac OS X上,这将为您提供dirname "$(readlink -f "$0")",并且对于可移植脚本没有任何实际好处,但更适用于引用可能符号链接和/或包含在$ PATH目录中的已安装二进制文件的位置