如何识别脚本中是否正在使用bash或dash?

时间:2014-04-11 11:29:05

标签: bash dash-shell

我正在编写一个bash脚本,但在使用" sh"时会出错。 Ubuntu中的命令(看起来它与破折号不兼容,我正在学习这个主题)。所以我想检测是否正在使用dash而不是bash来抛出错误。

如何在脚本上下文中检测到它?它甚至可能吗?

4 个答案:

答案 0 :(得分:4)

您可以检查是否存在特定于shell的变量

例如,bash定义$BASH_VERSION。 由于该变量在dash中运行时无法定义,因此您可以使用它来区分:

[ -n "$BASH_VERSION" ] && isBash=1

事后补充:如果您想避免依赖变量(可以想象,可能设置不正确),您可以尝试获取终极名称shell可执行文件运行您的脚本,通过确定调用可执行文件,如果是符号链接,则将其跟踪到(最终)目标。

下面的 shell函数getTrueShellExeName() 就是这样做的;例如,对于使用'dash'运行的脚本(无论是明确地还是通过shebang sh),它会在Ubuntu上返回#!/bin/sh,因为sh符号链接到dash那里。

请注意,该功能的目标有两个:

  • 便携式
    • 使用所有POSIX兼容(Bourne-like)shell,
    • 至少大多数平台,关于使用哪些实用程序和选项 - 请参阅下面的警告。
  • 所有调用方案中工作
    • sourced(无论是否来自登录shell)
    • 通过shebang线独立执行
    • 通过作为文件名参数传递给shell可执行文件
    • 来执行
    • 通过将其内容通过stdin传递给shell可执行文件
    • 来执行

注意事项

  • 在至少一个平台上 - OSX - sh不是符号链接,即使它是有效的bash。在那里,该函数将在使用'sh'的脚本中返回sh
  • 该函数使用readlink,尽管大多数现代平台上都存在,但它不是POSIX强制要求的 - 尽管具有不同的语法和功能。因此,使用GNU readlink -f选项查找符号链接的终极目标是选项。<登记/> (我个人都知道的唯一现代平台具有readlink实用程序是HP-UX - 请参阅https://stackoverflow.com/a/24114056/45375以获取递归读取链接实现在所有 POSIX平台上工作。)
  • 该函数使用which实用程序(zsh除外,其中内置),虽然不是由POSIX强制执行的,但在< em>大多数现代平台。

该功能的使用示例:

[ "$(getTrueShellExeName)" = 'bash' ] && isBash=1 

Shell函数getTrueShellExeName()

getTrueShellExeName() {
  local trueExe nextTarget 2>/dev/null # ignore error in shells without `local`
  # Determine the shell executable filename.
  trueExe=$(ps -o comm= $$) || return 1
  # Strip a leading "-", as added e.g. by OSX for login shells.
  [ "${trueExe#-}" = "$trueExe" ] || trueExe=${trueExe#-}
  # Determine full executable path.
  [ "${trueExe#/}" != "$trueExe" ] || trueExe=$([ -n "$ZSH_VERSION" ] && which -p "$trueExe" || which "$trueExe")
  # If the executable is a symlink, resolve it to its *ultimate*
  # target. 
  while nextTarget=$(readlink "$trueExe"); do trueExe=$nextTarget; done
  # Output the executable name only.
  printf '%s\n' "$(basename "$trueExe")"
}

答案 1 :(得分:4)

使用$ 0(即被调用的shell的可执行文件的名称)。例如

的命令
echo $0

给出

/usr/bin/dash

表示短划线和

/bin/bash

表示bash。参数替换

${0##*/}

只给出'破折号'或'bash'。这可以用于测试。

答案 2 :(得分:1)

另一种方法可能是测试shell功能是否可用,例如给出一个想法......

[[ 1 ]] 2>/dev/null && echo could be bash || echo not bash, maybe dash

答案 3 :(得分:-1)

echo $0 and [[ 1 ]] 2>/dev/null && echo 

可能是bash ||回声不是bash,也许bash对运行Ubuntu 19的我有用。

在学校做过轻微的Pascal,Fortran和C,但需要精通Shell脚本。