始终在bash中获取相关文件的完整路径

Always get the full path of a relative file in bash

我在/home/http/mywebsite/bin/download.sh中有一个bash脚本。

我在/home/http/mywebsite/config/config.yaml中有一个配置文件

现在,不管我在哪里执行脚本,我都要读取yaml文件。

问题:当我进入/home/http/mywebsite/bin/并运行./download.sh时,一切正常。

当我cd到/home/并运行http/mywebsite/bin/download.sh时,由于相对路径的原因,它找不到配置文件。

如何确保无论在何处执行脚本,都可以读取配置文件。它始终位于config/config.yaml中脚本的上方4个目录中。

脚本如下:

1
2
3
4
#!/bin/bash
# This will give me the root directory of my project which is /home/http/mywebsite/
fullpath="$( cd ../"$( dirname"${BASH_SOURCE[0]}" )" && pwd )"
cat ${fullpath}config/config.yaml

如果我在脚本所在的目录中执行它,这将起作用。

如果我从另一个目录(如/home/i)执行脚本,会得到以下错误:

1
2
cd: ../http/mywebsite/bin: No such file or directory
cat: config/config.yaml: No such file or directory

解决方案?

如果有可能的话,代码片段可以多次沿着一条路径向上遍历,这将解决我的问题。但它对我来说太先进了。

例如,您可以设置变量"cd_up=1"上升多少次。运行循环/SED或任何魔法。

它将绝对字符串从:/主页/http/mywebsite/bin/进入:/主页/http/mywebsite/

将其更改为2,则字符串将更改为:/HOT/HTTP/


最终通过以下方法解决:

1
2
3
4
5
6
#!/bin/bash
cd"$(dirname"$0")"
BASE_DIR=$PWD
# Root directory to the project
ROOT_DIR=${BASE_DIR}/../
cat ${ROOT_DIR}config/config.yaml

这允许我执行脚本,无论我在哪里。


您可以使用哪个命令来确定执行脚本的绝对路径,无论您在哪里运行

1
2
3
BASE_DIR=$(which $0 | xargs dirname)
ROOT_DIR=${BASE_DIR}/../..
cat ${ROOT_DIR}/config/config.yaml

让我们尝试从不同的位置打印路径。

1
2
3
4
5
6
7
8
9
-bash-4.1$ /tmp/dir.sh
$0 - /tmp/dir.sh. Absolute path - /tmp
-bash-4.1$ cd /tmp
-bash-4.1$ ./dir.sh
$0 - ./dir.sh. Absolute path - /tmp
-bash-4.1$
-bash-4.1$ cd /usr/bin
-bash-4.1$ ../../tmp/dir.sh
$0 - ../../tmp/dir.sh. Absolute path - /tmp