Exit codes details

All Duplicacy commands return 0 when successful, otherwise non-zero. The specific non-zero codes are:

  • 1: the command was interrupted by user
  • 2: the command arguments are malformed
  • 3: invalid value for a command argument
  • 100: the command encountered an error in the Duplicacy code (most run-time errors, including those from failed connections, will emit this exit code)
  • 101: the command encountered an error in a dependency library used by Duplicacy

I think, as it is implemented right now, the 0 exit code is a little misleading. I mean, I would like to get a 0 exit code when absolutely no problem occurred, not even a warning, so that I can send (by scripting) an email saying “backup successful”.

I just did a backup, a file was not backed up, but I still got a 0 exit code! What if it was an important file? What if 99% of files (for some reason) were not backed up? Should i always “grep” the backup output looking for signs of trouble? What if I grep for some specific text and in some future release the warning message changes? The exit codes exist to avoid this kind of problems, I think. So why not to add another exit code in case of any warning or problem during the backup?

Here is my backup output that gave me 0 exit code:

Backup for / at revision 3 completed
Files: 1278499 total, 573,580M bytes; 183 new, 70,170K bytes
File chunks: 116957 total, 573,807M bytes; 11 new, 62,841K bytes, 19,645K bytes uploaded
Metadata chunks: 92 total, 482,955K bytes; 16 new, 99,754K bytes, 28,975K bytes uploaded
All chunks: 117049 total, 574,278M bytes; 27 new, 162,596K bytes, 48,620K bytes uploaded
Total running time: 00:02:30
1 file was not included due to access errors

I’ve just created an issue on GitHub.

1 Like

2 posts were merged into an existing topic: Move all Github issues to Discourse?

Was really surprised to find out even straight up backup errors also produce status 0.

I am checking for a 0 status and running prune, and as you can see, this backup failed, and prune was still run:

[2019-08-13 08:34:23 PDT] Uploaded chunk 66 size 41078410, 20.83MB/s 12:11:00 0.6%
[2019-08-13 08:43:24 PDT] [1] Maximum number of retries reached (backoff: 64, attempts: 15)
[2019-08-13 08:43:24 PDT] Failed to upload the chunk 1580f575fc54c646969e1b3c215011a0ddf7ac57ce9c985e04f05e4cc0c96b2c: googleapi: Error 403: User rate limit exceeded., userRateLimitExceeded
[2019-08-13 08:43:38 PDT] Incomplete snapshot saved to preferences/incomplete
Backup successful, so let's run a prune

@gchen Please change this behavior, it makes no sense in the Linux world.

I find that hard to believe. Are you sure you’re not getting the exit code of one of the “linking” commands?

1 Like

Crap, you’re absolutely right. Apologies.

Here’s the code I was using:

duplicacy -debug backup -stats -threads 8 | ts '[%Y-%m-%d %H:%M:%S %Z]' | tee -a logs/duplicacy-backup.$( date +"%Y%m%d" ).log
if [ $? -eq 0 ]; then
    echo "Backup successful, so let's run a prune"
    duplicacy prune -exclusive -keep 30:365 -keep 7:30 -keep 1:1 | ts '[%Y-%m-%d %H:%M:%S %Z]' | tee -a logs/duplicacy-backup.$( date +"%Y%m%d" ).log

I’ll need to figure out how to get just the return value for duplicacy.

1 Like

Alright, wasn’t too hard: https://unix.stackexchange.com/questions/14270/get-exit-status-of-process-thats-piped-to-another.

duplicacy -debug backup -stats -threads 8 | ts '[%Y-%m-%d %H:%M:%S %Z]' | tee -a logs/duplicacy-backup.$( date +"%Y%m%d" ).log
if [ ${PIPESTATUS[0]} -eq 0 ]; then
    echo "Backup successful, so let's run a prune"
    duplicacy prune -exclusive -keep 30:365 -keep 7:30 -keep 1:1 | ts '[%Y-%m-%d %H:%M:%S %Z]' | tee -a logs/duplicacy-backup.$( date +"%Y%m%d" ).log

This code is working as expected from what I can tell.


Nice solution with the pipestatus!

:d: also has the -log option to add time stamps to the output, which makes the code a bit simpler! Of course you might have other reasons to use ts, or need other filters.

Sinse your solution is for *nux and this thing troubles Windows users as well, here’s how to work around this problem in Windows.
Problem: Original exit code is lost after piping to a command (filter)

For Windows bat files, the simplest, most robust way is probably

  • Save the output of command to a temporary file and save the exit code in a variable
  • Investigate or manipulate the temp file with other commands.
  • Evaluate the variable with the original exit code

Sample bat file:

set Log=logs\duplicacy-backup.%DATE%.log

"C:\Program Files\Duplicacy\duplicacy.exe" -log backup -stats >> %Log%
set Error=%Errorlevel%
type %Log% | find /i "something"
REM Just an example. Find has changed the exitcode but not %Error%
If NOT %Error%!==0! goto BackupError

  echo "Backup successful, so let's run a prune"
  duplicacy -log prune -exclusive -keep 30:365 -keep 7:30 -keep 1:1 >> %Log%
  goto EOF

REM Perform optional error actions here
REM %Error% will still have duplicacys first exit code
REM (%errorlevel% in this case should be from the Find command)
goto :EOF
1 Like