加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

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

发布时间:2020-12-15 22:02:31 所属栏目:安全 来源:网络整理
导读:我正在写一个bash脚本,它在Ubuntu中使用“sh”命令时会抛出一个错误(它似乎与dash不兼容,我正在学习这个主题).所以我想检测是否正在使用dash而不是bash来抛出错误. 如何在脚本上下文中检测到它?它甚至可能吗? 解决方法 您可以检查是否存在特定于 shell的变
我正在写一个bash脚本,它在Ubuntu中使用“sh”命令时会抛出一个错误(它似乎与dash不兼容,我正在学习这个主题).所以我想检测是否正在使用dash而不是bash来抛出错误.

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

解决方法

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

例如,bash定义了$BASH_VERSION.
由于在dash中运行时不会定义该变量,因此可以使用它来区分:

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

事后想想:如果你想避免依赖变量(可以想象,可能设置不正确),你可以尝试通过确定调用可执行文件来获取运行脚本的shell可执行文件的最终名称,如果它是符号链接,遵循它的(最终)目标.

下面的shell函数getTrueShellExeName()就是这样做的;例如,它会在Ubuntu上返回’破折号’,用于运行带sh的脚本(无论是显式还是通过shebang#!/ bin / sh),因为sh符号链接到那里.

请注意,该函数的目标是双重的:

>便携式:

>使用所有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平台的递归读取链接实现.)
>该函数使用哪个实用程序(zsh除外,它是内置函数),虽然不是POSIX强制要求,但它存在于大多数现代平台上.

使用函数的示例:

[ "$(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 '%sn' "$(basename "$trueExe")"
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读