此问题在此处已有答案:
How do I get the directory where a Bash script is located from within the script itself?(74个答案)
八年前就关门了。
给定:
some.txt
dir
|-cat.sh
cat.sh包含以下内容:
cat ../some.txt
那么在dir
中运行./cat.sh
可以正常工作,而在与dir
相同的级别上运行./dir/cat.sh
则不行。我认为这是由于不同的工作目录造成的。有没有简单的方法使路径../some.txt
相对于cat.sh
的位置?
3条答案
按热度按时间uelo1irk1#
您要做的是获取脚本的绝对路径(可通过
${BASH_SOURCE[0]}
获得),然后在脚本开始时使用该路径获取父目录和cd
。这将使你的shell脚本独立于你从哪里调用它。每次你运行它时,就好像你在
dir
中运行./cat.sh
一样。请注意,此脚本仅在您直接调用脚本(即不通过符号链接)时有效,否则查找脚本的当前位置会变得有点棘手)
alen0pnh2#
@ MartinKonecny的答案提供了一个有效的解决方案,但是-正如他提到的-只有当实际脚本不是通过驻留在 * 不同目录 * 中的 * 符号链接 * 调用时,它才起作用。
此答案涵盖了该情况:一个解决方案,当脚本通过 * 符号链接 * 或甚至 * 符号链接链*调用时也能工作:
**Linux / GNU
readlink
**解决方案:如果您的脚本只需要在Linux上运行,或者您知道**GNU
readlink
**在$PATH
中,请使用readlink -f
,它可以方便地将符号链接解析到其 * 最终 * 目标:请注意,GNU
readlink
有3个相关的选项,用于将符号链接解析为其最终目标的完整路径:第一个是第五个是第一个。由于根据定义目标存在于该场景中,因此可以使用3个选项中的任何一个;我在这里选择
-f
,因为它是最有名的一个。多(类Unix)平台解决方案(包括具有一组仅POSIX实用程序的平台):
如果脚本必须在满足以下条件的任何平台上运行:
readlink
实用程序,但缺少-f
选项(在GNU意义上,将符号链接解析到其最终目标)-例如,macOS。readlink
的BSD实现的 * 旧版本 *;请注意,FreeBSD/PC-BSD * 的最新版本支持-f
。readlink
,但具有POSIX兼容实用程序-例如HP-UX(感谢@Charles Duffy)。以下解决方案受https://stackoverflow.com/a/1116890/45375启发,定义了helper shell函数
rreadlink()
,它将给定的符号链接解析为循环中的最终目标--此函数实际上是GNUreadlink
的-e
选项的POSIX兼容实现,它**类似于-f
选项,只是最终目标必须存在注意:此函数是一个**
bash
**函数,并且仅在使用具有POSIX兼容选项的POSIX实用程序时才与POSIX兼容。有关此函数 * 本身 * 用POSIX兼容shell代码编写的版本(对于/bin/sh
),请参阅here。readlink
可用,则使用它(不带选项)-在大多数现代平台上为true。ls -l
的输出,这是确定符号链接目标的唯一符合POSIX的方法。->
,这将中断-但这是不可能的。(Note缺少
readlink
的平台仍然可以提供用于解析符号链接的其他非POSIX方法;例如,@ CharlesDuffy提到HP-UX的find
实用程序支持%l
字符,其-printf
主字符;为了简洁起见,该函数不尝试检测此类情况。)rreadlink
in the npm registry找到;在Linux和macOS上,使用[sudo] npm install -g rreadlink
进行安装;在其他平台上(假设它们具有bash
),请按照手动安装说明进行操作。如果参数是符号链接,则返回最终目标的规范路径;否则,返回参数自身的规范路径。
hgqdbh6s3#
只要一行就可以了。