通过SSH的Rsync没有tty礼物

我在Debian的root的crontab中使用下面的命令。

rsync -vqrlHEAXogDtzhi --log-file=${LOG} --progress --rsync-path="sudo /usr/bin/rsync" --exclude-from=$CONFIG_DIR/excludes -e "ssh -i /home/backups/.ssh/id_rsa" backups@${HOSTNAME}:/ ${BACKUP_DIR} 

我得到以下内容:

 sudo: no tty present and no askpass program specified 

我曾尝试添加-t到ssh命令,我得到:

 Pseudo-terminal will not be allocated because stdin is not a terminal. 

我曾尝试添加-t -t到ssh命令,我得到:

 protocol version mismatch -- is your shell clean? 

我已经添加了一个.hushlogin到远程盒子上的备份用户,并确认我可以ssh作为备份使用远程框的一个键没有任何显示(login被搁置)。 我仍然收到这些消息。

请注意,我可以使用密钥ssh作为备份到远程盒成功。

请注意,我的sudo没有-tt选项。

请注意,源和目标的/ etc / sudoers文件中设置了以下内容:

 backups ALL= NOPASSWD:/usr/bin/rsync 

请注意,我的/ etc / sudoers文件没有任何引用:

 Defaults requiretty 

请注意,我不会在命令中回显我的密码。

我怎么能给这只猫蒙皮? :|

谢谢

有时候你觉得事情太难了。

Rsync未安装在远程系统上。

/捂脸

  1. 如果cron作业以root身份执行,则不需要sudo
  2. 有一些不必要的标志: -rlptgoD ; 删除并用-areplace。
  3. 来自sudo的TTY消息用于本地 TTY,而ssh-t选项用于远程 TTY。 不要混淆两者。
  4. 不要-v-q相互矛盾?
  5. 你最后的担心应该是本地SSH私钥是否被encryption。 前者不能用于无人参与的运行(例如, stdin不是TTY的;它们不是从terminal或terminal仿真器运行的)。

编辑/更新

  • 我收回1和2。
  • 3应该是在cron运行时没有本地的TTY,而SSH没有远程分配,因为没有本地的。

我会猜测这是一个关键的问题。 备份的私钥具有密码短语,或者公钥不在远程用户钥匙串中。 也许你以前的尝试使用了已经加载到你的钥匙串中的钥匙?

把这个放在这里,所以我可以记住和分享这个技巧:

 rsync -av -e "ssh -tt" --rsync-path="stty raw -echo; sudo /usr/bin/rsync" user@${HOSTNAME}:/ ${DEST_DIR} 

这个方法似乎绕过了一些tty的要求,这些tty在一些系统默认的/etc/sudoers文件中使用了Defaults requiretty 。 这个信息是在审查这个SO问题和答案后精心制作的。

在这个答案中,他们build议从/etc/sudoers删除Defaults requiretty 。 这是更简单的方法。 但是,如果您无法修改远程主机/etc/sudoers以删除此configuration选项,则可以尝试强制本地rsync使用ssh -tt 。 这个ssh选项在ssh客户端手册页面中描述,如下所示:

强制伪terminal分配。 这可以用来在远程机器上执行任意基于屏幕的程序,这可能是非常有用的,例如在实现菜单服务时。 多个-t选项强制tty分配,即使ssh没有本地tty。

因此,我们强制ssh分配一个伪tty来避免这个错误:

 Pseudo-terminal will not be allocated because stdin is not a terminal. stty: standard input: Inappropriate ioctl for device sudo: sorry, you must have a tty to run sudo 

然后,使用以下命令覆盖--rsync-path

 stty raw -echo; sudo /usr/bin/rsync 

stty raw -echo是将远程terminal的线路stty raw -echo设置为通过。 这有效地导致它的行为像一个pipe道,而不是一个没有-tt的伪terminal。

然后,远程rsync命令将是sudo /usr/bin/rsync ,它现在有一个伪tty,并将通过对sudorequiretty检查。