I 've had a problem executing 'du -sk' command from a 'tclsh' shell.
From my understanding, 'du' command does not give the size of a
directory if the directory does not have a Read or Execute permission.
I changed to a directory which has some subdirectories out of which
some sub-directories do not have Read and Execute permissions.
From UNIX command line i have executed 'du' command.
from the result i found out that the size for the sub-directory
which does not have read and execute permission is not getting
displayed.
Now from UNIX command line i swithced onto a tclshell using 'tclsh'
command
and i tried to execute 'du' command
My problem here is 'du' is not functioning the same way as executed in
unix command line..
instead it is reporting like 'CHILD PROCESS EXITED ABNORMALLY'. I
tried to execute the same from a tcl script executing 'du' command in
catch block of statements.. but still i found the same error caught..
'CHILD PROCESS EXITED ABNORMALLY'..
How do i handle this situation.. Please help me out in this regard.
Thanks in advance..
Ravikanth
You're being hit by the fact that du writes to its stderr when it
reports the access problems. From [exec] manpage:
If any of the commands writes to its standard error file and
that standard error isn't redirected, then exec will
return an error;
Then the accepted optimum is to tell [exec] to be transparent on
stderr (ie routing the child's stderr to tclsh own current stderr, so
that you can see it in real time when it's a terminal for example):
exec du -sk ... >@ stderr
Now, you're not saved yet :-}
Doing so still leaves the post-mortem check in [exec]: at the end of
du's execution, [exec] will still report an error if the exit status
was non-zero, which is notably the case when du has encountered access
problems here and there. Here it is too bad since it happens only at
the end of du's life, well after it has written interesting data to
its output, but Tcl will still report the whole as an error (mixing
the child's stdout and Tcl error message in the error report):
% catch {exec du -sk aaa 2>@ stderr} err
du: cannot read directory `aaa/bbb': Permission denied
1
% puts $err
8 aaa
child process exited abnormally
To solve this second issue, two options:
(1) You know the output format enough to rip off the error message at
the end (that's doable only because du's output is made of whole
lines)
(2) You hide the exit status from Tcl by using a shell:
set x [exec sh -c {du -sk aaa;exit 0} 2>@ stderr]
HTH,
-Alex
As a matter of personal preference, I like this:
set thefile aaa
set x [exec sh -c {du -sk "$0" || true} $thefile 2>@stderr]
This is better because it doesn't do any substituting of the filename
across different quoting schemes and so will handle unusual filenames
correctly (a source of perennial trouble otherwise...)
Donal.
Thanks for this gem Donal !
(I had never realized that sh -c allowed more than 1 arg :-)
-Alex
Guyzzz..!! Thanks a lot for the information provided.
I got more insight into this issue after reading these posts.
> instead it is reporting like 'CHILD PROCESS EXITED ABNORMALLY'.
I don't know how your system implements du. However, on SPARC Solaris
9, du returns a return code of 1 when there is a directory into which
it cannot descends - even though no output is produced, by default,
about that fact. Thus, even though it _looks_ like the command
completed successfully, the return code is different than when all
directories can be read.
Tcl generally treats a non-zero return code as if it was an error/
abnormal exit. You will start getting used to this when using commands
that use return values for some other purpose (say, grep for
instance).
Anyways, you should read up on the catch command and see http://wiki.tcl.tk/catch
for tips on handling these "non-error" errors.