我想将多个本地文件与远程主机上的对应文件进行比较,因此我想创建一个如下脚本:
ssh user@remote_host "cat remote_file1.txt" | diff - local_file1.txt
ssh user@remote_host "cat remote_file2.txt" | diff - local_file2.txt
...
ssh user@remote_host "cat remote_fileN.txt" | diff - local_fileN.txt
此类脚本的问题在于它会询问每个文件的密码。如何让它只询问一次密码?
答案1
一种方法是设置无密码访问(公钥身份验证),另一种方法是复用连接。~/.ssh/config
使用以下内容创建配置文件:
Host remote_host
User user
ControlPath ~/.ssh/controlmasters/%r@%h:%p
ControlMaster auto
ControlPersist 5m
创建一个目录~/.ssh/controlmasters/
:
mkdir -m 700 ~/.ssh/controlmasters/
然后,当您运行脚本时,它应该只询问一次密码,所有其他命令将通过相同的、已经经过身份验证的连接运行。
答案2
如果您不允许使用以下命令创建无密码访问ssh-keygen user@remotehost
,您可以安装常用expect
工具,并创建名为 的脚本passexpect
:
#!/usr/bin/expect -f
set timeout 20
set cmd [lrange $argv 1 end]
set password [lindex $argv 0]
log_user 0
eval spawn $cmd
expect "assword:"
send "$password\r";
interact
然后在主 shell 脚本中,您可以读取密码一次:
printf "ssh password:" >&2; read -s pass; printf "\n">&2
并在任何 ssh 命令中使用它:
passexpect $pass ssh user@remotehost command_for_remote_host
或者为了您的目的,完整的脚本将是:
#/usr/bin/env bash
printf "ssh password:" >&2; read -s pass; printf "\n">&2
./passexpect $pass ssh user@remotehost cat remoteF1.txt | diff - localF1.txt
./passexpect $pass ssh user@remotehost cat remoteF2.txt | diff - localF2.txt