sshpass & svn commit in script: 当脚本 运行 手动时工作,当 运行 与 Cron 时失败
sshpass & svn commit in script: Works when script run manually, fails when run with Cron
我编写了一个 Bash 脚本,用于自动更新我存储在 SourceForge 和 GitHub 上的某些文件。在文件末尾附近,我有两个命令分别将更新的文件 Rsync 到 SourceForge 和 Svn 将它们提交到 GitHub(在有人问之前,我有使用 Svn 而不是 Git 的理由) ).
我的问题是,当我手动 运行 脚本执行它需要执行的操作时,将更改提交到 GitHub 的代码行失败并出现身份验证错误。
我编写了脚本以将 Stderr 的内容输出到日志文件中。这是我手动 运行 脚本后该文件的内容并且它有效:
auto_update_svn.bash:
17 Sep 2018 18:42 UTC
SSHPASS searching for password prompt using match "assword"
SSHPASS read: Authentication realm: <https://github.com:443> GitHub
SSHPASS read:
SSHPASS read: Password for 'XJDHDR':
SSHPASS detected prompt. Sending password.
SSHPASS read: *
<"SSHPASS read: *" repeated another 25 times
SSHPASS read:
SSHPASS read:
这是在我通过 Crontab 运行 脚本失败后日志显示的内容:
auto_update_svn.bash:
16 Sep 2018 14:00 UTC
svn: E215004: Authentication failed and interactive prompting is disabled; see the --force-interactive option
svn: E215004: Commit failed (details follow):
svn: E215004: No more credentials or we tried too many times.
Authentication failed
svn: E200042: Additional errors:
svn: E120191: Error running context: The requested authentication type(s) are not supported
据我所知,当我使用 Cron 运行 时,sshpass 没有 运行ning,因此 Svn 没有收到密码。很奇怪,因为在前面的几行中,我使用 sshpass 和 Rsync 将文件发送到 SouceForge,并且当脚本是 运行 通过 Cron 时它起作用了。我经常看到的一种解决方案与限制 Cron 中的 Path 环境变量有关。我用脚本顶部附近的这一行解决了这个问题,但对我来说没有帮助:PATH=$PATH:$(grep 'PATH=' /etc/environment | sed 's/^.*=// ; s/\"//g')
这是我的 Crontab 中的内容:
0 14 * * * /bin/bash /home/svn/xjdhdr-random-code/Bash/auto_update_svn.bash
这是我脚本的内容:
#!/bin/bash
PATH=$PATH:$(sed -n '/PATH=/s/^.*=// ; s/\"//gp' '/etc/environment')
sDateTime=$(date -u +"%d %b %Y %H:%M")
{
# Commit changes
# SourceForge
sshpass -f "$HOME/sourceforge_password.txt" rsync -qcruz -e ssh --exclude=.svn '/home/svn/xjdhdr-random-code/' \
'xjdhdr@frs.sourceforge.net:/home/frs/project/xjdhdr-random-code/'
# GitHub
svn status '/home/svn/xjdhdr-random-code/' | grep ^\? | cut -c2- | while IFS='' read -r sFile
do
svn add "$sFile"
done
sshpass -v -f "$HOME/github_password.txt" svn commit --username=XJDHDR --no-auth-cache \
-m 'Automatic update of Adblock, Bash + blocklist files' '/home/svn/xjdhdr-random-code'
} 2> '/tmp/stderr-contents-auto_update_svn.txt'
if [ -f '/tmp/stderr-contents-auto_update_svn.txt' ]
then
errors+=$(cat '/tmp/stderr-contents-auto_update_svn.txt')
rm -f '/tmp/stderr-contents-auto_update_svn.txt'
fi
if [ -n "$errors" ]
then
printf 'auto_update_svn.bash:\n%s UTC\n'"$errors"'\n\n' "$sDateTime" >> '/home/error_reports_to_email.txt'
fi
我设法找到了问题的原因和解决方案。
首先,原因。 SSHPass
要求通过它的程序 运行 必须提示输入密码,然后它将提供给提示程序。 Svn commit
反过来,如果没有通过命令行开关 提供密码并且在交互式环境 运行 中 ,则会提示输入密码。这就是为什么我在观察我观察到的东西;当 运行 手动运行脚本时,svn 运行 在交互式环境中运行。反之,当svn通过Cron运行时,检测到环境是not交互。因此,它不会提示输入密码,SSHPass
也无能为力。
这种情况下的解决方法是在svn的命令中加入开关--force-interactive
。因此,我脚本中的相关行现在显示:
sshpass -v -f "$HOME/github_password.txt" svn commit --username=XJDHDR --no-auth-cache --force-interactive \
-m 'Automatic update of Adblock, Bash + blocklist files' '/home/svn/xjdhdr-random-code'
另一种可能的解决方案是将 --password
开关添加到带有问题密码的 svn 命令中,并避免完全使用 SSHPass
。在我的例子中,这是行不通的,因为这需要将密码以纯文本形式添加到脚本中。这给我带来了两个问题。首先,服务器上的每个用户帐户都可以访问脚本 运行ning 而 SSHPass 使用的密码文件只能由用于执行脚本的用户帐户读取。其次,此脚本是上传到我的 SourceForge 和 GitHub 存储库的文件之一。
我编写了一个 Bash 脚本,用于自动更新我存储在 SourceForge 和 GitHub 上的某些文件。在文件末尾附近,我有两个命令分别将更新的文件 Rsync 到 SourceForge 和 Svn 将它们提交到 GitHub(在有人问之前,我有使用 Svn 而不是 Git 的理由) ).
我的问题是,当我手动 运行 脚本执行它需要执行的操作时,将更改提交到 GitHub 的代码行失败并出现身份验证错误。
我编写了脚本以将 Stderr 的内容输出到日志文件中。这是我手动 运行 脚本后该文件的内容并且它有效:
auto_update_svn.bash:
17 Sep 2018 18:42 UTC
SSHPASS searching for password prompt using match "assword"
SSHPASS read: Authentication realm: <https://github.com:443> GitHub
SSHPASS read:
SSHPASS read: Password for 'XJDHDR':
SSHPASS detected prompt. Sending password.
SSHPASS read: *
<"SSHPASS read: *" repeated another 25 times
SSHPASS read:
SSHPASS read:
这是在我通过 Crontab 运行 脚本失败后日志显示的内容:
auto_update_svn.bash:
16 Sep 2018 14:00 UTC
svn: E215004: Authentication failed and interactive prompting is disabled; see the --force-interactive option
svn: E215004: Commit failed (details follow):
svn: E215004: No more credentials or we tried too many times.
Authentication failed
svn: E200042: Additional errors:
svn: E120191: Error running context: The requested authentication type(s) are not supported
据我所知,当我使用 Cron 运行 时,sshpass 没有 运行ning,因此 Svn 没有收到密码。很奇怪,因为在前面的几行中,我使用 sshpass 和 Rsync 将文件发送到 SouceForge,并且当脚本是 运行 通过 Cron 时它起作用了。我经常看到的一种解决方案与限制 Cron 中的 Path 环境变量有关。我用脚本顶部附近的这一行解决了这个问题,但对我来说没有帮助:PATH=$PATH:$(grep 'PATH=' /etc/environment | sed 's/^.*=// ; s/\"//g')
这是我的 Crontab 中的内容:
0 14 * * * /bin/bash /home/svn/xjdhdr-random-code/Bash/auto_update_svn.bash
这是我脚本的内容:
#!/bin/bash
PATH=$PATH:$(sed -n '/PATH=/s/^.*=// ; s/\"//gp' '/etc/environment')
sDateTime=$(date -u +"%d %b %Y %H:%M")
{
# Commit changes
# SourceForge
sshpass -f "$HOME/sourceforge_password.txt" rsync -qcruz -e ssh --exclude=.svn '/home/svn/xjdhdr-random-code/' \
'xjdhdr@frs.sourceforge.net:/home/frs/project/xjdhdr-random-code/'
# GitHub
svn status '/home/svn/xjdhdr-random-code/' | grep ^\? | cut -c2- | while IFS='' read -r sFile
do
svn add "$sFile"
done
sshpass -v -f "$HOME/github_password.txt" svn commit --username=XJDHDR --no-auth-cache \
-m 'Automatic update of Adblock, Bash + blocklist files' '/home/svn/xjdhdr-random-code'
} 2> '/tmp/stderr-contents-auto_update_svn.txt'
if [ -f '/tmp/stderr-contents-auto_update_svn.txt' ]
then
errors+=$(cat '/tmp/stderr-contents-auto_update_svn.txt')
rm -f '/tmp/stderr-contents-auto_update_svn.txt'
fi
if [ -n "$errors" ]
then
printf 'auto_update_svn.bash:\n%s UTC\n'"$errors"'\n\n' "$sDateTime" >> '/home/error_reports_to_email.txt'
fi
我设法找到了问题的原因和解决方案。
首先,原因。 SSHPass
要求通过它的程序 运行 必须提示输入密码,然后它将提供给提示程序。 Svn commit
反过来,如果没有通过命令行开关 提供密码并且在交互式环境 运行 中 ,则会提示输入密码。这就是为什么我在观察我观察到的东西;当 运行 手动运行脚本时,svn 运行 在交互式环境中运行。反之,当svn通过Cron运行时,检测到环境是not交互。因此,它不会提示输入密码,SSHPass
也无能为力。
这种情况下的解决方法是在svn的命令中加入开关--force-interactive
。因此,我脚本中的相关行现在显示:
sshpass -v -f "$HOME/github_password.txt" svn commit --username=XJDHDR --no-auth-cache --force-interactive \
-m 'Automatic update of Adblock, Bash + blocklist files' '/home/svn/xjdhdr-random-code'
另一种可能的解决方案是将 --password
开关添加到带有问题密码的 svn 命令中,并避免完全使用 SSHPass
。在我的例子中,这是行不通的,因为这需要将密码以纯文本形式添加到脚本中。这给我带来了两个问题。首先,服务器上的每个用户帐户都可以访问脚本 运行ning 而 SSHPass 使用的密码文件只能由用于执行脚本的用户帐户读取。其次,此脚本是上传到我的 SourceForge 和 GitHub 存储库的文件之一。