基本上我需要运行与shell脚本文件位置相关的路径脚本,我如何将当前目录更改为脚本文件所在的相同目录?


当前回答

在Bash中,你应该像这样得到你需要的东西:

#!/usr/bin/env bash

BASEDIR=$(dirname "$0")
echo "$BASEDIR"

其他回答

让我们把它变成一个POSIX在线程序:

a="/$0"; a="${a%/*}"; a="${a:-.}"; a="${a##/}/"; BINDIR=$(cd "$a"; pwd)

在包括BSD在内的许多兼容bourne的shell上进行了测试。

据我所知,我是作者,我把它放到了公共领域。更多信息见: https://www.bublina.eu.org/posts/2017-05-11-posix_shell_dirname_replacement/

灵感来自blueyed的回答

read < <(readlink -f $0 | xargs dirname)
cd $REPLY

如果你想获得实际的脚本目录(不管你是使用符号链接还是直接调用脚本),尝试:

BASEDIR=$(dirname $(realpath "$0"))
echo "$BASEDIR"

这在linux和macOS上都适用。我没看到有人提到realpath。不确定这种方法是否有任何缺点。

在macOS上,需要安装coreutils才能使用realpath。例如:brew install coreutils。

这个问题的最佳答案是: 从内部获取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'"

正如marko所言:

BASEDIR=$(dirname $0)
echo $BASEDIR

除非你在脚本所在的目录中执行脚本,在这种情况下,你会得到一个值'。'

要解决这个问题,请使用:

current_dir=$(pwd)
script_dir=$(dirname $0)

if [ $script_dir = '.' ]
then
script_dir="$current_dir"
fi

现在可以在整个脚本中使用变量current_dir来引用脚本目录。然而,这可能仍然有符号链接的问题。