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

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

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

@echo Running from %~dp0

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

【问题讨论】:

  • 如果是重复的,请链接到原文。

标签: 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")
猜你喜欢
  • 2010-12-21
  • 2010-11-14
  • 1970-01-01
  • 1970-01-01
  • 2016-07-08
相关资源
最近更新 更多