非交互方式运行ssh/scp命令

在使用ssh或者scp的时候都需要用户输入密码,可有些时候我们希望在脚本里面执行ssh/scp以免去用户输入密码的过程。
ssh/scp能不能从文件或者其他地方获取密码,而不需要用终端交互输入呢。

工具expect可以用来满足这种需求:

  1. 定义一个expect脚本文件
$ cat ./exp
#!/usr/bin/env expect

# Usage example:
# ssh: exp  ssh @ 
# scp: exp  scp  @:

set timeout 20
set password [lindex $argv 0]
set cmd      [lindex $argv 1]
set param    [lrange $argv 2 end]

eval spawn $cmd -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no $param
expect "password:"
send "$password\r";
interact
  1. 执行脚本文件

远程执行:
./exp ssh @

远程拷贝:
./exp scp @: # 本地文件拷远程
./exp scp @: # 远端文件拷本地

  1. 使用限制

上述exp不能使用在stdin发生重定向过的环境下面,例如:

$ cat t.data 
aa
$ cat t.sh
#!/bin/bash

file=t.data
while IFS= read -r line; do
  ./exp mypassword ssh username@hostname ls
done < "$file"

运行结果是什么:

$ ./t.sh 
spawn ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no username@hostname ls
Warning: Permanently added 'hostname,10.9.X.X' (ECDSA) to the list of known hosts.
username@hostname's password: [username@localhost ~/]$ 

expect无法从当前环境中识别出状态,也就无法给ssh输送密码域。
解决的办法是不要使用输入输出重定向,可以先把文件的内容读出到变量里面,然后再来循环变量,保证在循环的时候,也就是调用exp的时候没有重定向行为发生。

你可能感兴趣的:(非交互方式运行ssh/scp命令)