我有一个bash脚本文件,该文件放在添加到$ PATH的某个目录下,以便可以从任何目录调用该脚本。
在与脚本相同的目录下还有另一个文本文件。我想知道如何在脚本中引用文本文件吗?
例如,如果脚本仅用于输出文本文件的内容,cat textfile
则将不起作用,因为当从其他目录调用脚本时,找不到文本文件。
我有一个bash脚本文件,该文件放在添加到$ PATH的某个目录下,以便可以从任何目录调用该脚本。
在与脚本相同的目录下还有另一个文本文件。我想知道如何在脚本中引用文本文件吗?
例如,如果脚本仅用于输出文本文件的内容,cat textfile
则将不起作用,因为当从其他目录调用脚本时,找不到文本文件。
Answers:
只要没有符号链接(在路径扩展或脚本本身中),这些命令就应该起作用:
MYDIR="$(dirname "$(realpath "$0")")"
MYDIR="$(dirname "$(which "$0")")"
以上任何一个的两步版本:
MYSELF="$(realpath "$0")"
MYDIR="${MYSELF%/*}"
如果到脚本的路径上有符号链接,which
则将提供一个答案,不包括该链接的解析。如果realpath
您的系统上没有默认安装,则可以在此处找到。
[编辑]:似乎与Caleb的建议realpath
相比没有优势,所以最好使用后者。我的计时测试表明它实际上更快。readlink -f
realpath
来自您的系统。(对于其他没有它的用户,可以使用readlink -f
realpath
可以追溯到GNU coreutils中(readlink -f
甚至还有readlink
IIRC)(周围有几种类似的工具,readlink -f
最终成为事实上的标准)。realpath
仅保留它是为了与仍在使用它的脚本兼容。
$(dirname "$(which "$0")")
在$(dirname $0)
哪里which
不再存在的优势是什么?是不是一样
readlink -f
在Mac OS X 10.11.6上似乎不起作用,但是realpath
开箱即用。
我的系统没有realpath
如通过rozcietrzewiacz建议。
您可以使用readlink
命令完成此操作。与解析which
或其他解决方案相比,使用此方法的优势在于,即使路径或执行的文件名的一部分是符号链接,您也可以找到实际文件所在的目录。
MYDIR="$(dirname "$(readlink -f "$0")")"
然后可以将您的文本文件读入如下变量:
TEXTFILE="$(<$MYDIR/textfile)"
which
建议。这个正常的解决方案涉及任一只是dirname
或其组合cd
和pwd
在子shell。Readlink在这里具有优势。无论如何,realpath
似乎几乎只是一个包装readlink -f
。
realpath
与的不同之处readlink -f
。我只能看到它给了我相同的结果(而不是which
)。
readlink -f
(来自GNU coreutils)不需要存在路径的最后一个元素readlink -e
,但确实存在,但并不受的支持busybox readlink
,后者模仿了-e
他们的-f
选择。
$0
脚本中的将是脚本的完整路径,dirname
并将采用完整路径并仅提供目录,因此您可以执行以下操作以保存文本文件:
$ cat "$(dirname -- "$0")/textfile"
realpath $0
您说“ $0
脚本中将是脚本的完整路径”是错误的。
$0
是运行时的命令,例如../script.sh
。
$(dirname "$0")
将相对路径返回到脚本,作为调用命令的一部分-而不是绝对路径。这可能导致脚本在运行时更改目录的问题。
您可以将其放在脚本的顶部:
cd "${BASH_SOURCE%/*}" || exit
BASH_SOURCE内部bash变量实际上是一个路径名数组。如果将其扩展为简单的字符串,例如“ $ BASH_SOURCE”,则会得到第一个元素,即当前正在执行的函数或脚本的路径名。