Ssh
遠端伺服器:通過 cronjob 將 rsync 與 ssh 與 gpg 一起使用時,權限被拒絕(公鑰)
我想通過 cronjob 定期備份我的遠端 VPS。兩個系統都執行 Debian 10。我一直在遵循本指南並根據自己的喜好對其進行了調整。腳本的相關部分:
/root/.local/bin/backup
#!/bin/bash SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket) rsync -avzAHXh -e ssh root@[someIP]:/path/to/remote/dir /path/to/local/dir \ || { echo "rsync died with error code $?"; exit 1; }
當我從終端執行它時,一切正常。但是,如果我通過 cronjob 執行它:
crontab -u root -e
# m h dom mon dow command 0 6 * * * /root/.local/bin/backup >> /var/log/backup 2>&1
然後
/var/log/backup
顯示:root@[someIP]: Permission denied (publickey).^M rsync: connection unexpectedly closed (0 bytes received so far) [Receiver] rsync error: error in rsync protocol data stream (code 12) at io.c(235) [Receiver=3.1.3] rsync died with error code 12
cronjob 出了什麼問題,我該怎麼辦?
PS:我已經刪除了我在這裡使用的 gpg 密鑰的密碼,試圖讓它工作。理想情況下,我想要一個即使我再次添加密碼也能工作的解決方案。
Cron 執行的命令有一個非常基本的執行環境和路徑設置,一個常見的錯誤是將命令或腳本測試為您的普通使用者 id。然後它在由 Cron 執行時失敗。
導出的環境變數經常被忽略。謹慎的做法是在部署之前以 root 身份使用完全縮減的環境進行最終測試,作為最終測試,使用子 shell。你總是可以添加一個一次性的 cronjob,它只是將它的 env 列印到一個日誌文件中,這使你能夠模擬你的命令在被 Cron 呼叫時執行的確切條件。第二個好處是,如果發生任何錯誤,它可以顯示在您的終端上,這樣調試起來更容易。
看起來你的腳本中分配的變數沒有導出,所以 SSH 不會選擇它。
在腳本中使用絕對文件路徑也很重要,除非您專門更改目錄,否則您不能假設您在特定目錄中,在一次性測試腳本中列印工作目錄,前面提到的也有幫助。您不能假設所有分佈在這方面都是相同的。檢查肯定沒有壞處。