我有一个远程目录,我想通过 ssh 将其同步到我的本地机器,无需密码,因为我希望它作为 cronjob(root 用户)运行
此命令(否sudo
)失败,因为它无法将文件写入/var/www/html/test-sftp
rsync -avz -e ssh --progress [email protected]:~/public_html/test-sftp/ /var/www/html/test-sftp
而这个命令(有sudo
)但会失败,因为远程服务器要求密码才能访问[email protected]:~/public_html/test-sftp/
请注意:我可以不用密码登录。ssh -p 2222 [email protected]
问题:在我的 crontab 中,如果我指定My-user_name
而不是root
,会rsync
正确执行吗?
挠头...有什么想法吗?
答案1
以下命令是@Bulat 回答的修改版本 在目标计算机上使用 rsync 和 sudo对我有用。
read -s -p "Remote sudo password: " SUDOPASS && sudo --preserve-env=SUDOPASS rsync -avz --stats --rsync-path="echo -n $SUDOPASS | sudo -Sv && sudo rsync" remoteuser@remotehost:/src/ /destination/
ZSH 不支持-p
选项read
。你应该使用
read -s "SUDOPASS?Remote sudo password: " && sudo --preserve-env=SUDOPASS rsync -avz --stats --rsync-path="echo -n $SUDOPASS | sudo -Sv && sudo rsync" remoteuser@remotehost:/src/ /destination/
该命令在 macOS 上对我来说不起作用。
答案2
分析
如果您rsync
从 crontab 以 My-user_name 身份运行,其行为将与rsync
不带 的运行类似sudo
。即使您授予用户对目标目录的写访问权限,也会出现问题,因为非 root 用户无法充分受益-a
(例如,rsync -a
将无法保留所有权,甚至不会尝试)。
您需要rsync
以 root 身份运行。然后-e ssh
它将以 root 身份运行ssh
。当您说“我可以不用密码登录”时,我猜您有一个密钥,并且ssh
以 My-user_name 身份运行会自动找到并使用该密钥。现在的问题是,ssh
以 root 身份运行不会自动找到此密钥。
解决方案
幸运的是你传递给的rsync -e
是完整命令,而不仅仅是某个可执行文件的名称。除了 sole,ssh
您还可以传递ssh -i /path/to/the/key
where /path/to/the/key
is/home/My-user_name/.ssh/id_rsa
或 so。您只需引用 right,这样整个命令就形成了一个选项参数-e
。它就像
sudo rsync -avz -e 'ssh -i /home/My-user_name/.ssh/id_rsa' …
ssh
以 root 身份运行应该能够读取该文件。
或者(我更喜欢这个解决方案),你可以sudo -u My-user_name ssh
,所以ssh
它本身以 My-user_name 身份运行并自动找到你的密钥。rsync
以 root 身份运行应该能够以sudo
任何用户身份运行命令而无需密码。完整命令是
sudo rsync -avz -e 'sudo -u My-user_name ssh' …
在 crontab 中
在 crontab 中您可能不需要第一个sudo
。
- 在系统范围的 crontab 中您不需要第一个
sudo
,只需指定 root 作为用户。 - 在 root 的 crontab 中(这不是全系统的)你不需要第一个
sudo
,rsync
将以root身份运行,因为它是root的crontab。 - 在您的 crontab 中,您需要第一个
sudo
,然后您需要无需密码即可运行的命令。这是可能的,但是如果我是你,我首先会使用系统范围或 root 的 crontab。
记住cron 用途PATH
那不是你的PATH
;sudo
可以使用完后还有PATH
。如果您不确定rsync
(或任何其他可执行文件)是否在PATH
当前重要位置,则考虑使用其完整路径。
时间到了,cron 将运行该作业无论前一个是否结束, 和你不想运行rsync
多个我会用flock
以防止发生这种情况。