Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

exec & return (error) code

600 views
Skip to first unread message

Bert_Paris

unread,
May 20, 2011, 3:25:34 AM5/20/11
to
Hi folks,

I am banging my head on something that looks trivial. No doubt you'll
be able to help me :-)

exec diff.exe .\\v1\\$f1 .\\v2\\$f1 >${f1}_diff.txt

(running under windows XP hence the \\)

Looks simple. It is actually executed in a glob loop and it works as
expected, *but* it stops with a "child process exited abnormally" error
on the first files that are different.
Using -ignorestderr or catch doesn't help (it's not an error caught by
the OS, it is a return code from the diff.exe utility).

Thanks a pile in advance,

Bert


Ralf Fassel

unread,
May 20, 2011, 4:12:50 AM5/20/11
to
* Bert_Paris <do_no...@me.com>

| exec diff.exe .\\v1\\$f1 .\\v2\\$f1 >${f1}_diff.txt
>
| (running under windows XP hence the \\)

You can use / on windows instead of \\, too.

| Looks simple. It is actually executed in a glob loop and it works as
| expected, *but* it stops with a "child process exited abnormally"
| error on the first files that are different.
| Using -ignorestderr or catch doesn't help (it's not an error caught by
| the OS, it is a return code from the diff.exe utility).

You gave the explanation already: 'diff' exits non-zero if differences
are found, but a non-zero exit code is an indication of failure for TCL.

The solution is quite simple:
- catch the exec and inspect the errorCode in case of errors:

if {[catch {exec diff file1 file2 ...} err]} {
switch -- [lindex $::errorCode 0] {
CHILDSTATUS {
# error triggered by non-zero exit status
set status [lindex $::errorCode 2]
# status == 1 => files differ, everything else indicates a
# different error (file not found etc)
}
default {
# other error from 'exec'
}
}
}

HTH
R'

Bert_Paris

unread,
May 20, 2011, 4:28:24 AM5/20/11
to
Unfortunately, this doesn't help me.
As I mentioned, using catch doesn't work, or maybe I don't use it as I
should. The complete code (with catch) is :

foreach f [glob src_v1/*] {
set f1 [file tail $f]
catch [exec diff.exe .\\src_v1\\$f1 ..\\Src\\$f1 >${f1}_diff.txt] err
}

I don't care about the return code at all so I'm not interested in
anything catch would be catching. I just want this script to _not_ stop
with the "child exited..." error.

Any idea ?

Ralf Fassel avait énoncé :

Arjen Markus

unread,
May 20, 2011, 5:22:29 AM5/20/11
to
On 20 mei, 10:28, Bert_Paris <do_not_s...@me.com> wrote:
> Unfortunately, this doesn't help me.
> As I mentioned, using catch doesn't work, or maybe I don't use it as I
> should. The complete code (with catch) is :
>
> foreach f [glob src_v1/*] {
>   set f1   [file tail $f]
>   catch [exec diff.exe .\\src_v1\\$f1 ..\\Src\\$f1 >${f1}_diff.txt] err
>   }
>
> I don't care about the return code at all so I'm not interested in
> anything catch would be catching. I just want this script to _not_ stop
> with the "child exited..." error.
>
> Any idea ?
>
> Ralf Fassel avait énoncé :
>
>
>
> > * Bert_Paris <do_not_s...@me.com>

> >> exec diff.exe .\\v1\\$f1 .\\v2\\$f1 >${f1}_diff.txt
>
> >> (running under windows XP hence the \\)
>
> > You can use / on windows instead of \\, too.
>
> >> Looks simple. It is actually executed in a glob loop and it works as
> >> expected, *but* it stops with a "child process exited abnormally"
> >> error on the first files that are different.
> >> Using -ignorestderr or catch doesn't help (it's not an error caught by
> >> the OS, it is a return code from the diff.exe utility).
>
> > You gave the explanation already: 'diff' exits non-zero if differences
> > are found, but a non-zero exit code is an indication of failure for TCL.
>
> > The solution is quite simple:
> > - catch the exec and inspect the errorCode in case of errors:
>
> >   if {[catch {exec diff file1 file2 ...} err]} {
> >      switch -- [lindex $::errorCode 0] {
> >        CHILDSTATUS {
> >          # error triggered by non-zero exit status
> >          set status [lindex $::errorCode 2]
> >          # status == 1 => files differ, everything else indicates a
> >          # different error (file not found etc)
> >        }
> >        default {
> >          # other error from 'exec'
> >        }
> >      }
> >    }
>
> > HTH
> > R'- Tekst uit oorspronkelijk bericht niet weergeven -
>
> - Tekst uit oorspronkelijk bericht weergeven -

Try:

foreach f [glob src_v1/*] {
set f1 [file tail $f]
catch {
exec diff.exe .\\src_v1\\$f1 ..\\Src\\$f1 >${f1}_diff.txt
} err
}

The way you had it, was wrong: you were catching the _result_ of the
[exec] statement,
due to the square brackets.

Regards,

Arjen

Bert_Paris

unread,
May 20, 2011, 1:21:45 PM5/20/11
to
Thanks !
It was trivial indeed, all my fault.

catch { exec diff.exe .\\v1\\$f1 ..\\v2\\$f1 >${f1}_diff.txt }

_does_ work.

As correctly stated by the 2 OPs, my error was using [] instead of {}
(which doesn't prevent the $ substitution) !

THANKS A PILE !

Bert_Paris wrote :

Andreas Leitgeb

unread,
May 20, 2011, 1:43:32 PM5/20/11
to
Bert_Paris <do_no...@me.com> wrote:
> As correctly stated by the 2 OPs, my error was using [] instead of {}

Indeed. So far so good.

> (which doesn't prevent the $ substitution) !

But, the $ substitution wasn't your problem! It seems like you're
now mixing up [] with "", where $-subst would indeed have been a problem.


Try this simplified but diagnose-enhanced variant of your situation:

proc testcmd {} { puts "called testcmd"; return 42 }
proc testcatch {arg} {
puts "called testcatch with command: >>>$arg<<<"
puts "code: [catch $arg msg]\n retval or error: $msg"
}
testcatch [ testcmd ]
testcatch { testcmd }

# hint: copy&paste the procs en bloc, then the tests line by line.

0 new messages