在Shell脚本中输入密码

在Shell脚本中输入密码的几种情况

如果是要使用sudo

首先在Shell脚本中使用sudo不是一个好主意。

可以考虑的替代方案有,

  1. 在脚本中去掉sudo,而要求在运行脚本时使用sudo。
  2. 如果是任务计划,考虑配置在root用户下。

在确定要在Shell中sudo的情况下可以使用如下方式

1
echo '密码' | sudo -S 命令 

如果是通过ssh/autossh建立远程连接或建立tunnel

考虑用SSH密钥登录来避免使用密码

例如我们要从 hostA 通过ssh密钥登录 hostB

我们现在 hostA 上生成密钥

1
ssh-keygen -t rsa

会询问将密钥放在何处,默认即可。然后是输入密码,留空(否则你登录不仅需要私钥还要输入密码)。

完成后在~/.ssh目录下会生成两个文件id_rsa和id_rsa.pub,一个私钥一个公钥。

把公钥追加到 hostB 某个用户的 ~/.ssh/authorized_keys 就代表 hostB 的这个用户允许持有相应私钥登录

ssh-copy-id命令可以帮我们完成追加公钥的操作

命令格式:ssh-copy-id [-p SSH端口默认22] [user@]hostname

在 hostA 上执行

1
ssh-copy-id root@hostB

按提示输出密码即可

还需要确保 hostB 的sshd服务配置允许使用公钥授权

配置文件路径 /etc/ssh/sshd_config

确认

1
PubkeyAuthentication yes

如果修改过配置需要重启sshd服务

1
service sshd restart

在hostA上现在可以验证登录hostB不再需要输入密码

1
ssh root@hostB

其他情况或其他程序需要输入密码

可以用expect工具,事实上这种方法也可以应对上面的几种情况

使用autossh+expect建立ssh tunnel的用法举例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/bash

passwd='123456'

/usr/bin/expect <<-EOF

set time 10
spawn autossh -M 0 -CNg -L 1433:192.168.1.140:1433 root@$WAN_IP -p $WAN_PORT
expect {
"*yes/no" { send "yes\n"; exp_continue }
"*password:" { send "$passwd\n" }
}
expect eof
EOF

expect更详细的说明自行搜索 linux expect