help for ashell                             (Nikos Askitas)

Capture the stdout of an OS command into stata variables

ashell OS_Command

Description

ashell is to be thought of as "another shell" or as "alternative" or "additional" shell. If you were at some point frustrated to find out that there is no way to capture the output of an OS command (one you submit by using stata's shell command) into a stata variable so that you can reformat it and reuse it or parts of it later then this is the module that solves your problem. It kind of adds to stata's shell command a feature like perl's backticks where you write something like "array = `os_command`" and your array contains the output of os_command.

You use ashell like shell (or instead of it) when you need to reuse the output (or parts thereof) of the command. For example shell ps -ef | wc -l would count the running processes on your system. If you need the number later in your program do {cmd:ashell ps -ef | wc -l} instead and capture the output into stata's r(o1).

More generally if a system command returns x lines of output ashell will place the number of lines into r(no) and the lines of the output itlself into r(o1), r(o2), ... , r(ox). You can then parse them with stata's regex engine and collect the info you need to keep.

Technical note

ashell While writing the module I kept on banging against stata's unusual datatypes. The simplest thing to have done is to return the entire output of a system command into one string and then parse it with a "match and replace regex loop" to collect what you need. This is impossible for many reasons not least of which is str244 (see datatypes). The current implementation is like swishing an arrow through 12 ax-heads.

Examples

On a Windows machine doing:

. ashell "date /T"

should put the current date in r(o1).

On a Solaris machine doing: . ashell "top -b"

should return r(o4) equal to somehing like:

Memory: 512M real, 267M free, 104M swap in use, 750M swap free

To get the amount of free memory you would then need a snippet like this:

. local memline = r(o4) . local m = regexm("`memline'", "[0-9]+[A-Z] swap free")

Now m is 1 if there was a match and the match is in regexr(0). So doing:

. local match = regexr(0)

puts "750M swap free" into match. Finally doing:

. local free = regexr("`match'", " swap free", "")

results in free being equal to: 750M.

Similarly on a MacOS X machine doing

. ashell top -l1 -n1 | grep PhysMem

should return r(o1) looking something like this:

PhysMem: 70.6M wired, 108M active, 145M inactive, 324M used, 699M free

Doing

. ashell date or . ashell date +%Y%m%d

sets r(o1) to the date in the form Tue Apr 10 07:11:19 CEST 2007 or YYYYMMDD respectively.

Author

Dr Nikos Askitas, IZA, Bonn, Germany. Email: nikos@@iza.org