【问题标题】:Bash script can't be run in ShellBash 脚本无法在 Shell 中运行
【发布时间】:2023-03-14 07:18:01
【问题描述】:

我一直在尝试为 Zabbix 实现一个警报脚本。 Zabbix 出于某种原因尝试在 Shell 中运行脚本,而脚本是用 Bash 编写的。

#!/bin/bash

# Slack incoming web-hook URL and user name
url='https://hooks.slack.com/services/this/is/my/webhook/'             # example: https://hooks.slack.com/services/QW3R7Y/D34DC0D3/BCADFGabcDEF123
username='Zabbix Notification System'

## Values received by this script:
# To = $1 (Slack channel or user to send the message to, specified in the Zabbix web interface; "@username" or "#channel")
# Subject = $2 (usually either PROBLEM or RECOVERY/OK)
# Message = $3 (whatever message the Zabbix action sends, preferably something like "Zabbix server is unreachable for 5 minutes - Zabbix server (127.0.0.1)")

# Get the Slack channel or user ($1) and Zabbix subject ($2 - hopefully either PROBLEM or RECOVERY/OK)
to="$1"
subject="$2"

# Change message emoji depending on the subject - smile (RECOVERY/OK), frowning (PROBLEM), or ghost (for everything else)
recoversub='^RECOVER(Y|ED)?$'
if [[ "$subject" =~ ${recoversub} ]]; then
        emoji=':smile:'
elif [ "$subject" == 'OK' ]; then
        emoji=':smile:'
elif [ "$subject" == 'PROBLEM' ]; then
        emoji=':frowning:'
else
        emoji=':ghost:'
fi

# The message that we want to send to Slack is the "subject" value ($2 / $subject - that we got earlier)
#  followed by the message that Zabbix actually sent us ($3)
message="${subject}: $3"

# Build our JSON payload and send it as a POST request to the Slack incoming web-hook URL
payload="payload={\"channel\": \"${to//\"/\\\"}\", \"username\": \"${username//\"/\\\"}\", \"text\": \"${message//\"/\\\"}\", \"icon_emoji\": \"${emoji}\"}"
curl -m 5 --data-urlencode "${payload}" $url -A "https://hooks.slack.com/services/this/is/my/web/hook"
~

当我使用“bash slack.sh”在本地运行脚本时,它会发送一个空通知,我会在 Slack 中收到该通知。 当我使用“sh slack.sh”在本地运行脚本时,出现以下错误。

slack.sh: 19: slack.sh: [[: not found
slack.sh: 21: [: unexpected operator
slack.sh: 23: [: unexpected operator
slack.sh: 34: slack.sh: Bad substitution

感谢您的帮助。

【问题讨论】:

  • 如果Zabbix 需要一个POSIX shell 脚本,那么你必须编写一个POSIX shell 脚本,而[[ 不是由POSIX 定义的。您是否可以将Zabbix 配置为使用不同的shell 是另一个问题。 (如果Zabbix 只需要一个可执行文件,那么@bishop 就有答案。)
  • (@bishop 删除了他的评论,其中建议使用#!/bin/bash 而不是# !/bin/bash。)
  • 根据Zabbix网站; “Zabbix 中的正则表达式支持已从 POSIX 扩展正则表达式切换到 Perl 兼容正则表达式 (PCRE),以增强正则表达式和与前端的一致性。”我已经考虑(并尝试过)删除'[['并将其替换为单个'[',但这无济于事。
  • 我不认为 Zabbix 中的正则表达式支持是相关的;这是一个 shell 脚本,或者您使用的是 bash,在这种情况下,=~ 需要一个 POSIX 正则表达式,或者该脚本由 /bin/sh(一个 POSIX 兼容的 shell)执行并且不支持正则表达式完全匹配
  • 但请注意,在 shell 中进行正则表达式匹配非常简单:if echo "$string_to_match" | grep "$pattern" > /dev/null; then ... 效果很好。

标签: bash shell zabbix


【解决方案1】:

你的 shebang 错了。

# !/bin/bash

删除第一个空格。

【讨论】:

  • 感谢您的关注。但这不是解决方案。
  • 原来的shebang语法确实需要空格。
  • @GiacomoCatenazzi 我不认为这是正确的。原始允许!之后有一个空格,但#!始终必须是文件的前两个字节。
  • @chepner:你说得对,我的眼睛看到了!之后的空格。
【解决方案2】:

您可以通过添加强制脚本使用 bash 运行

#! /bin/bash

if [ -z "$BASH" ]
then
    exec /bin/bash "$0" "$@"
fi
...

【讨论】:

    【解决方案3】:

    如果不能说服 Zabbix 使用bash 执行脚本,你将不得不放弃正则表达式匹配(expr 命令,奇怪的是,不支持任何形式的交替,这意味着它的正则表达式只能识别常规语言的子集):

    # if RECOVER(Y|ED)$ were a valid POSIX basic regular expression,
    # you could use
    #
    #   if expr "$subject" : "$recoverysub"; then
    #
    # but it is not, so you need...
    if [ "$subject" = RECOVERY ] || [ "$subject" = RECOVERED ]; then
    

    【讨论】:

    • case "${subject}" in .. esac
    • 当然可以,但在这种情况下,我认为这对if 语句没有很大的改进。 RECOVER(Y|ED) 也不是有效的模式,所以你仍然必须使用 RECOVERY|RECOVERED
    • 您还有OKPROBLEMdefault的案例。
    【解决方案4】:

    您在调用脚本时似乎使用 而不是

    使用

    bash script.sh
    

    chmod +x script.sh
    /full/path/to/script.sh
    

    注意:

    所以现在,您知道问题所在了。一种解决方案是将脚本更改为 POSIX shell 或搜索如何强制 zabbix 处理 bash 脚本

    【讨论】:

    • 我使用 'sh' 因为那是 Zabbix 试图使用的。当我使用“bash script.sh”时,它可以工作。但是我也找不到 Zabbix 使用 bash 的方法。
    • 该链接似乎是一个伪 sh 库,旨在 bash 脚本使用,而不是由 Zabbix 执行的 bash 脚本使用。 (我说“伪”是因为它似乎是写在 bash 的一个子集中,bash 在调用为 sh 时仍然可以识别。一个例子是使用 function 关键字来定义一个函数。)
    猜你喜欢
    • 2012-11-22
    • 1970-01-01
    • 1970-01-01
    • 2017-09-24
    • 2015-12-10
    • 2020-01-01
    • 2017-09-09
    • 2019-02-17
    • 1970-01-01
    相关资源
    最近更新 更多