我如何找到一个Bash脚本位于该脚本内部的目录的路径?
我想用Bash脚本作为另一个应用程序的启动器,我想将工作目录更改为Bash脚本所在的目录,所以我可以在该目录中的文件上运行,如下:
$ ./application
我如何找到一个Bash脚本位于该脚本内部的目录的路径?
我想用Bash脚本作为另一个应用程序的启动器,我想将工作目录更改为Bash脚本所在的目录,所以我可以在该目录中的文件上运行,如下:
$ ./application
当前回答
下面是易于记住的脚本:
DIR="$( dirname -- "${BASH_SOURCE[0]}"; )"; # Get the directory name
DIR="$( realpath -e -- "$DIR"; )"; # Resolve its full path if need be
其他回答
我会用这样的东西:
# Retrieve the full pathname of the called script
scriptPath=$(which $0)
# Check whether the path is a link or not
if [ -L $scriptPath ]; then
# It is a link then retrieve the target path and get the directory name
sourceDir=$(dirname $(readlink -f $scriptPath))
else
# Otherwise just get the directory name of the script path
sourceDir=$(dirname $scriptPath)
fi
命名命令是最基本的,简单地将路径到0美元(脚本名称)变量的名称:
dirname -- "$0";
但是,正如Matt b指出的那样,返回的路径取决于脚本的名称。 pwd 不做工作,因为它只告诉你当前的目录是什么,而不是脚本的目录是什么。
有些人提到了阅读链接命令,但最简单的是,你可以使用:
dirname -- "$( readlink -f -- "$0"; )";
阅读链接将解决脚本路径从文件系统的根源到绝对路径,因此,任何包含单点或双点的路径,图标和/或象征性链接将解决到完整路径。
#!/usr/bin/env bash
echo "pwd: `pwd`"
echo "\$0: $0"
echo "basename: `basename -- "$0"`"
echo "dirname: `dirname -- "$0"`"
echo "dirname/readlink: $( dirname -- "$( readlink -f -- "$0"; )"; )"
在我的家中运行这个脚本,使用相对的路径:
>>>$ ./whatdir.sh
pwd: /Users/phatblat
$0: ./whatdir.sh
basename: whatdir.sh
dirname: .
dirname/readlink: /Users/phatblat
再一次,但使用完整的路径到脚本:
>>>$ /Users/phatblat/whatdir.sh
pwd: /Users/phatblat
$0: /Users/phatblat/whatdir.sh
basename: whatdir.sh
dirname: /Users/phatblat
dirname/readlink: /Users/phatblat
现在更改目录:
>>>$ cd /tmp
>>>$ ~/whatdir.sh
pwd: /tmp
$0: /Users/phatblat/whatdir.sh
basename: whatdir.sh
dirname: /Users/phatblat
dirname/readlink: /Users/phatblat
最后,使用一个象征性的链接来执行脚本:
>>>$ ln -s ~/whatdir.sh whatdirlink.sh
>>>$ ./whatdirlink.sh
pwd: /tmp
$0: ./whatdirlink.sh
basename: whatdirlink.sh
dirname: .
dirname/readlink: /Users/phatblat
然而,有一個案例,這不起作用,當脚本來源(而不是執行)在 bash:
>>>$ cd /tmp
>>>$ . ~/whatdir.sh
pwd: /tmp
$0: bash
basename: bash
dirname: .
dirname/readlink: /tmp
我想评论上面的答案(我如何从脚本本身中获取Bash脚本的源目录?),但没有足够的声誉来做到这一点。
我在两年前在苹果的文档网站上找到了一个解决方案: https://developer.apple.com/library/archive/documentation/OpenSource/Conceptual/ShellScripting/AdvancedTechniques/AdvancedTechniques.html。
#!/bin/sh
# Get an absolute path for the poem.txt file.
POEM="$PWD/../poem.txt"
# Get an absolute path for the script file.
SCRIPT="$(which $0)"
if [ "x$(echo $SCRIPT | grep '^\/')" = "x" ] ; then
SCRIPT="$PWD/$SCRIPT"
fi
正如代码所表明的那样,一旦您获得脚本的绝对路径,则您可以使用命令命名以获得目录的路径。
我不认为这是像其他人这样容易的。 pwd 不工作,因为当前的目录不一定是与脚本的目录。 $0 不总是有信息。
./script
/usr/bin/script
script
在第一和第三方式 $0 没有完整的路径信息. 在第二和第三, pwd 不工作. 唯一的方式来获得目录的第三方式将是通过路径运行并找到文件与正确的匹配。
做你正在要求的一种方式,就是在 /usr/share 目录中的数据硬编码,并将其引用到其完整的路径。
这应该是这样做的:
DIR="$(dirname "$(realpath "$0")")"
这与路线上的交线和空间一起工作。
请参见男人的页面为 dirname 和 realpath。
请添加关于如何支持MacOS的评论,对不起,我可以验证。