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 运行这个脚本??

4

6 回答 6

3

听起来像是你可以使用期望做的事情。

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

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

于 2012-10-17T15:20:44.960 回答
3

由于您需要登录远程机器,因此 AFAICT 无法“没有 ssh”来执行此操作。但是,ssh一旦登录就接受在远程机器上执行的命令(而不是它会启动的 shell)。因此,如果您可以将脚本保存在远程机器上,例如 as ~/script.sh,您可以在不启动交互式 shell 的情况下执行它

$ ssh remote_machine ~/script.sh

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

于 2012-10-17T15:23:22.783 回答
2

ssh remoteserver.example /bin/bash < localscript.bash

于 2013-11-15T17:44:05.970 回答
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

(相同的结果。)

于 2012-10-17T15:37:28.293 回答
0

也许您想尝试如下的期望命令

#!/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 命令将捕获“密码:”,然后自动填写您在上面发送的密码。

请记住,将 ssh_port、ssh_username、ssh_server_host 和 your_passwd 替换为您自己的配置

于 2013-11-15T14:54:46.923 回答
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 作为脚本的一部分来回复制文件,因此您无需在交互过程中手动提供密码:

安装腻子工具:

$ sudo apt-get install putty-tools

在脚本中使用 pscp:

pscp -scp -pw $password file_to_copy $login@$IP:$dest_dir
于 2012-10-17T15:30:39.903 回答