确定执行 BASH 脚本的路径 [重复]

Posted

技术标签:

【中文标题】确定执行 BASH 脚本的路径 [重复]【英文标题】:Determine the path of the executing BASH script [duplicate] 【发布时间】:2010-10-12 10:28:25 【问题描述】:

可能重复:Can a Bash script tell what directory it's stored in?

在Windows 命令脚本中,可以使用%~dp0 确定当前执行脚本的目录 路径。例如:

@echo Running from %~dp0

BASH 脚本中的等价物是什么?

【问题讨论】:

如果是重复的,请链接到原文。 【参考方案1】:

对于相对路径(即直接相当于 Windows 的%~dp0):

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

对于绝对的规范化路径:

MY_PATH=$(dirname "$0")            # relative
MY_PATH=$(cd "$MY_PATH" && pwd)    # absolutized and normalized
if [[ -z "$MY_PATH" ]] ; then
  # error; for some reason, the path is not accessible
  # to the script (e.g. permissions re-evaled after suid)
  exit 1  # fail
fi
echo "$MY_PATH"

【讨论】:

你的 mac bash 有什么问题?在 Cygwin、Linux、Solaris 等上运行得很好,它也必须在 mac 上运行 在 bash 中你也可以使用$BASH_SOURCE。来自this post。 $0 在大多数情况下都可以,例如,当您正在执行的脚本有别名时(通过 .bash_profile 中的别名),一些例外情况。你真的应该使用 $BASH_SOURCE 变量,而不是 $0。 当我通过符号链接执行脚本时对我不起作用。是否有一个变体可以确定完全解析的脚本目录?编辑:$(dirname $(readlink $0)) 似乎有效 在使用source script. script 运行脚本时,使用$0 不起作用;脚本名称不可用。【参考方案2】:

假设您输入 bash 脚本的完整路径,请使用 $0dirname,例如:

#!/bin/bash
echo "$0"
dirname "$0"

示例输出:

$ /a/b/c/myScript.bash
/a/b/c/myScript.bash
/a/b/c

如有必要,将$PWD 变量的结果附加到相对路径。

编辑:添加引号来处理空格字符。

【讨论】:

@Rothko,如果 $0 包含空格,您的解决方案将失败。 在 bash 中你也可以使用$BASH_SOURCE。来自this post。【参考方案3】:

Stephane CHAZELAS 供稿于 c.u.s. 假设 POSIX shell:

prg=$0
if [ ! -e "$prg" ]; then
  case $prg in
    (*/*) exit 1;;
    (*) prg=$(command -v -- "$prg") || exit;;
  esac
fi
dir=$(
  cd -P -- "$(dirname -- "$prg")" && pwd -P
) || exit
prg=$dir/$(basename -- "$prg") || exit 

printf '%s\n' "$prg"

【讨论】:

在 Mac OSX 上对我来说非常棒,而这个问题中的其他方法却没有。 +1 用于通过$PATH 搜索处理脚本调用;但是,上面的 不是 POSIX。它只适用于bash。使用 which 而不是 command 和反引号而不是 $(...) 这必须在其他较旧的 shell 下运行。 嗨@vladr,上面的代码是POSIX!如果我理解正确,您的意思是代码不会在旧的 Bourne shell 上运行(例如 /bin/sh 在 Solaris @DimitreRadoulov 抱歉,是的,我的意思是最低公分母 POSIX,用于大多数可移植性,即 POSIX.1。从技术上讲是的,任何 POSIX.2 shell 以及旧的 ksh 等,不仅是 bash,都可以运行上述程序,但仍有相当多的人使用 Solaris 10(支持结束时间为 2018 年,还有很多年),有些甚至运行旧的 AIX 和 HP-UX。 @vladr,Bourne shell 不符合 POSIX,它早于 POSIX 标准。 POSIX.1 的标准化用户命令行和脚本界面基于 Korn Shell。据我所知,所有商业 Unices 都提供符合 POSIX 标准的外壳(例如,在 Solaris 上是 /usr/xpg4/bin/sh)。【参考方案4】:

Vlad 的代码被过度引用。应该是:

MY_PATH=`dirname "$0"`
MY_PATH=`( cd "$MY_PATH" && pwd )`

【讨论】:

第二行多了一个双引号。 旧 Solaris 版本需要过度引用,在原始发布时仍在使用。【参考方案5】:
echo Running from `dirname $0`

【讨论】:

$0 应该被转义 (dirname "$0")

以上是关于确定执行 BASH 脚本的路径 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

从用户获取输入到包含空格的路径(bash脚本)[重复]

读取bash脚本中的输入,该脚本是路径中带有空格的目录[重复]

bash: 避免命令重复执行的简单脚本

bash -- 杀死命令脚本 [重复]

bash - 错误或超时关闭脚本[重复]

While循环重置Bash脚本中的数字变量[重复]