2

I have a script file that uses rsync for backup, then compares the two directory trees using diff. diff seems to find all the differences correctly - it matches what WinMerge finds. But when there are file differences found, all lines after the diff line in the script file appear to be ignored, and the script file returns to the Cygwin prompt.

The test directory is 23 folders, with 100 files totaling 40 MB. The code snippet below, together with a set of test directories, is enough to re-create the problem. My Cygwin install is up to date (Cygwin setup v2.932, diffutils v3.10-1, no installs pending).

...
echo -e "Running diff...\r\n"
diff -qr /cygdrive/d/Data/Tools/Scripts/ /cygdrive/e/Backups/Data/Tools/Scripts
return_code=$?
echo "Return code:  ${return_code}"
...

When there are no differences (using subset of test directory), the return code output line appears correctly.

Running diff...

Return code:  0

Admin@PC0 /cygdrive/d/Data/Tools/scripts/backups
$

But when there are file differences, nothing is output after the last listed difference, and the Cygwin prompt returns. The return code correctly shows 1, for at least one difference found.

Running diff...

Only in /cygdrive/d/Data/Tools/Scripts/: Cygwin-diff.txt
Files /cygdrive/d/Data/Tools/Scripts/backups/Backup_Notes.txt and /cygdrive/e/Backups/Data/Tools/Scripts/backups/Backup_Notes.txt differ
Files /cygdrive/d/Data/Tools/Scripts/backups/backup.sh and /cygdrive/e/Backups/Data/Tools/Scripts/backups/backup.sh differ
Only in /cygdrive/d/Data/Tools/Scripts/backups: bx.sh

Admin@PC0 /cygdrive/d/Data/Tools/scripts/backups
$ echo $?
1

In the actual script, there are a number of echo statements after the "Return code" line, none of which show up when the return code is 1.

Any ideas?

--- edit 2024-06-05 ---

Thanks to @G-Man Says 'Reinstate Monica', his item 1. I put in

set -euo pipefail

into the script in my very early days with bash several years ago, to fix a problem with a blank argument $1 causing an 'unbound variable' error. I wanted to handle it in the script itself with a syntax message. Removing the 'e' (Exit immediately if a command exits with a non-zero status) fixed the problem here. I obviously need to look at the rest of this line more closely. If you were to repost as an answer I would select it as the solution. Item 2 echo A; false; echo B echoes 'A', then exits the script, with 'set -e' still in place, but works with 'B' output on the following line when 'set -e' is removed. This is a nice, quick, easy test for this condition.

@petitradisgris I am using bash. Your sample code caused an exit after 'Running diff...' when 'set -e' was still in use. Without it, it output 'a: ' before the start of diff's differences, and did not output anything for '$a'. But it did cause the diff return code to be '0' when it should have been '1'.

--- edit 2024-06-29 ---

@user1934428 I wanted its behavior initially, or thought I did, when first writing the script, which at that point only used rsync. Later, I realized rsync was missing a few changed files when those files were in the destination path, as they were newer. I added diff to catch them, without realizing (& not checking) what return codes diff used on success, and how that would affect 'set -e'.

2
  • 2
    (1) Does your script contain set -e?  (2) If you put echo A; false; echo B in the script, what do you get? Commented Jun 5 at 0:58
  • I wonder why you have set the -e option in the first place, if you don't want its behaviour.... Commented Jun 17 at 13:49

1 Answer 1

0

Which interpreter are you using ? bash or sh ?

In all cases, try this: It catch your potential faulty command into a variable (a for instance), while keeping a return code ($?) coherent to your diff success or not. Of course the commannd output is stored in the $a variable, and may be displayed after (with echo command). This is purely "voodoo" (i agree with the comment XD), but this may help keeping the script running even if diff encunter sme weird fails.

#!/bin/bash
...
echo -e "Running diff...\r\n"
a=$(diff -qr /cygdrive/d/Data/Tools/Scripts/ /cygdrive/e/Backups/Data/Tools/Scripts)
return_code="$?"
echo "$a"
echo "Return code:  ${return_code}"
2
  • 1
    Why might it help? Without a hypothesis, "try this" is just voodoo. Commented Jun 5 at 3:59
  • I agree. it is voodoo, but as the computing world is voodoo too, sometimes voodoo helps ^^ Commented Jun 8 at 17:00

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .