2

Using documentation here: https://grasswiki.osgeo.org/wiki/Working_with_GRASS_without_starting_it_explicitly#Python:_GRASS_GIS_7

I've figured out how to access GRASS modules in Python without explicityly starting GRASS; I set up the environment and run my script in IDLE and all goes well. I'm using GRASS 7 on Linux with Python 2.7.

What I haven't been able to figure out is how to capture the output that GRASS would generate and print to the command console. I would like to print that information to the screen so that I have an indication that things worked. For example, running this command from either the GRASS shell or gui:

gscript.run_command('v.in.ascii', input=pntfile, output='raster_pnts', overwrite=True)

Would print this to the console and do the operation:

(Fri Jan 15 16:17:35 2016)
v.in.ascii --overwrite input=/grass_work/output/points_out.txt output=raster_pnts WARNING: Vector map already exists and will be overwritten Scanning input for column types... Number of columns: 3 Number of rows: 93 Importing points... Populating table... Building topology for vector map ... Registering primitives... 93 primitives registered 93 vertices registered Building areas... 0 areas built 0 isles built Attaching islands... Attaching centroids... Number of nodes: 0 Number of primitives: 93 Number of points: 93 Number of lines: 0 Number of boundaries: 0 Number of centroids: 0 Number of areas: 0 Number of isles: 0 (Fri Jan 15 16:17:36 2016) Command finished (0 sec)

When I execute my Python scripts I also want this to print to the screen, but I can't figure out how to do it. I know how to do this with certain commands where strings are returned as output, like:

region = gscript.parse_command('g.region', flags='p') print region

Would parse and print the region info for me. I know this is different, as I'm trying to capture error messages or progress and not the output itself. I have experimented with some of the examples here:

https://grasswiki.osgeo.org/wiki/GRASS_Python_Scripting_Library

And have tried using start_command instead of run_command to try and capture and print output messages, but I can't get it right (have experimented and searched for several hours).

(I also tried using subprocess.check_output - I've successfully used that for passing input from Python to the GDAL/OGR command line tools and getting the output messages back, but can't get it working here).

PolyGeo
  • 65,136
  • 29
  • 109
  • 338
fdonnelly
  • 473
  • 2
  • 10
  • Is read_command what you're looking for? – user55937 Jan 16 '16 at 22:12
  • I don't think so. For commands that return strings as output, like g.region, read_command returns the result as an unparsed string: http://gis.stackexchange.com/questions/74549/grass-6-5-or-7-0-need-help-with-loop-script. I want to capture any message that's printed or returned to the output window or shell. – fdonnelly Jan 17 '16 at 17:01
  • Essentially what this person was looking to do, except I can't figure out how to do this within a GRASS Python script: http://gis.stackexchange.com/questions/7038/saving-command-history-outputs-to-a-file-grass?rq=1 – fdonnelly Jan 17 '16 at 17:03

1 Answers1

1

I think I understand now. Let me know if this is not what you're looking for.

>>> import subprocess
>>> p = subprocess.Popen(['v.in.ascii', 'input=/home/username/Desktop/temp.txt', 'output=raster_pnts','x=1','y=2','fs=\',\'','--o'],stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> stdoutdata, stderrdata = p.communicate()
>>> print stderrdata
WARNING: Vector map <raster_pnts> already exists and will be overwritten
Scanning input for column types...
Maximum input row length: 5
Maximum number of columns: 2
Minimum number of columns: 2
Importing points...
 100%
Building topology for vector map <raster_pnts>...
Registering primitives...
3 primitives registered
3 vertices registered
Building areas...
 100%
0 areas built
0 isles built
Attaching islands...
Attaching centroids...
 100%
Number of nodes: 3
Number of primitives: 3
Number of points: 3
Number of lines: 0
Number of boundaries: 0
Number of centroids: 0
Number of areas: 0
Number of isles: 0
v.in.ascii complete.

You could also use the start command and redirect stderr:

import subprocess
import grass.script as grass
p = grass.start_command('v.in.ascii',input='temp.txt',output='temp',stderr=subprocess.PIPE)
stdoutdata, stderrdata = p.communicate()
print stderrdata

I'm guessing you didn't have the stderr=subprocess.PIPE as an argument in your call to start_command.

Here's my source using the start command with arguments that are accepted by Popen.

user55937
  • 1,293
  • 11
  • 18
  • Thank you! Your 2nd example was exactly what I was looking for - I also added stdout=subprocess.PIPE to the list of arguments and was able to print both output and errors (v.in.ascii doesn't return any standard output, but I'm running several other processes that do). – fdonnelly Jan 19 '16 at 14:54