如何编写Linux脚本实现自动SFTP登录服务器并自动输入PEM密钥密码?
嘿,我明白你遇到的问题了——你想用带密码保护的PEM密钥通过SFTP自动登录,但之前的命令参数用错了,-p其实是用来指定SFTP端口的,根本不是传递密钥密码的参数。别担心,我给你几个实用的Linux脚本解决方案,都是日常运维里常用的办法:
方案1:用ssh-agent临时托管密钥密码(推荐,最安全)
这个方法不会把密钥密码明文写在脚本里,而是通过ssh-agent临时托管密钥,输入一次密码后后续操作就无需重复输入。
示例脚本:
#!/bin/bash # 启动ssh-agent进程 eval "$(ssh-agent -s)" # 加载带密码的PEM密钥,执行到这里会提示你输入密钥密码 ssh-add /绝对路径/rsa_private.pem # 执行SFTP操作,这里可以替换成你需要的命令,比如上传/下载文件 sftp -i /绝对路径/rsa_private.pem username@ip_address << EOF # 示例命令:列出远程服务器目录 ls # 示例命令:下载远程文件到本地 get remote_file.txt ./local_dir/ # 示例命令:上传本地文件到远程 put ./local_file.txt /remote_dir/ EOF # 操作完成后关闭ssh-agent ssh-agent -k
如果想让脚本完全自动输入密钥密码(仅限测试环境或信任度极高的场景,因为密码会明文暴露),可以配合sshpass工具:
- 先安装sshpass:
sudo apt install sshpass(Debian/Ubuntu)或sudo yum install sshpass(RHEL/CentOS) - 修改脚本里的
ssh-add行:
sshpass -p "你的密钥密码" ssh-add /绝对路径/rsa_private.pem
方案2:用expect脚本处理交互式密码输入
Expect是专门用来自动化交互式命令的工具,适合这种需要自动回应密码提示的场景。
示例脚本:
#!/usr/bin/expect # 设置超时时间(单位:秒) set timeout 15 # 定义变量,替换成你的实际信息 set key_path "/绝对路径/rsa_private.pem" set key_pass "你的密钥密码" set user "username" set server_ip "ip_address" # 启动SFTP命令 spawn sftp -i $key_path $user@$server_ip # 匹配密钥密码提示,自动输入密码 expect "Enter passphrase for key" send "$key_pass\r" # 执行你需要的SFTP操作 expect "sftp>" send "ls\r" # 列出远程目录 send "get log.tar.gz\r" # 下载文件 send "exit\r" # 退出SFTP # 等待命令执行完成 expect eof
先安装expect:sudo apt install expect或sudo yum install expect
方案3:修改ssh_config实现长期免密(适合频繁登录的场景)
如果你经常需要登录这台服务器,可以修改~/.ssh/config配置,结合ssh-agent实现长期免密:
- 编辑配置文件:
vim ~/.ssh/config - 添加以下内容:
Host sftp_server HostName ip_address User username IdentityFile /绝对路径/rsa_private.pem AddKeysToAgent yes
- 保存退出后,第一次执行
ssh-add /绝对路径/rsa_private.pem输入密钥密码,之后直接用sftp sftp_server就能登录,脚本里也可以直接用这个简化命令。
重要安全提醒
- 务必确保你的PEM密钥文件权限是600:
chmod 600 /绝对路径/rsa_private.pem,否则SSH会拒绝使用该密钥。 - 除非是完全可控的测试环境,否则不要把密钥密码明文写在脚本里,优先选择ssh-agent的方案。
内容的提问来源于stack exchange,提问作者Sam White




