通过SSH远程运行脚本

3

我需要从100个远程服务器收集用户信息。我们有公共/私人密钥基础设施进行身份验证,并且我已配置了ssh-agent命令以转发密钥,这意味着我可以在任何服务器上自动登录而无需输入密码。

现在,我想在所有服务器上运行脚本以收集用户信息(所有服务器上有多少个用户帐户)。

这是我的收集用户信息的脚本。

#!/bin/bash
_l="/etc/login.defs"
_p="/etc/passwd"

## get mini UID limit ##
l=$(grep "^UID_MIN" $_l)

## get max UID limit ##
l1=$(grep "^UID_MAX" $_l)

awk -F':' -v "min=${l##UID_MIN}" -v "max=${l1##UID_MAX}" '{ if ( $3 >= min && $3 <= max  && $7 != "/sbin/nologin" ) print $0 }' "$_p"

我不知道如何在没有交互的情况下使用SSH运行此脚本?
6个回答

3

既然需要登录到远程机器,据我所知没有“不使用ssh”的方法。但是,ssh接受一个命令在登录后在远程机器上执行(而不是启动它的shell)。因此,如果您可以将脚本保存在远程机器上,例如作为~/script.sh,则可以使用以下命令在不启动交互式shell的情况下执行它:

$ ssh remote_machine ~/script.sh

一旦脚本终止,连接将自动关闭(如果您没有故意配置它)。


啊!我怎么错过了scp :( 我可以做到无需密码进行scp,并将此脚本推送到所有远程服务器的/tmp目录中并运行ssh来执行它们.. 这就是提醒我的原因。 - Satish
如果您无论如何都要在每个系统上安装东西,为什么不全力以赴地使用像Munin这样的完整工具呢?您可以添加自定义信息,随时间绘制结果图表,设置通知,如果主机变得不可达。监控是好的。 :-) 在Munin文档中有关于使用yum在Linux系统上安装Munin的说明。 - ghoti

3
听起来像是可以使用expect完成的事情。

http://linux.die.net/man/1/expect

Expect是一个可以根据脚本与其他交互式程序“对话”的程序。根据脚本,Expect知道可以从程序中预期什么以及正确的响应应该是什么。


我知道我们可以使用 EXPECT 程序,但我认为如果我能找到更简单的方法来使它变得简单就好了。 - Satish
1
好的。我知道我有一些 Expect 脚本,用于从多台服务器获取信息... 一旦我找到它们,我就会在这里发布一个示例。 - andrux

2

如果您在每台机器上都有一把钥匙,并且可以从监控主机上使用 ssh remotehost 命令,那么您就拥有了收集所需信息的全部条件。

#!/bin/bash

servers=(wopr gerty mother)

fmt="%s\t%s\t%s\n"
printf "$fmt" "Host" "UIDs" "Highest"
printf "$fmt" "----" "----" "-------"

count='awk "END {print NR}" /etc/passwd' # avoids whitespace problems from `wc`
highest="awk -F: '\$3>n&&\$3<60000{n=\$3} END{print n}' /etc/passwd"

for server in ${servers[@]}; do
    printf "$fmt" "$server" "$(ssh "$server" "$count")" "$(ssh "$server" "$highest")"
done

我的结果:

$ ./doit.sh
Host    UIDs    Highest
----    ----    -------
wopr    40      2020
gerty   37      9001
mother  32      534

请注意,这将对每个服务器进行两个ssh连接以收集每个数据。如果您想更有效地执行此操作,可以将信息捆绑到一个单一的、稍微复杂一些的采集脚本中:
#!/usr/local/bin/bash

servers=(wopr gerty mother)

fmt="%s\t%s\t%s\n"
printf "$fmt" "Host" "UIDs" "Highest"
printf "$fmt" "----" "----" "-------"

gather="awk -F: '\$3>n&&\$3<60000{n=\$3} END{print NR,n}' /etc/passwd"

for server in ${servers[@]}; do
    read count highest < <(ssh "$server" "$gather")
    printf "$fmt" "$server" "$count" "$highest"
done

(结果相同。)


2

使用ssh连接到远程服务器,执行本地脚本localscript.bash


0

也许你想尝试以下 expect 命令

#!/usr/bin/expect
set timeout 30
spawn ssh -p ssh_port -l ssh_username ssh_server_host
expect "password:" 
send "your_passwd\r"
interact

expect命令将捕获"password:",然后自动填充上面发送的密码。

记得用你自己的配置替换ssh_port、ssh_username、ssh_server_host和your_passwd。


0
(注:在不手动输入密码的情况下进行身份验证的“正确”方法是使用SSH密钥。即使在本地脚本中以明文形式存储密码也可能存在安全漏洞)
您可以将expect作为bash脚本的一部分运行。以下是一个快速示例,您可以将其插入到现有脚本中:
login=user
IP=127.0.0.1
password='your_password'

expect_sh=$(expect -c "
spawn ssh $login@$IP
expect \"password:\"
send \"$password\r\"
expect \"#\"
send \"./$remote_side_script\r\"
expect \"#\"
send \"cd /lib\r\"
expect \"#\"
send \"cat file_name\r\" 
expect \"#\"
send \"exit\r\"
")

echo "$expect_sh"

您还可以使用pscp作为脚本的一部分来复制文件,这样您就不需要手动提供密码以进行交互:

安装putty-tools:

$ sudo apt-get install putty-tools

在你的脚本中使用 pscp:

pscp -scp -pw $password file_to_copy $login@$IP:$dest_dir

不幸的是,我有RedHat系统(yum)。无法编译或安装第三方工具 :( - Satish

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接