基本上我需要使用与shell脚本文件位置相关的路径来运行脚本,如何将当前目录更改为与脚本文件所在目录相同?
您可以使用以下命令将当前工作目录更改为与脚本文件所在目录相同:``` cd "$(dirname "$0")" ```
其中 `$0` 是脚本文件的名称,`$(dirname "$0")` 获取该文件所在的目录,并使用 `cd` 命令将当前工作目录切换到那个目录。
基本上我需要使用与shell脚本文件位置相关的路径来运行脚本,如何将当前目录更改为与脚本文件所在目录相同?
您可以使用以下命令将当前工作目录更改为与脚本文件所在目录相同:#!/usr/bin/env bash
BASEDIR=$(dirname "$0")
echo "$BASEDIR"
readlink
命令(请参见下面al的答案)。 - AndrewR$BASH_SOURCE
代替$0
更安全,因为$0
并不总是包含正在调用的脚本的路径,比如在"source"脚本时。 - mklement0$BASH_SOURCE
是 Bash 特有的,这个问题是关于一般的 shell 脚本。 - Ha-Duong NguyenCUR_PATH=$(pwd)
或 pwd
命令返回当前目录(并不一定是脚本的父目录)! - Andreas Covidiot$BASH_SOURCE
,它返回了我需要的结果。我的脚本被另一个脚本调用,而$0
返回.
,而$BASH_SOURCE
返回了正确的子目录(在我的情况下是scripts
)。 - David Rissato Cruzreadlink
选项 -f
完成。当脚本被绝对路径和相对路径调用时都可以使用。#!/bin/bash
# Absolute path to this script, e.g. /home/user/bin/foo.sh
SCRIPT=$(readlink -f "$0")
# Absolute path this script is in, thus /home/user/bin
SCRIPTPATH=$(dirname "$SCRIPT")
echo $SCRIPTPATH
对于tcsh、csh:
#!/bin/tcsh
# Absolute path to this script, e.g. /home/user/bin/foo.csh
set SCRIPT=`readlink -f "$0"`
# Absolute path this script is in, thus /home/user/bin
set SCRIPTPATH=`dirname "$SCRIPT"`
echo $SCRIPTPATH
readlink
命令。这就是我建议使用bash内置的pushd/popd命令的原因。 - docwhatreadlink
的 -f
选项在 OS X(Lion)和可能的 BSD 上有不同的功能。
https://dev59.com/UnNA5IYBdhLWcg3wL62x - Ergwun-f
;你可以删除-f
,以解决至多一个间接级别的解析,例如pushd "$(dirname "$(readlink "$BASH_SOURCE" || echo "$BASH_SOURCE")")"
,或者按照链接帖子中演示的方式编写自己的递归符号链接跟随脚本。 - mklement0sh /some/other/directory/script.sh
),那么这可能会成为一个问题。在这种情况下,.
将是您的当前工作目录,而不是 /some/other/directory
。请注意调整当前工作目录以匹配脚本位置。 - Jon z之前在一个回答中已经提到了这个问题,但是在所有其他回答中很容易被忽略。
在使用bash时:
echo this file: "$BASH_SOURCE"
echo this dir: "$(dirname "$BASH_SOURCE")"
dirname "$BASH_SOURCE"
来处理$BASH_SOURCE中的空格。 - Mygod假设您正在使用bash
#!/bin/bash
current_dir=$(pwd)
script_dir=$(dirname "$0")
echo $current_dir
echo $script_dir
这个脚本应该打印你所在的目录,然后是脚本所在的目录。例如,在/
中调用脚本并将其放在/home/mez/
中时,它输出:
/
/home/mez
记住,当从命令输出中分配变量时,请用 $(
和)
括起该命令 - 否则您将无法获得所需的输出。
这个问题的最佳答案已经在这里回答了:
从Bash脚本内获取源目录
答案是:
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
无论脚本从哪里调用,都可以使用一行命令获取完整的脚本目录。
为了理解其工作原理,您可以执行以下脚本:
#!/bin/bash
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
TARGET="$(readlink "$SOURCE")"
if [[ $TARGET == /* ]]; then
echo "SOURCE '$SOURCE' is an absolute symlink to '$TARGET'"
SOURCE="$TARGET"
else
DIR="$( dirname "$SOURCE" )"
echo "SOURCE '$SOURCE' is a relative symlink to '$TARGET' (relative to '$DIR')"
SOURCE="$DIR/$TARGET" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
fi
done
echo "SOURCE is '$SOURCE'"
RDIR="$( dirname "$SOURCE" )"
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
if [ "$DIR" != "$RDIR" ]; then
echo "DIR '$RDIR' resolves to '$DIR'"
fi
echo "DIR is '$DIR'"
#!/bin/bash
pushd $(dirname "${0}") > /dev/null
basedir=$(pwd -L)
# Use "pwd -P" for the path without links. man bash for more info.
popd > /dev/null
echo "${basedir}"
pwd -L
пјҢдҪ еҸҜд»Ҙз”Ёcd $(dirname "${0}")
е’Ң cd -
д»Јжӣҝpushd
/popd
е‘Ҫд»ӨпјҢд»ҘдҪҝе‘Ҫд»ӨеңЁе…¶д»–shellдёҠд№ҹиғҪжӯЈеёёдҪҝз”ЁгҖӮиҜ·жіЁж„ҸдёҚиҰҒж”№еҸҳеҺҹж„ҸгҖӮ - docwhat如果您想获取实际的脚本目录(无论您是使用符号链接还是直接调用脚本),请尝试:
BASEDIR=$(dirname $(realpath "$0"))
echo "$BASEDIR"
这适用于linux和macOS。我没有看到任何人提到realpath
。不确定这种方法是否有任何缺点。
在macOS上,您需要安装coreutils
才能使用realpath
。例如:brew install coreutils
。
ash
和dash
,例如在Alpine Linux上)上运行良好。 - jchook正如Marko所建议的:
BASEDIR=$(dirname $0)
echo $BASEDIR
除非您从脚本所在的相同目录执行脚本,否则此方法有效;在这种情况下,您将得到一个'.'的值。
为了解决这个问题,请使用:
current_dir=$(pwd)
script_dir=$(dirname $0)
if [ $script_dir = '.' ]
then
script_dir="$current_dir"
fi
现在你可以在整个脚本中使用变量 current_dir 来引用脚本目录。但是这可能仍然存在符号链接问题。
让我们把它变成一个 POSIX 单行命令:
a="/$0"; a="${a%/*}"; a="${a:-.}"; a="${a##/}/"; BINDIR=$(cd "$a"; pwd)
在许多Bourne兼容的shell上进行了测试,包括BSD shell。
据我所知,我是作者,并将其置于公共领域。更多信息请参见:https://www.bublina.eu.org/posts/2017-05-11-posix_shell_dirname_replacement/
#!/bin/sh
兼容的解决方案!我的好男人。 - s3cBINDIR=$(cd "$a"; pwd)
而不是 BINDIR="$(cd $a; pwd)"
,因为当 $a
中有空格时,cd $a
会失败,而 $(...)
本身就被视为带引号的,因此在其周围添加额外的引号 - 即:"$(...)"
是多余的。 - michaelcd $(dirname $(readlink -f $0))