Run scripts remotely via SSH

大憨熊 提交于 2019-12-06 02:51:39
Benjamin Bannier

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!