目录
需求描述
方法一:使用 dirname 和 readlink 命令
方法二:使用 BASH_SOURCE 变量
方法三:仅使用纯 Bash 实现
需求描述
工作中经常有这样情况,需要在脚本内部获取该脚本自己所在目录的绝对路径。
假如有一个脚本/a/b/c/work.sh。如何在work.sh内部获取work.sh所在目录的绝对路径,即获取到/a/b/c,或者/a/b/c/也可以。要求无论在哪个目录执行work.sh都能达到目的。
能适用于以下情形:
情形1:在/a/b/c目录下执行 bash work.sh或者bash ./work.sh 或者 bash /a/b/c/work.sh
情形2:在/a目录执行bash b/c/work.sh或者./b/c/work.sh 或者 bash /a/b/c/work.sh
情形3:在/a/b/c/d/目录下执行 bash ../work.sh 或者 bash /a/b/c/work.sh
以下是几种常见且有效的实现方式。
方法一:使用 dirname
和 readlink
命令
dirname
命令用于返回路径中的目录部分,readlink -f
用于获取文件的绝对路径。
#!/bin/bash
# 获取脚本的绝对路径
script_path=$(readlink -f "$0")
echo "$script_path"
# 获取脚本所在目录的绝对路径
script_dir=$(dirname "$script_path")
echo "$script_dir"
在上述代码中,$0
代表当前正在执行的脚本名。readlink -f "$0"
会将脚本的相对路径转换为绝对路径,然后使用 dirname
命令提取出该绝对路径中的目录部分。
方法二:使用 BASH_SOURCE
变量
BASH_SOURCE
是一个数组变量,BASH_SOURCE[0]
存储着当前执行脚本的文件名。结合 dirname
和 realpath
命令可以获取脚本所在目录的绝对路径。
#!/bin/bash
# 获取脚本的绝对路径
script_path=$(realpath "${BASH_SOURCE[0]}")
echo $script_path
# 获取脚本所在目录的绝对路径
script_dir=$(dirname "$(realpath "${BASH_SOURCE[0]}")")
echo "$script_dir"
方法三:仅使用纯 Bash 实现
如果系统不支持 readlink
或 realpath
命令,也可以使用纯 Bash 代码来实现:
#!/bin/bash
# 获取脚本的相对路径
relative_dir=$(dirname "$0")
# 转换为绝对路径
pushd "$relative_dir" > /dev/null
script_dir=$(pwd)
popd > /dev/null
echo "$script_dir"
在这个实现中,dirname "$0"
先获取脚本的相对目录,然后使用 pushd
命令进入该目录,pwd
命令获取当前工作目录的绝对路径,最后使用 popd
命令返回到原来的目录。> /dev/null
用于抑制命令的输出信息。
一个等价的做法是:
script_dir=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd)
以上三种方法都能确保无论在哪个目录下执行 work.sh
脚本,都可以准确获取到该脚本所在目录的绝对路径。