Issue
I have written a Bash script that I use to automatically update certain files that I store on SourceForge and GitHub. Near the end of the file, I have two commands that Rsync the updated files to SourceForge and Svn Commit them to GitHub, respectively (before anyone asks, I have my reasons for using Svn rather than Git).
My problem is that while the script does what it needs to do when I run it manually, the line of code that commits the changes to GitHub fails with an authentication error.
I have programmed the script to output the contents of Stderr into a log file. This is the contents of that file after I run the script manually and it works:
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:
This is what that log says after I run the script through Crontab and it fails:
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
From what I can see, sshpass is not running when I run it with Cron and so Svn doesn't receive a password. Strange because a few lines earlier, I use sshpass with Rsync to send file to SouceForge and that works when the script is run through Cron. One solution I've often seen is related to the Path environment variable in Cron being limited. I fixed this in my case with this line near the top of my script but it doesn't help in my case: PATH=$PATH:$(grep 'PATH=' /etc/environment | sed 's/^.*=// ; s/\"//g')
This is what I have in my Crontab:
0 14 * * * /bin/bash /home/svn/xjdhdr-random-code/Bash/auto_update_svn.bash
And this is the contents of my script:
#!/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/' \
'[email protected]:/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
Solution
I managed to find the cause of my problem and solution.
First, the cause. SSHPass
requires that the program run through it must prompt for a password, which it will then supply to the prompting program. Svn commit
, in turn, will prompt for a password if one hasn't been supplied through a command line switch and is running in an interactive environment. This is why I was observing what I observed; when running the script manually, svn was running in an interactive environment. Conversely, when svn is run through Cron, it detects that the environment is not interactive. Hence, it does not prompt for a password and SSHPass
can't do anything.
The solution in this case is to add the switch --force-interactive
to svn's command. Thus, the relevant line in my script now says:
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'
Another possible solution would be to add the --password
switch to the svn command with the password in question and avoid using SSHPass
entirely. In my case, this wouldn't work because that would require adding the password in plain text to the script. This causes two problems for me. First, the script is accessible by every user account on the server I have this script running whereas the password file used by SSHPass is only readable by the user account that is used to execute the script. Second, this script is one of the files that is uploaded to my SourceForge and GitHub repositories.
Answered By - XJDHDR