Вопрос

I need to collect user information from 100 remote servers. We have public/private key infrastructure for authentication, and I have configured ssh-agent command to forward key, meaning i can login on any server without password prompt (auto login).

Now I want to run a script on all server to collect user information (how many user account we have on all servers).

This is my script to collect user info.

#!/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"

I don't know how to run this script using ssh without interaction??

Это было полезно?

Решение

Since you need to log into the remote machine there is AFAICT no way to do this "without ssh". However, ssh accepts a command to execute on the remote machine once logged in (instead of the shell it would start). So if you can save your script on the remote machine, e.g. as ~/script.sh, you can execute it without starting an interactive shell with

$ ssh remote_machine ~/script.sh

Once the script terminates the connection will automatically be closed (if you didn't configure that away purposely).

Другие советы

Sounds like something you can do using expect.

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

Expect is a program that "talks" to other interactive programs according to a script. Following the script, Expect knows what can be expected from a program and what the correct response should be.

If you've got a key on each machine and can ssh remotehost from your monitoring host, you've got all that's required to collect the information you've asked for.

#!/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

Results for me:

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

Note that this makes TWO ssh connections to each server to collect each datum. If you'd like to do this a little more efficiently, you can bundle the information into a single, slightly more complex collection script:

#!/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

(Identical results.)

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

(Note: the "proper" way to authenticate without manually entering in password is to use SSH keys. Storing password in plaintext even in your local scripts is a potential security vulnerability)

You can run expect as part of your bash script. Here's a quick example that you can hack into your existing script:

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"

You can also use pscp to copy files back and forth as part of a script so you don't need to manually supply the password as part of the interaction:

Install putty-tools:

$ sudo apt-get install putty-tools

Using pscp in your script:

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

maybe you'd like to try the expect command as following

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

the expect command will catch the "password:" and then auto fill the passwd your send by above.

Remember that replace the ssh_port, ssh_username, ssh_server_host and your_passwd with your own configure

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top