0

I have 2 procs which are called one after the other. The first proc uses the diff functionality and creates file.txt. The proc right after compresses the file. The issue is that when I run the script, the file.txt is empty. When I comment out the compressing proc, the file has the differences printed in it. I believe this is caused because the second proc does not wait for the first proc to finish.

create_difference "file1" "file2" 
create_compress "path"

The order of procedure calls above produce an empty file.txt.gz

create_difference "file1" "file2" 
#create_compress "path"

The order of procedure calls above create an expected difference file. Within the procs, I tried adding a return statement (to return 1), this did not make a difference.

I tried using the wait command as in Waiting for background processes to finish before exiting script:

create_difference "file1" "file2" 
wait
create_compress "path"

However the script hangs at that point.

Proc for creating the differences: tcl: capture output from "exec diff" which returned non-zero

set dso1 [open file.txt w]
set status [catch {exec diff $file1 $file2} result]
if {$status == 0} {
   puts $dso1 "$file1 and $file2 are identical"
} elseif {$status == 1} {
   puts $dso1 "** $file1 and $file2 are different **"
   puts $dso1 "***************************************************************************"
   puts $dso1 ""
   puts $dso1 $result
   puts $dso1 ""
   puts $dso1 "***************************************************************************"
} else {
   puts stderr "** diff exited with status $status **"
   puts stderr "***********************************************************************"
   puts stderr $result
   puts stderr "***********************************************************************"
}

The proc for compressing the files:

proc create_compress  {thepath} {
        catch {exec find ${thepath}/. -type f -exec gzip "{}" \; } result
        #return 1
}

There are some other files in there which need compressing, which is why I compress every file within the folder, given the path of the folder. The other files do compress as intended.

I ran some more testing on it. It seems that even after the diff proc has been called and finished, the differences are written to file.txt ONLY after the script has ended. Right up to the end of the script, the Differences file is created, but it's size is 0.

Community
  • 1
  • 1
user2883071
  • 960
  • 1
  • 20
  • 50
  • Run your program again after creating differences but this time reverse the comments so that create_compress runs. Is the file still blank or did the compression work? – wolfhammer Mar 30 '15 at 15:04
  • How do you use diff? Can you show how you call diff from Tcl? – Johannes Kuhn Mar 30 '15 at 15:05
  • I should edit my post, the file is compressed (compression works), however it is empty – user2883071 Mar 30 '15 at 15:05
  • This is a syntax error: `puts $dso1 stderr "** diff exited with status $status **"` -- wrong number of arguments for `puts` – glenn jackman Mar 30 '15 at 15:29
  • You have no background processes, so remove `wait` – glenn jackman Mar 30 '15 at 15:29
  • I will fix the stderr error, thanks. Regarding `wait`, I was showing what I was trying out. My thoughts were that the diff utility would spawn a back-ground process, for which I would wait. However, as stated in the question, the script hangs at that point – user2883071 Mar 30 '15 at 15:32

2 Answers2

1

The reason why nothing was being written to the Difference file is because it was not closed. In my create_diff proc, I forgot to include the command: close $dso1 Therefore once the script finished running, only then it would write to the file. However, right after the diff proc, I compress the files, and since it cannot write to a compressed file, the file would be empty.

Tldr; I did not close the file I was writing the differences to.

user2883071
  • 960
  • 1
  • 20
  • 50
  • That means that what was being written was small, less than the default buffer size… – Donal Fellows Mar 30 '15 at 19:44
  • So you mean to say that if I was writing many differences (enough to fill the buffer up), even if I did not close the file, it would write out the buffer to reset it? – user2883071 Mar 30 '15 at 19:46
  • 1
    I think that if the contents were larger, the file would not be zero size, but it would probably be inomplete. Lesson: always close file handles you open. – glenn jackman Mar 30 '15 at 20:44
0
set status [catch {exec diff $file1 $file2} result]

"status" is not diff's exit status, it is catch's exit status. Not the same. To get diff's exit status:

if {$status == 1} {
    set err_type [lindex $::errorCode 0]
    if {$err_type eq "NONE"} {
        # diff exited with exit status 0 but printed something
        # to stderr
    } elseif {$err_type eq "CHILDSTATUS"} {
        # diff returned non-zero status
        set diff_exit_status [lindex $::errorCode end]
        if {$diff_exit_status == 1} {
            # diff results in $result
        } else {
            # diff had some kind of trouble
        }
    }
}
glenn jackman
  • 238,783
  • 38
  • 220
  • 352
  • I get the error: `cant read "errorCode": no such variable`. However, would this solve the initial issue where the file.txt.gz files is empty? – user2883071 Mar 30 '15 at 15:55
  • Ah, this is in a proc. Use `$::errorCode` to get the global variable. – glenn jackman Mar 30 '15 at 16:06
  • You have said that the proc to create the diff is working, and the compressed file is empty after you run the compress proc. Where do you think the error is most likely to be? – glenn jackman Mar 30 '15 at 16:07
  • Yes, but as mentioned in my question, when I run the diff proc without running the compress proc, it works! When I run the diff proc and comment out the compress proc, my diff file has the expected differences – user2883071 Mar 30 '15 at 17:28
  • OK. And then you run the compress proc and see that "file.txt.gz" is empty. Which proc do you think is responsible for that? I would think it's the compress proc. Maybe you should show us what that proc does, hmm? – glenn jackman Mar 30 '15 at 17:41
  • Posted, could it be that the compress proc is called before the differences file can be generated? – user2883071 Mar 30 '15 at 17:50
  • The code you've shown does not do anything in the background. Are you running an event loop (i.e. Tk) ? – glenn jackman Mar 30 '15 at 17:55
  • No I am not.. Or I do not think so. Would the proc create_compress wait for create_difference to finish before it runs? – user2883071 Mar 30 '15 at 17:59
  • Please expand on where and how I have. Unfortunately I do not understand where/what the event loop is – user2883071 Mar 30 '15 at 19:18