Linux下sshpass搭配scp通过crontab执行失败问题求助
crontab执行scp脚本失败但手动执行正常的排查解决
问题描述
手动通过Putty连接服务器A执行以下命令,可正常从服务器B复制文件:
sshpass -p 'myPass' scp userB@serverB_ip:/file.txt /home/XXXXXX.txt
但将命令写入Shell脚本copyfilefromB.sh并通过crontab定时执行时,复制操作失败。脚本内容如下:
#!/bin/sh echo "start" sshpass -p 'myPass' scp userB@serverB_ip:/file.txt /home/XXXXXX.txt echo "end"
尝试过指定命令绝对路径仍无效:
/usr/bin/sshpass -p 'myPass' scp userB@serverB_ip:/file.txt /home/XXXXXX.txt /usr/bin/sshpass -p 'myPass' /usr/bin/scp userB@serverB_ip:/file.txt /home/XXXXXX.txt
crontab配置:
0 1 * * * /usr/bin/sh /home/copyfilefromB.sh >> copyfilefromB.log
日志文件仅显示start和end,无错误信息,但文件未成功复制。
可能的原因及解决方法
1. crontab环境变量缺失
crontab的执行环境比手动登录的环境精简很多,PATH变量可能不包含依赖命令的路径,即使指定了绝对路径,也可能缺少其他必要环境变量。解决:
在脚本开头手动指定完整环境变量:
#!/bin/sh export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin echo "start" /usr/bin/sshpass -p 'myPass' /usr/bin/scp userB@serverB_ip:/file.txt /home/XXXXXX.txt echo "end"
2. SSH主机密钥未信任
手动执行时你已经确认过服务器B的主机密钥,但crontab执行的环境下未保存该密钥,scp会因需要交互确认而静默失败。解决:
- 手动登录服务器A,执行
ssh userB@serverB_ip,确认并保存主机密钥到~/.ssh/known_hosts; - 或者在scp命令中添加参数跳过验证(注意存在安全风险):
/usr/bin/sshpass -p 'myPass' /usr/bin/scp -o StrictHostKeyChecking=no userB@serverB_ip:/file.txt /home/XXXXXX.txt
3. 未捕获错误输出
当前日志仅收集了标准输出,错误输出(stderr)未被捕获,导致看不到具体错误。解决:
- 修改crontab,将错误输出也写入日志:
0 1 * * * /usr/bin/sh /home/copyfilefromB.sh >> /home/copyfilefromB.log 2>&1
- 或者在脚本的scp命令后添加错误重定向:
/usr/bin/sshpass -p 'myPass' /usr/bin/scp userB@serverB_ip:/file.txt /home/XXXXXX.txt >> /home/copyfilefromB.log 2>&1
4. 文件权限问题
- 检查目标路径
/home/XXXXXX.txt的权限,确认crontab执行用户(默认是当前用户)有写入权限; - 检查服务器B上的
/file.txt是否对userB有读取权限。
5. 密码特殊字符解析问题
如果密码包含$、!等特殊字符,在脚本或crontab中可能被解析为变量或特殊符号,导致密码错误。解决:
- 确保密码用单引号包裹(已做的前提下,确认无转义冲突);
- 或者将密码写入权限为600的文件,用
sshpass -f读取,避免解析问题:
# 先创建密码文件并设置权限 echo 'myPass' > /home/sshpass.txt chmod 600 /home/sshpass.txt # 脚本中修改为 /usr/bin/sshpass -f /home/sshpass.txt /usr/bin/scp userB@serverB_ip:/file.txt /home/XXXXXX.txt
内容的提问来源于stack exchange,提问作者TMCHAN2020
相关产品推荐
相关产品推荐

