我如何找到一个Bash脚本位于该脚本内部的目录的路径?

我想用Bash脚本作为另一个应用程序的启动器,我想将工作目录更改为Bash脚本所在的目录,所以我可以在该目录中的文件上运行,如下:

$ ./application

当前回答

查看下面的测试与奇怪的目录名称。

要将工作目录更改为Bash脚本的位置,您应该尝试这个简单的,测试和验证的Shellcheck解决方案:

#!/bin/bash --
cd "$(dirname "${0}")"/. || exit 2

测试:

$ ls 
application
$ mkdir "$(printf "\1\2\3\4\5\6\7\10\11\12\13\14\15\16\17\20\21\22\23\24\25\26\27\30\31\32\33\34\35\36\37\40\41\42\43\44\45\46\47testdir" "")"
$ mv application *testdir
$ ln -s *testdir "$(printf "\1\2\3\4\5\6\7\10\11\12\13\14\15\16\17\20\21\22\23\24\25\26\27\30\31\32\33\34\35\36\37\40\41\42\43\44\45\46\47symlink" "")"
$ ls -lb
total 4
lrwxrwxrwx 1 jay stacko   46 Mar 30 20:44 \001\002\003\004\005\006\a\b\t\n\v\f\r\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\ !"#$%&'symlink -> \001\002\003\004\005\006\a\b\t\n\v\f\r\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\ !"#$%&'testdir
drwxr-xr-x 2 jay stacko 4096 Mar 30 20:44 \001\002\003\004\005\006\a\b\t\n\v\f\r\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\ !"#$%&'testdir
$ *testdir/application && printf "SUCCESS\n" ""
SUCCESS
$ *symlink/application && printf "SUCCESS\n" ""
SUCCESS

其他回答

pwd 可以用来找到当前工作目录,而 dirname 可以用来找到特定文件的目录(运行命令为 $0,所以 dirname $0 应该给你当前脚本的目录)。

然而,字体名称给出了字体名称的目录部分,这更有可能与当前工作目录无关,如果你的脚本需要因某种原因更改目录,那么字体名称的输出就会变得毫无意义。

我建议如下:

#!/usr/bin/env bash

reldir="$( dirname -- "$0"; )";
cd "$reldir";
directory="$( pwd; )";

echo "Directory is ${directory}";

这样,你就得到一个绝对的,而不是一个相对的目录。

由于脚本将在一个单独的Bash例子中运行,没有必要恢复工作目录后,但如果你想因某种原因改变你的脚本,你可以轻松地将PWD的值分配给一个变量,在你更改目录之前,用于未来的使用。

雖然只是

cd "$( dirname -- "$0"; )";

解决这个问题的具体场景,我发现有绝对的道路到更有用的一般。

这是令人不安的,我发现的唯一一个线路,它在Linux和macOS工作,当执行的脚本是一个同步链接:

SCRIPT_DIR=$(python -c "import os; print(os.path.dirname(os.path.realpath('${BASH_SOURCE[0]}')))")

或,类似,使用Python3 pathlib模块:

SCRIPT_DIR=$(python3 -c "from pathlib import Path; print(Path('${BASH_SOURCE[0]}').resolve().parent)")

在Linux和macOS上进行测试,并与其他解决方案进行比较: https://gist.github.com/ptc-mrucci/61772387878ed53a6c717d51a21d9371

这应该是这样做的:

DIR="$(dirname "$(realpath "$0")")"

这与路线上的交线和空间一起工作。

请参见男人的页面为 dirname 和 realpath。

请添加关于如何支持MacOS的评论,对不起,我可以验证。

我会用这样的东西:

# 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

此分類上一篇: Mac OS X v10.6.6 (Snow Leopard):

DIR=$(cd "$(dirname "$0")"; pwd)