Mombu the Programming Forum

Go Back   Mombu the Programming Forum > Programming > Capture windows command return code to variable in awk script?
User Name
Password
REGISTER NOW! Mark Forums Read




Reply
1 31st October 18:07
External User
 
Posts: 1
Default Capture windows command return code to variable in awk script?



I need to capture the return code of the "which" command in a Windows
command window, so I can check for success. This must be done in an awk
script running with gawk.

I tried using the system command, but apparently the value that is
stored is whether or not the system command succeeded, regardless of
what happened with which. So, if which succeeds, I get 0, and if it
fails I also get 0.

function have_program (name) {
if (match(ENVIRON["COMSPEC"], "command[.]com$")) { # win98
return 0==system("which " name " >NUL");
}
else { # XP or 2000
return 0==system("which " name " 2>&1 >NUL");
}
}


How can I capture the return code for "which" in Windows (XP) in an awk
script?

Thanks,
JP

(more familiar with perl than with awk, and only mildly so)
  Reply With Quote


 


2 31st October 18:08
External User
 
Posts: 1
Default Capture windows command return code to variable in awk script?



I figured out something using getline. I'm still getting a result I
can't explain. Here's a snippet:

function have_program (name) {
code = (("which " name) | getline );
return code;
}

BEGIN {

#Testing part:
value = have_program("programB");
print value;

if (have_program("programA.exe")) {
build_program = "programA";
}
else if (have_program("programB.exe")) {
build_program = "programB";
}
else if (have_program("programC.exe")) {
build_program = "programC";
}

else {
print "pcbuild.awk: Can't find the program " > "/dev/stderr";
exit 1;
}


When I invoke this script, programB is the only one that exists. The
first time have_program is invoked (the "Testing part"), the value of
"code" within "have_program" is 1, and "have_program" returns 1, as I
expect. The second time is different: have_program returns 0 for both
programA and programB, even though the "which" command knows programB
is there (I know that because I saw the "which" stderr spewage for not
finding programA, but not for programB).

Now, if I comment out the "Testing part" and run the script again, when
the "if" chain tests for programB, have_program returns 1 as it should.
I'm quite confused.

Help?
Thanks,
JP
  Reply With Quote
3 31st October 18:08
External User
 
Posts: 1
Default Capture windows command return code to variable in awk script?


Er, I meant to say the second time have_program is invoked, it returns
0 when I expect it to return 1.

And, even better, that led me to figure this out. I thought I only
needed to close the string that is being piped through getline if that
string is a file name, but apparently that's true for command line
strings too. If I add this line before the return in have_program, the
script does what I expect it to:
close("which " name);

Have a good one,
JP
  Reply With Quote
4 31st October 18:08
ed morton
External User
 
Posts: 1
Default Capture windows command return code to variable in awk script?


Please don't top-post. See below.

I meant to say the second time have_program is invoked, it returns

Normally, it's good practice to define a string to hold the full command
name and use that string for both the open and close, e.g.:

function have_program (name, code, cmd, tmp) {
cmd = "which " name
code = (cmd | getline tmp)
close(cmd)
return code;
}

By the way, note the extra unused function arguments to provide local variables.

"code" contains the return code from "getline", not the return code from "which".

When I read this I thought you were looking for the exit code from
"which", but apparently all you actually want is it's output, which is
an easier task. Given that, either save the output in a file then read it back, e.g.:
system("command > file")
getline result < "file"

or use getline from a pipe as you discovered, e.g.:

"command" | getline result
close("command")

or use coprocesses, e.g.:

print "input" |& "command"
"command" |& getline result

Just beware of using getline as it has a ton of caveats (including the
one that led me to use "tmp" as an argument). You really should get the
Gawk book (http://www.oreilly.com/catalog/awkprog3/) if you're going to
be using awk a lot.

Regards,

Ed.
  Reply With Quote
5 31st October 18:08
External User
 
Posts: 1
Default Capture windows command return code to variable in awk script?


[order cleaned up to fix top-posting; my apologies; and un-needed lines
snipped]


Ah, so the return code from "getline" does tell me whether or not
"which" found the command, because when "which" is successful, it
outputs to sdtout, and when it isn't the output goes to stderr.
(guessing.) So "getline" returns a 1 if "which" found the command, and
0 otherwise. This is the behavior I see, anyway.

Thank you for the tip! I will put it to use.

[snip]

Actually, your first read was correct. I do not need to know the
location of a command, just whether or not it is found. I appreciate
the advice; I may be able to use it some day.

Thank you for this pointer as well. At the moment, I'm just a C
programmer trying to fix a broken build environment, and awk is the
best tool for my immediate purpose. Now that I've been introduced to
the language, it's nice to have it in my toolbox.

Have a good one,
JP
  Reply With Quote
6 31st October 18:08
gazelle
External User
 
Posts: 1
Default Capture windows command return code to variable in awk script?


Actually, I think what's really going on here is that getline returns an
immediate EOF (0) if there is no stdout output from the command (which
is the case when the command is "not found"). If there is something to
read, then it returns 1.

I don't think there is any "standard" way using getline to get the exit
value of the command.

But, system works fine for me, using GAWK:

% gawk 'BEGIN {print system("which dslkjfls")}'
1
% gawk 'BEGIN {print system("which ls")}'
/bin/ls
0

Are you sure these aren't the results you would get?
  Reply With Quote
7 31st October 18:08
External User
 
Posts: 1
Default Capture windows command return code to variable in awk script?


Yes, I'm certain. My system call returns 0 whether the command is
present or not. I read in an old post that this is a behavior that is
different between Unix and Windows, and I'm running this on Windows.
(sorry, I can't do much about that)

JP
  Reply With Quote
8 31st October 18:08
gazelle
External User
 
Posts: 1
Default Capture windows command return code to variable in awk script?


Yes, you are right. I looked back at your original post and you did
specify Windows (quite often here, people don't, and the responses tend
to assume Unix unless/until the OP says, "Oh, and I'm running on
Windows...").

Given that you now have a solution using getline (although Cnot for the
reason you originally thought - i.e., you still aren't getting the exit
status of the command), this is now probably moot for you, but I should
also add that this is not strictly speaking a different between Unix and
Windows, but rather a function of what shell you are using (i.e., which
shell is being invoked by GAWK to run system commands). It's a shame
(but not a surprise...) that none of the standard DOS/Windows shells
work right.

There are shells available for DOS/Windows that do preserve the exit
status. They are hard to find, though...

BTW, which version of Windows are you using (the DOS/95/95/ME strain ror
the NT/2K/XP strain) ? The shells in the later do work somewhat better
than those in the former.
  Reply With Quote
9 31st October 18:08
External User
 
Posts: 1
Default Capture windows command return code to variable in awk script?


Win XP.

We do embedded programming using a cross compiler that runs on Windoze.
Awk is part of our standard development environment, which in installed
on all the developer PCs and distributed to our co-dev partners. For
some reason, perl is not. The script will be invoked from within a
makefile.

Here's another, somewhat related, question:
Can I surpress the output of the "which" command to the console while
maintaining the functionality for the script? Right now, every time the
"which" command comes up empty handed, the console shows "which"s
complaint about not finding the command followed by all the environment
path info. It's not critical, but it's annoying.
I've tried variations on ">NUL 2>&1" which I found around, with various
placements in the line "code = (cmd | getline tmp);" but I either get
no change in output or syntax errors that prevent the script from
running. I believe that redirects stdout to NUL and stderr to stdout.

Thanks,
JP
  Reply With Quote
10 31st October 18:08
gazelle
External User
 
Posts: 1
Default Capture windows command return code to variable in awk script?


I think "2>nul" should do the trick (leaving stdout undisturbed).
  Reply With Quote
Reply


Thread Tools
Display Modes




666