bash - 使用命令行参数(主机名)运行外部命令

发布于 2025-01-11 15:11:54 字数 660 浏览 0 评论 0原文

第一次发帖,如有遗漏还请大家谅解。

我有一个应该与 icinga 一起使用的脚本。我需要 icinga 登录我的 Linux 机器并运行“script”之类的命令。然后,该脚本将向该主机名运行命令,例如 sudo /etc/init.d/apache2 status,然后报告“正在运行或未使用”以及退出状态 0 或 2。 我想知道如何添加另一个命令并根据给定的主机名运行其中一个命令。其中一半需要 apache2 才能运行,另一半需要有一个名为 dss 的进程才能运行。我不想有两个单独的脚本。这是工作脚本,抱歉它很草率,但我还没有做任何清理工作,而且我还不太擅长 bash。

因此用户将运行脚本 ./chkdss2 或

#!/bin/bash
ec=0
ec1=2
var3=run
var4=unused

for host in "$@"
do
  var1=`ssh $host sudo /etc/init.d/dss status|awk '{print $6}'`
  var2="$( echo $var1 | cut -c 3-5 )"
if [[ "$var2" == "$var3" ]]; then
    echo "$host is running"
    echo $ec
  else
    echo "$host is not running"
    echo $ec1
fi
done

First time post, please forgive any missing information.

I have a script that is supposed to work with icinga. I need icinga to log into my Linux box and run a command like "script ". The script will then run a command to that hostname like sudo /etc/init.d/apache2 status then report back "running or unused" and an exit status of 0 or 2.
I'm wondering how I could add another command and have it one or the other run depending on what hostname it's given. Half of them need apache2 to be running and the other half need to have a process called dss to be running. I'd rather not have two separate scripts. Here is the working script and sorry it's sloppy but I haven't done any clean up and I'm not real good at bash yet.

so the user would run the script ./chkdss2 or

#!/bin/bash
ec=0
ec1=2
var3=run
var4=unused

for host in "$@"
do
  var1=`ssh $host sudo /etc/init.d/dss status|awk '{print $6}'`
  var2="$( echo $var1 | cut -c 3-5 )"
if [[ "$var2" == "$var3" ]]; then
    echo "$host is running"
    echo $ec
  else
    echo "$host is not running"
    echo $ec1
fi
done

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

黑凤梨 2025-01-18 15:11:54

有几种方法可以测试特定主机名是用于 apache 还是 dss。您只需拥有每种情况的主机名列表,并检查收到的主机名是否包含在所述列表中。

方法 1:使用数组

#!/bin/bash

# Method 1, using array lists of hosts
apachehosts=('ap1' 'ap2' 'ap3')
dsshosts=('dss1' 'dss2' 'dss3')

for host in "$@"
do
    if printf '%s\n' "${apachehosts[@]}" | grep -Fxq "$host"
    then
        echo "$host: APACHE HOST"
    elif printf '%s\n' "${dsshosts[@]}" | grep -Fxq "$host"
    then
        echo "$host: DSS HOST"
    else
        echo "ERROR, $host: unknown host"
    fi
done

要修改主机列表,只需在数组 apachehostsdsshosts 声明中添加或删除值即可。


方法 2:使用 case

#!/bin/bash

# Method 2, using case
for host in "$@"
do
    case "$host" in
        'ap1'|'ap2'|'ap3')
            echo "CASE, $host: APACHE HOST"
            ;;
        'dss1'|'dss2'|'dss3')
            echo "CASE, $host: DSS HOST"
            ;;
        *)
            echo "ERROR CASE, $host: unknown host"
            ;;
    esac
done

在这里,您可以编辑每种情况下的模式。


方法 3:使用 if

#!/bin/bash

# Method 3, using if
for host in "$@"
do
    if [[ "$host" == 'ap1' || "$host" == 'ap2' || "$host" == 'ap3' ]]
    then
        echo "IF, $host: APACHE HOST"
    elif [[ "$host" == 'dss1' || "$host" == 'dss2' || "$host" == 'dss3' ]]
    then
        echo "IF, $host: DSS HOST"
    else
        echo "IF, $host: unknown host"
    fi
done

您可以在此处修改 if 条件。我更喜欢其他方法,因为这种方法编辑起来比较复杂,而且不太清楚,特别是当您的主机列表很长时。


方法 4:主机名条件

如果幸运的话,您的主机名有一些模式。前任。所有 apache 服务器都以字母 ap 开头,所有 dss 服务器的名称中都包含 dss,...

然后您可以简单地使用 2 个 if 语句来决定哪个是哪个。

#!/bin/bash

# Method 4, patterns
for host in "$@"
do
    if [[ $(echo "$host" | grep -c -e "^ap") -ne 0 ]]
    then
        echo "PATTERNS, $host: APACHE HOST"
    elif [[ $(echo "$host" | grep -c -e "dss") -ne 0 ]]
    then
        echo "PATTERNS, $host: DSS host"
    else
        echo "PATTERNS, $host: unknown host"
    fi
done

注意:主机名 apdss1 在这里将作为 Apache 服务器出现。以前的方法会响应“未知主机”。您的模式必须足够严格以避免不匹配。

There are a couple ways to test if a particular hostname is for apache or dss. You only need to have a list of hostnames for each case, and check if the received hostnames are included in said lists.

Method 1: using arrays

#!/bin/bash

# Method 1, using array lists of hosts
apachehosts=('ap1' 'ap2' 'ap3')
dsshosts=('dss1' 'dss2' 'dss3')

for host in "$@"
do
    if printf '%s\n' "${apachehosts[@]}" | grep -Fxq "$host"
    then
        echo "$host: APACHE HOST"
    elif printf '%s\n' "${dsshosts[@]}" | grep -Fxq "$host"
    then
        echo "$host: DSS HOST"
    else
        echo "ERROR, $host: unknown host"
    fi
done

To modify the lists of hosts, simply add or remove values in the declaration of arrays apachehosts and dsshosts.


Method 2: using case

#!/bin/bash

# Method 2, using case
for host in "$@"
do
    case "$host" in
        'ap1'|'ap2'|'ap3')
            echo "CASE, $host: APACHE HOST"
            ;;
        'dss1'|'dss2'|'dss3')
            echo "CASE, $host: DSS HOST"
            ;;
        *)
            echo "ERROR CASE, $host: unknown host"
            ;;
    esac
done

Here, you edit the patterns in each case.


Method 3: using if

#!/bin/bash

# Method 3, using if
for host in "$@"
do
    if [[ "$host" == 'ap1' || "$host" == 'ap2' || "$host" == 'ap3' ]]
    then
        echo "IF, $host: APACHE HOST"
    elif [[ "$host" == 'dss1' || "$host" == 'dss2' || "$host" == 'dss3' ]]
    then
        echo "IF, $host: DSS HOST"
    else
        echo "IF, $host: unknown host"
    fi
done

Here you modify the if conditions. I prefer the other methods, since this one is more complicated to edit, it is not as clear, especially if your list of hosts is long.


Method 4: condition on the hostnames

If you are lucky, there is some pattern to your hostnames. Ex. all apache servers start with letters ap, all your dss servers include dss in the name, ...

You can then simply use 2 if statements to decide which is which.

#!/bin/bash

# Method 4, patterns
for host in "$@"
do
    if [[ $(echo "$host" | grep -c -e "^ap") -ne 0 ]]
    then
        echo "PATTERNS, $host: APACHE HOST"
    elif [[ $(echo "$host" | grep -c -e "dss") -ne 0 ]]
    then
        echo "PATTERNS, $host: DSS host"
    else
        echo "PATTERNS, $host: unknown host"
    fi
done

Note: hostname apdss1 would come out as an Apache server here. Previous methods would respond "unknown host". You patterns must be strict enough to avoid mismatches.

倚栏听风 2025-01-18 15:11:54

我有一个类似的任务,使用单个 ssh 请求获取一些报告项目。

我必须在 single ssh 命令中检索:

  1. 其 Docker 主机的完整主机名 (FQDN)
  2. Linux 版本
  3. IP 地址(如果存在),或者“无”

我让我的脚本在第 3 阶段工作。

1. 从远程主机获取多行信息

ssh -q dudi-HP-Compaq-Elite-8300-MT  <<< '
date +%F:%T   # line 1: time stamp
hostname -f     # line 2: hostname 
awk  "/DESCR/{print \$3}" /etc/lsb-release # line 3 : host linux distribution version
ip a | awk "/inet / && !/127.0.0.1/{sub(\"/.*\",\"\",\$2);printf(\"%s \", \$2)}"      # line 4: list IP address to the host
'

结果:

2022-03-05:22:22:21
dudi-HP-Compaq-Elite-8300-MT
20
192.168.2.111 192.168.122.1 172.17.0.1

2. 处理来自远程主机的多行信息

将远程主机的多行信息读取到数组 sshResultsArr 中。

readarray -t sshResultsArr < <(ssh -q dudi-HP-Compaq-Elite-8300-MT  <<< '
date +%F:%T   # line 1: time stamp
hostname -f     # line 2: hostname 
awk  "/DESCR/{print \$3}" /etc/lsb-release # line 3 : host linux distribution version
ip a | awk "/inet / && !/127.0.0.1/{sub(\"/.*\",\"\",\$2);printf(\"%s \", \$2)}"      # line 4: list IP address to the host
')
hostname=${sshResultsArr[1]}
osVersion=${sshResultsArr[2]}
hasDockerIp=$(grep -Eo "172(.[[:digit:]]{1,3}){3}" <<< "${sshResultsArr[3]}") # find IP starting with 172
hasDockerIp=${hasDockerIp:="none"} # if not found IP set to "NONE"

printf "%s \t OS version: %s \t has Docker IP: %s\n" "$hostname" "$osVersion" "$hasDockerIp"

结果:

dudi-HP-Compaq-Elite-8300-MT     OS version: 20          has Docker IP: 172.17.0.1

3.循环处理每个远程主机

#!/bin/bash
for host in "$@"; do
  readarray -t sshResultsArr < <(ssh -q $host  <<< '
  date +%F:%T   # line 1: time stamp
  hostname -f     # line 2: hostname 
  awk  "/DESCR/{print \$3}" /etc/lsb-release # line 3 : host linux distribution version
  ip a | awk "/inet / && !/127.0.0.1/{sub(\"/.*\",\"\",\$2);printf(\"%s \", \$2)}"      # line 4: list IP address to the host
  ')
  hostname=${sshResultsArr[1]}
  osVersion=${sshResultsArr[2]}
  hasDockerIp=$(grep -Eo "172(.[[:digit:]]{1,3}){3}" <<< "${sshResultsArr[3]}") # find IP starting with 172
  hasDockerIp=${hasDockerIp:="none"} # if not found IP set to "NONE"

  printf "%s \t OS version: %s \t has Docker IP: %s\n" "$hostname" "$osVersion" "$hasDockerIp"
done

I had a similar task to get few report items using single ssh request.

I had to retrieve in singel ssh command:

  1. Full hostname (FQDN)
  2. Linux version
  3. IP address of its Docker host if exist, or "none"

I got my script to work in 3 stage.

1. Get multiple lines of information from remote host

ssh -q dudi-HP-Compaq-Elite-8300-MT  <<< '
date +%F:%T   # line 1: time stamp
hostname -f     # line 2: hostname 
awk  "/DESCR/{print \$3}" /etc/lsb-release # line 3 : host linux distribution version
ip a | awk "/inet / && !/127.0.0.1/{sub(\"/.*\",\"\",\$2);printf(\"%s \", \$2)}"      # line 4: list IP address to the host
'

Results:

2022-03-05:22:22:21
dudi-HP-Compaq-Elite-8300-MT
20
192.168.2.111 192.168.122.1 172.17.0.1

2. Process multiple lines of information from remote host

Read lines of information from remote host, into an array sshResultsArr.

readarray -t sshResultsArr < <(ssh -q dudi-HP-Compaq-Elite-8300-MT  <<< '
date +%F:%T   # line 1: time stamp
hostname -f     # line 2: hostname 
awk  "/DESCR/{print \$3}" /etc/lsb-release # line 3 : host linux distribution version
ip a | awk "/inet / && !/127.0.0.1/{sub(\"/.*\",\"\",\$2);printf(\"%s \", \$2)}"      # line 4: list IP address to the host
')
hostname=${sshResultsArr[1]}
osVersion=${sshResultsArr[2]}
hasDockerIp=$(grep -Eo "172(.[[:digit:]]{1,3}){3}" <<< "${sshResultsArr[3]}") # find IP starting with 172
hasDockerIp=${hasDockerIp:="none"} # if not found IP set to "NONE"

printf "%s \t OS version: %s \t has Docker IP: %s\n" "$hostname" "$osVersion" "$hasDockerIp"

Result:

dudi-HP-Compaq-Elite-8300-MT     OS version: 20          has Docker IP: 172.17.0.1

3. Process each remote host in a loop

#!/bin/bash
for host in "$@"; do
  readarray -t sshResultsArr < <(ssh -q $host  <<< '
  date +%F:%T   # line 1: time stamp
  hostname -f     # line 2: hostname 
  awk  "/DESCR/{print \$3}" /etc/lsb-release # line 3 : host linux distribution version
  ip a | awk "/inet / && !/127.0.0.1/{sub(\"/.*\",\"\",\$2);printf(\"%s \", \$2)}"      # line 4: list IP address to the host
  ')
  hostname=${sshResultsArr[1]}
  osVersion=${sshResultsArr[2]}
  hasDockerIp=$(grep -Eo "172(.[[:digit:]]{1,3}){3}" <<< "${sshResultsArr[3]}") # find IP starting with 172
  hasDockerIp=${hasDockerIp:="none"} # if not found IP set to "NONE"

  printf "%s \t OS version: %s \t has Docker IP: %s\n" "$hostname" "$osVersion" "$hasDockerIp"
done
我还不会笑 2025-01-18 15:11:54

我从收到的答案中汲取了一些经验,并整理出了一些行之有效的东西。谢谢大家的回答。

for host in "$@"
do
    case "$host" in
       ('vho1uc1-primary'|'vho1uc2-backup'|'vho2uc1-primary'|'vho2uc2-backup'|'vho3uc1-primary'|'vho3uc2-backup'|'vho10uc1-primary')
          var1=`ssh "$host" sudo /etc/init.d/apache2 status|awk '{print $4}'`
          var2="$( echo $var1 | cut -c 3-5 )"
            if [[ "$var2" == "$var3" ]]; then
          echo "Apache2 on $host is running"
          echo "0"
            else
          echo "Apache2 on $host is not running"
          echo "2"
          fi
          ;;
       *)
    esac
done

I was able to take a little bit from the answers I received and put together something that works well. Thank you all for your answers.

for host in "$@"
do
    case "$host" in
       ('vho1uc1-primary'|'vho1uc2-backup'|'vho2uc1-primary'|'vho2uc2-backup'|'vho3uc1-primary'|'vho3uc2-backup'|'vho10uc1-primary')
          var1=`ssh "$host" sudo /etc/init.d/apache2 status|awk '{print $4}'`
          var2="$( echo $var1 | cut -c 3-5 )"
            if [[ "$var2" == "$var3" ]]; then
          echo "Apache2 on $host is running"
          echo "0"
            else
          echo "Apache2 on $host is not running"
          echo "2"
          fi
          ;;
       *)
    esac
done
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文