Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

exec can't find files

Status
Not open for further replies.

gcooper

Programmer
Aug 29, 2002
16
CH
When I execute:

set tempString [exec ls -l $file_list]

where file list has the value "file1 file2 file3 file4"
and I have previously done a cd to the directory containing file1 file2 file3 file4 and the permissions on the directory and files is 777.

I get:

Error: file1 file2 file3 file4 not found

Any ideas?

Thanks,

Gary Cooper
 
Yes I've an idea.
You're exec'ing a ls -l on a file whose name is "file1 file2 file3 file4", whith embedded spaces. If you want a round of deferentiation before the exec you need to use eval:
Code:
  set tempString [eval exec ls -l $file_list]
What happened?
The script [exec ls -l $file_list] is not converted to a string before evaled but each argument (with its boundaries) is passed to exec: ls, -l and then the value of file_list as a whole.
By contrast:
Code:
  set exec "exec ls -l $file_list"
  set tempString [eval $exec]
1/ transforms the list of args in a string
2/ interprets the string as a list of args, following the space boundaries.
Then, the exec evaled is now:
Code:
  exec ls -l file1 file2 file3 file4
This is what does eval: it concats all args before evaling.

HTH

ulis
 
Thanks for the reply Ulis.

OK, in the example I gave (i.e. the 'ls' command) it works OK. What I was doing was using 'ls' to help debug another problem. The technique you suggest doesn't appear to fix my original problem, which is this.

The command causing the problem is grep, not ls.
So what I've done is:
set execCmd "exec grep -l $searchTag $file_list"
set tempString [eval $execCmd]

It seems to set tempString to:

exec grep -l {XVE65651} file1 file2 file3 file4 etc.
then bomb out with the message:
Error: child process exited abnormally

When executed manually as a ksh command in the same directory, it does just what I expect - i.e. returns a null string (there are no occurances of the string XVE65651 in any of the files).

Regards,

Gary
 
Not easy to answer another question that the one you asked.
I'll try.

The
Code:
exec
command returns (among other cases) an error if stderr is written. To catch this error you need to
Code:
catch
it and display the error message:
Code:
  set execCmd "exec grep -l $searchTag $file_list"
  catch { eval $execCmd } result
  puts $result
The
Code:
catch
command gets two results:
- the return code of the command evaled (see below),
- the returned string.
If an error occurs, the returned string is replaced by the error message.

If you want to be more error prone you should try this:
Code:
  set execCmd "exec grep -l $searchTag $file_list"
  set rc [catch { eval $execCmd } result]
  if {$rc} { puts stderr "error:\n$result" }   else { puts $result }
More on exec at: More on catch at:
HTH

ulis
 
As a side note, once you start working with eval, you have to be really careful managing your arguments. In your above example, let's assume that:

Code:
set searchTag "some string"
set file_list "file1.txt file2.txt"

Now, the result of the string concatenation of the following line:

Code:
set execCmd "exec grep -l $searchTag $file_list"

is:

Code:
exec grep -l some string file1.txt file2.txt

Not quite what we had in mind. The argument "some string" got split into 2 separate arguments because the string concatenation.

So, in a case like this, it's by far safest to use Tcl list commands to help us build up our command to evaluate. In this case:

[tt]eval [ignore][list[/ignore] exec grep -l $searchTag[ignore]][/ignore] $file_list[/tt]

Now, when eval concatentates its arguments together, the value of searchTag retains its identity as a single argument, but the "unprotected" value of file_list gets expanded.

There are a few other quirks to watch out for. You can find out more about them on the Tcl'ers Wiki ( starting with the page "eval,"
NOTE: This is going to become much easier as of Tcl 8.5, with the first new addition to Tcl syntax in many years. Tcl will gain a [tt]{}[/tt] notation, which, when used as the first 2 characters of an argument, mark that argument for expansion into separate arguments. Thus, in Tcl 8.5 or later, you'll be able to do simply:

[tt]exec grep -l $searchTag {}$file_list[/tt]

- Ken Jones, President, ken@avia-training.com
Avia Training and Consulting, 866-TCL-HELP (866-825-4357) US Toll free
415-643-8692 Voice
415-643-8697 Fax
 
Hi Guys,

Thanks for the suggestions. I've had a play around with catch. Also I note what Ken suggests about using the list command...

But guess what? I think I've found what's causing the problem. Have a look near the beginning of
It was actually Ken that unwittingly pointed me in the right direction - through the other posting.

In this particular instance, the grep command that I'm exec'ing is returning no matches (which is what I expect) and this results in a return value of 1 (no match found), which according to Ken causes the string "child process exited abnormally" to be appended to stdout.

That's OK insofar as I now know what the problem is, but how to fix it? Checking for the returned value "child process exited abnormally" would probably work, but it isn't very elegant is it?

Any suggestions?

Thanks,

Gary
 
Well, here is an area where Tcl doesn't make it as easy as it could. The exit code of an exec'ed program is available, but not in a straightforward manner.

When an error occurs in Tcl, it stores values in a couple of pre-defined global variables. One of those is errorInfo, which gets a stack track of the Tcl commands executing at the time of the error. The other is errorCode, which is "set to hold additional information about the error in a form that is easy to process with programs" -- at least according to the tclvars reference page. The value of errorCode is a list, whose elements depend on the type of error that occurred.

When a child process exits with a non-zero exit code, the value of errorCode contains 3 elements: the string "CHILDSTATUS", the process ID of the child process, and the exit code. On the Tcl'ers Wiki ( the "exec" page, has an excellent example from Kevin Kenny showing how you can handle all the permutations and combinations of child process termination.

Another possibility, if it's an option for you, is to use the bgexec command from the BLT extension. It has some really nice features for dealing with external programs, including an extremely simple method of getting the program's exit code. You can find out more information at "bgexec," and "BLT,"
- Ken Jones, President, ken@avia-training.com
Avia Training and Consulting, 866-TCL-HELP (866-825-4357) US Toll free
415-643-8692 Voice
415-643-8697 Fax
 
Hi gcooper

Just happy New Year's Message.


Lupco.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top