GRASS and Shell: Difference between revisions

From GRASS-Wiki
Jump to navigation Jump to search
m (grass7x --> grass78)
 
(20 intermediate revisions by 6 users not shown)
Line 1: Line 1:
It is fairly easy to write a GRASS job as Shell script which launches GRASS, does the operation and cleans up the temporary files.
This page contains information about GRASS GIS' own shell setup and use.  


=== What's this? ===
For information about scripting for GRASS, please refer to the page [http://grasswiki.osgeo.org/wiki/Shell_scripting Shell scripting].


Often it is convenient to automate repeated jobs. GRASS can be controlled via user scripts to facilitate daily work. How to start? Using command line is a kind of writing scripts without saving them - so, you may start to write '''your first script''' by saving the executed commands in a text file (use your preferred editor to do so, ideally save the script file in ASCII format).
== Automated batch jobs: Setting the GRASS environmental variables ==


  IMPORTANT NOTE: if you don't know shell programming and consider to learn it,
'''''Main article: [[Working with GRASS without starting it explicitly]]'''''
  better look at Python (e.g. [[GRASS and Python]]) to not waste time...
 
This section applies to jobs which shall set the entire GRASS environment.
You have to set a couple of variables to enable GRASS command to run from outside GRASS:


== A first GRASS shell script ==
<source lang="bash">
  # Example in bash shell syntax:
  # path to GRASS binaries and libraries:
  export GISBASE=/usr/lib64/grass78
  export PATH=$PATH:$GISBASE/bin:$GISBASE/scripts
  export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$GISBASE/lib
 
  # set PYTHONPATH to include the GRASS Python lib
  if [ ! "$PYTHONPATH" ] ; then
      PYTHONPATH="$GISBASE/etc/python"
  else
      PYTHONPATH="$GISBASE/etc/python:$PYTHONPATH"
  fi
  export PYTHONPATH
  # use process ID (PID) as lock file number:
  export GIS_LOCK=$$
  # settings for graphical output to PNG file (optional)
  export GRASS_PNGFILE=/tmp/grass6output.png
  export GRASS_TRUECOLOR=TRUE
  export GRASS_WIDTH=900
  export GRASS_HEIGHT=1200
  export GRASS_PNG_COMPRESSION=1
  export GRASS_MESSAGE_FORMAT=plain
</source>


Comments should be started with a '#' character. The first line indicates the shell interpreter to be used, here "sh" which is always in the /bin/ directory.
Define a GRASS session with the last used GISDBASE, LOCATION_NAME, and MAPSET


Silly example, run within a GRASS session:


<source lang="bash">
<source lang="bash">
#!/bin/sh
  # path to GRASS settings file
# my first script,
  export GISRC=$HOME/.grassrc7
# copyright, year, Author
</source>


# plot current region settings
Define a GRASS session with a different GISDBASE, LOCATION_NAME, and/or MAPSET
g.region -p


# leave with exit status 0 which means "ok":
<source lang="bash">
exit 0
  # path to GRASS settings file
  export GISRC=/tmp/grass7-${USER}-$GIS_LOCK/gisrc
  # remove any leftover files/folder
  rm -fr /tmp/grass7-${USER}-$GIS_LOCK
  mkdir /tmp/grass7-${USER}-$GIS_LOCK
  export TMPDIR="/tmp/grass7-${USER}-$GIS_LOCK"
  # set GISDBASE, LOCATION_NAME, and/or MAPSET
  echo "GISDBASE: /path/to/some/grassdata" >>$GISRC
  echo "LOCATION_NAME: some_location" >>$GISRC
  echo "MAPSET: some_mapset" >>$GISRC
  # start in text mode
  echo "GRASS_GUI: text" >>$GISRC
</source>
</source>


Save this in a file "myscript.sh" and run it within GRASS GIS from the command line:
The following three settings are only recommended if you will be calling the script from another program - e.g. a PHP web page using system() or exec()


<source lang="bash">
<source lang="bash">
sh myscript.sh
  export HOME=/var/www
  export USER=www-data
  export GROUP=www-data
</source>
</source>


It should print the current region settings, finish, and return to the command line.
Now you can test:


For '''shell debugging''', run instead:
<source lang="bash">
  # this should print the GRASS version used:
  g.version
  # check GISDBASE, LOCATION_NAME, and MAPSET
  g.gisenv
  # other calculations go here ...
</source>
 
If this works, you can launch other GRASS commands. The approach works within Shell scripts and also in the command line terminal.
 
When done, you should cleanup internal tmp files like this:


<source lang="bash">
<source lang="bash">
sh -x myscript.sh
  # run GRASS' cleanup routine
  $GISBASE/etc/clean_temp
  # remove session tmp directory:
  rm -rf /tmp/grass7-${USER}-$GIS_LOCK
</source>
</source>


It will echo every line which helps to identify errors.
'''Changing the prompt:'''


=== Example 1:  d.rast.region (simple) ===
<source lang="bash">
  PS1_BACKUP="$PS1"
  export PS1="GRASS 6> "
</source>


Script to set [[computational region]] to a raster map ($1 is the parameter given to the script, here map name):
Once you are done, you can set it back (see also next hint about unsetting variables):


<source lang="bash">
<source lang="bash">
#!/bin/sh
  export PS1="$PS1_BACKUP"
# Author: me, today; copyright: GPL >= 2
# Purpose: Script to set computational region to a raster map
# Usage: d.rast.region rastermap
 
g.region rast=$1
d.erase
d.rast $1
exit 0
</source>
</source>


Using the script in a "North Carolina" location GRASS 6 session:
'''Unsetting variables after usage:'''


<source lang="bash">
<source lang="bash">
d.mon x0
  Using the "unset VARNAME" command you get rid of it:
sh d.rast.region elev_state_500m
  unset GISBASE
sh d.rast.region lsat7_2002_40
  unset GISRC
  ...
</source>
</source>


=== Example 2:  d.rast.region (improved) ===
=== Example ===


In this example, we assign the first parameter ($1) given to the script (here map name) to a new variable which is easier to understand in the script. Again, the script is setting the computational region to a raster map, but now it says what happens:
* GRASS shell script job to generate a [http://grass.fbk.eu/spearfish/php_grass_earthquakes.php Recent Earthquakes Map] (get the [http://grass.fbk.eu/spearfish/grass_earthquakes.sh grass_earthquakes.sh shell script])


<source lang="bash">
=== Parallel GRASS jobs ===
#!/bin/sh
# Author: me, today; copyright: GPL >= 2
# Purpose: Script to set computational region to a raster map
# Usage: d.rast.region rastermap


# be careful to not have white space in the next line:
See [[Parallel GRASS jobs]] for Grid Engine, PBS etc.
map=$1
g.message message="Setting computational region to map <$map>"
g.region rast=$map
d.erase
d.rast $map
exit 0
</source>


Using the script in a "North Carolina" location GRASS 6 session: see Example 1 above.
=== GRASS Batch jobs ===


=== Example 3:  d.rast.region (improved again) ===
Since GRASS GIS 6.4, there is an alternative method to easily run jobs in GRASS from a collection of commands in a shell script file. Just define the environmental variable GRASS_BATCH_JOB with the shell script file containing GRASS (or whatever) commands, preferably with full path. Then launch GRASS and it will be executed. It is best to launch GRASS in <tt>-text</tt> mode and to provide gisdbase/location/mapset as parameters. The job script needs executable file permissions (<tt>chmod</tt> on Unix). In order to get readable percentage output during the processing (0..2..4... 100%), we set the environment variable GRASS_MESSAGE_FORMAT to "plain":


Here we introduce the variable $0 which contains the program name as well as a test to see if the user specified the map to be shown:
Example:


<source lang="bash">
<source lang="bash">
#!/bin/sh
#### 1) PREPARATION
# Author: me, today; copyright: GPL >= 2
# First we generate a script which contains the command(s) to be executed:
# Purpose: Script to set computational region to a raster map
# for convenience, we save the file in our HOME directory
# Usage: d.rast.region rastermap
## You may use also a text editor for this, here we use the "echo" shell command
 
echo "export GRASS_MESSAGE_FORMAT=plain
# set computational region, here: UTM32N coordinates
g.region n=4900000 s=4800000 w=700000 e=800000 res=100
v.random mymap3000 n=3000
v.out.ogr input=mymap3000 output=mymap3000.shp" > $HOME/my_grassjob.sh


if [ $# -lt 1 ] ; then
# verify the content of the file
  echo "Parameter not defined. Usage"
cat $HOME/my_grassjob.sh
  echo "  $0 rastermap"
  exit 1
fi


map=$1
# make it user executable (this is important, use 'chmod' or via file manager)
g.message message="Setting computational region to map <$map>"
chmod u+x $HOME/my_grassjob.sh
g.region rast=$map
d.erase
d.rast $map
exit 0
</source>


To see how it works, it is interesting to use shell debugging:
# create a directory (may be elsewhere) to hold the location used for processing
mkdir -p $HOME/grassdata


<source lang="bash">
# create new temporary location for the job, exit after creation of this location
d.mon x0
grass78 -c epsg:32632 $HOME/grassdata/mytemploc_utm32n -e
sh -x d.rast.region elev_state_500m
</source>


=== Example 4: Parameter handling ===
#### 2) USING THE BATCH JOB
# define job file as environmental variable
export GRASS_BATCH_JOB="$HOME/my_grassjob.sh"


Assume you want to create a shell script for GRASS that has two parameters (x and y coordinates) in order to calculate the watershed related to this outlet point ({{cmd|r.water.outlet}}). In shell, the variables $1 $2 and so on are the parameters you pass on to the script. So, if you have a script called basin.sh and you type
# now we can use this new location and run the job defined via GRASS_BATCH_JOB
grass78 $HOME/grassdata/mytemploc_utm32n/PERMANENT


<source lang="bash">
#### 3) CLEANUP
sh basin.sh -23.3 -47.7
# switch back to interactive mode, for the next GRASS GIS session
</source>
unset GRASS_BATCH_JOB


the variable $1 will be -23.3 and $2 will be -47.6. So in your script basin.sh you could use the line
# delete temporary location (consider to export results first in your batch job)
rm -rf $HOME/grassdata/mytemploc_utm32n


<source lang="bash">
# Now you can use the resulting SHAPE file "mymap3000.shp" elsewhere.
r.water.outlet drainage="your_map" basin="basin_map" easting=$2 northing=$1
</source>
</source>


Likewise, you could also pass a third parameter for the basin map name, etc.
The grass78 command starts GRASS in the given mapset, executes the contents of the job file and leaves GRASS. Since the normal startup/closure is used, all internal tmp files are properly removed.


However, it is highly recommended to use {{cmd|g.parser}} for the parameter handling. It is much easier and then even the graphical user interface will be autocreated and standard messages appear already translated! You can clone from existing scripts, see [http://trac.osgeo.org/grass/browser/grass/branches/releasebranch_6_4/scripts here] for a series of examples.
Note: The $HOME variable (or the ~ shortcut) cannot be used in the batch job itself since the variables are not available here.


== Using output from GRASS modules in the script ==
==== Example ====


Sometimes you need to use the output of a module for the next step in a script. Most of the GRASS modules which produce numeric output offer a "-g" flag to facilitate the parsing of the results. Along with the "eval" shell function you can reduce the effort of using printed output in the next step to a minimum. The trick is that the equal sign is considered as variable assignment in shell:
* Another set of GRASS shell scripts to run the job to generate another version of the [http://adhoc.osgeo.osuosl.org/grass/alternate_projections/earthquakes_wintri.png Recent Earthquakes Map] (find the setup files in the [https://trac.osgeo.org/grass/browser/grass-promo/tutorials/batch_processing "batch_processing" tutorials section] of the GRASS SVN)


  # North Carolina example
=== Unattended execution ===
  inmap=elevation
  outmap=some_result


Example for common module output:
* {{wikipedia|GNU_Screen}} is another ''extremely'' valuable tool if you need to detatch and leave long-running processes unattended. It is well worth your time to learn how to use it if you run scripts on remote systems. There are many good tutorials on the web.
  g.region rast=$inmap
: Usage:
  r.info -r $inmap
:: Run "screen" in the terminal. You will reach again the command line but now in screen mode. Now start GRASS.  
  min=55.57879
::: - To disconnect from the session press Control-A, Control-D.
  max=156.3299
::: - To list your screens type "screen -ls" (to find it back)
::: - To reconnect with a disconnected screen run "screen -r [identifier]" (the "identifier" you need only if you have several screens running)
:: Enjoy.


Using this in a script:
* Along with the "{{wikipedia|nohup}}" (no hang-up) command you can login to your machine, launch the job and leave the machine again.
  eval `r.info -r $inmap`
The process will continue after you logged off when you start it with nohup:
  r.mapcalc "$outmap = float($inmap) / $max"
        nohup grass64 ~/grassdata/spearfish60/neteler/ &


Verify:
=== Receive a notification when finished ===
  r.info -r $outmap
  min=0.355522472489405
  max=0.999999772928615


== Best practice shell programming ==
Maybe put email notification at the end of 'my_grassjob.sh' using the "mail" or the "mutt" program, for example like this:


There are many books on the subject, and the subject will be subjective to personal preference, but here are some tips from fellow wiki users. For patches submitted to GRASS, please follow the code guidelines set out in the SUBMITTING files in the main dir of the source code.
        echo "Finished at `date`" > /tmp/done.txt && \
 
        EDITOR=touch mutt -s "Job done" \
* try to reach 50% of comments, started with # character (see above). Then you will understand your script even after years
        me@mydomain.org < /tmp/done.txt && rm -f /tmp/done.txt
* add an initial comment about what the script does
* study existing scripts, see [http://trac.osgeo.org/grass/browser/grass/branches/releasebranch_6_4/scripts here] for a series of scripts


or like this:
        mail -s "GRASS job $0 finished" me@mydomain.org <<EOF
          GRASS GIS has finished the batch job $0
        EOF


Error management:
or simply like this:
        echo "GRASS GIS has finished the batch job $0" | mail -s "GRASS job finished" me@mydomain.org


A module which terminates with a fatal error will return a non-zero exit status, so you can use the command with "if", "||", "&&" etc, or test the value of "$?".
== Stupid pet tricks (don't use them!) ==


== Stupid pet tricks ==
Note: This is highly discouraged. Keep fingers off from manually modifying the content of a GRASS GIS mapset (at least don't complain if you break things).


;Quick cd to the MAPSET directory
<strike>;Quick cd to the MAPSET directory
To make a quick little function called 'g.cd' to change into the mapset dir, add this to <tt>~/.grass.bashrc</tt>:
To make a quick little function called 'g.cd' to change into the mapset dir, add this to <tt>~/.grass.bashrc</tt>:


Line 194: Line 233:
   alias g.home='cd `dirname "$HISTFILE"`'
   alias g.home='cd `dirname "$HISTFILE"`'
</source>
</source>
 
</strike>


;Simpler command completion from command history
;Simpler command completion from command history
Line 209: Line 248:


Then you can type a bit of a command and use PgUp and PgDn to cycle through the command history which matches in a way less clumsy that Ctrl-r. Also it tells to make the shell flash on alarm instead of sending a beep to the speaker (making tab-completion compatible with your office mates).
Then you can type a bit of a command and use PgUp and PgDn to cycle through the command history which matches in a way less clumsy that Ctrl-r. Also it tells to make the shell flash on alarm instead of sending a beep to the speaker (making tab-completion compatible with your office mates).
== Automated batch jobs: Setting the GRASS environmental variables ==
This section applies to jobs which shall set the entire GRASS environment.
You have to set a couple of variables to enable GRASS command to run (see ''''GRASS Batch jobs'''' below for a solution when you want to run the GRASS job from outside GRASS):
  # Example in bash shell syntax:
  # path to GRASS binaries and libraries:
  export GISBASE=/usr/local/grass64
  export PATH=$PATH:$GISBASE/bin:$GISBASE/scripts
  export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$GISBASE/lib
  # use process ID (PID) as lock file number:
  export GIS_LOCK=$$
  # settings for graphical output to PNG file (optional)
  export GRASS_PNGFILE=/tmp/grass6output.png
  export GRASS_TRUECOLOR=TRUE
  export GRASS_WIDTH=900
  export GRASS_HEIGHT=1200
  export GRASS_PNG_COMPRESSION=1
  export GRASS_MESSAGE_FORMAT=plain
The following variable defines where the GRASS settings file is stored. This can be anywhere on the system. You could also generate the '.grassrc6' on the fly in your script, even with different name. Just indicate it correctly:
  # path to GRASS settings file
  export GISRC=$HOME/.grassrc6
  # The following three settings are only recommended if you will be calling
  # the script from another program - e.g. a PHP web page using system() or exec()
  export HOME=/var/www
  export USER=www-data
  export GROUP=www-data
Now you can test:
  # this should print the GRASS version used:
  g.version
  # other calculations go here ...
You should cleanup internal tmp files like this:
  # run GRASS' cleanup routine
  $GISBASE/etc/clean_temp
  # remove session tmp directory:
  rm -rf /tmp/grass6-$USER-$GIS_LOCK
If this works, you can launch other GRASS commands. The approach works within Shell scripts and also in the command line terminal.
=== Example ===
* GRASS shell script job to generate a [http://grass.fbk.eu/spearfish/php_grass_earthquakes.php Recent Earthquakes Map] (get the [http://grass.fbk.eu/spearfish/grass_earthquakes.sh grass_earthquakes.sh shell script])
=== Parallel GRASS jobs ===
See [[Parallel GRASS jobs]] for Grid Engine, PBS etc.
=== GRASS Batch jobs ===
There is (now) an alternative method to easily run jobs in GRASS from a collection of commands in a shell script file. Just define the environmental variable GRASS_BATCH_JOB with the shell script file containing GRASS (or whatever) commands, preferably with full path. Then launch GRASS and it will be executed. It is best to launch GRASS in <tt>-text</tt> mode and to provide gisdbase/location/mapset as parameters. The job script needs executable file permissions (<tt>chmod</tt> on Unix).
Example:
chmod u+x $HOME/my_grassjob.sh
export GRASS_BATCH_JOB=$HOME/my_grassjob.sh
grass64 ~/grassdata/spearfish60/neteler/
The grass64 command starts GRASS in the given mapset, executes the contents of the job file and leaves GRASS. Since the normal startup/closure is used, all tmp files are properly removed.
Note: The $HOME variable (or the ~ shortcut) cannot be used in the batch job since the variables are not available here.
To deactivate the batch job mode, run (bash example):
unset GRASS_BATCH_JOB
=== Unattended execution ===
* {{wikipedia|GNU_Screen}} is another ''extremely'' valuable tool if you need to detatch and leave long-running processes unattended. It is well worth your time to learn how to use it if you run scripts on remote systems. There are many good tutorials on the web.
: Usage:
:: Run "screen" in the terminal. You will reach again the command line but now in screen mode. Now start GRASS.
::: - To disconnect from the session press Control-A, Control-D.
::: - To list your screens type "screen -ls" (to find it back)
::: - To reconnect with a disconnected screen run "screen -r [identifier]" (the "identifier" you need only if you have several screens running)
:: Enjoy.
* Along with the "{{wikipedia|nohup}}" (no hang-up) command you can login to your machine, launch the job and leave the machine again.
The process will continue after you logged off when you start it with nohup:
        nohup grass64 ~/grassdata/spearfish60/neteler/ &
=== Receive a notification when finished ===
Maybe put email notification at the end of 'my_grassjob.sh' using the "mail" or the "mutt" program, for example like this:
        echo "Finished at `date`" > /tmp/done.txt && \
        EDITOR=touch mutt -s "Job done" \
        me@mydomain.org < /tmp/done.txt && rm -f /tmp/done.txt
or like this:
        mail -s "GRASS job $0 finished" me@mydomain.org <<EOF
          GRASS GIS has finished the batch job $0
        EOF


== See also ==
== See also ==
Line 330: Line 264:
* [[GRASS and Python]]
* [[GRASS and Python]]
* [[Working with GRASS without starting it explicitly]]
* [[Working with GRASS without starting it explicitly]]
* [[GRASS and windows console]]


[[Category:FAQ]]
[[Category:FAQ]]
[[Category:Scripting]]
[[Category:Scripting]]
[[Category:Linking to other languages]]
[[Category:Linking to other languages]]

Latest revision as of 13:29, 29 March 2021

This page contains information about GRASS GIS' own shell setup and use.

For information about scripting for GRASS, please refer to the page Shell scripting.

Automated batch jobs: Setting the GRASS environmental variables

Main article: Working with GRASS without starting it explicitly

This section applies to jobs which shall set the entire GRASS environment. You have to set a couple of variables to enable GRASS command to run from outside GRASS:

   # Example in bash shell syntax:
 
   # path to GRASS binaries and libraries:
   export GISBASE=/usr/lib64/grass78
 
   export PATH=$PATH:$GISBASE/bin:$GISBASE/scripts
   export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$GISBASE/lib
   
   # set PYTHONPATH to include the GRASS Python lib
   if [ ! "$PYTHONPATH" ] ; then
      PYTHONPATH="$GISBASE/etc/python"
   else
      PYTHONPATH="$GISBASE/etc/python:$PYTHONPATH"
   fi
   export PYTHONPATH
 
   # use process ID (PID) as lock file number:
   export GIS_LOCK=$$
 
   # settings for graphical output to PNG file (optional)
   export GRASS_PNGFILE=/tmp/grass6output.png
   export GRASS_TRUECOLOR=TRUE
   export GRASS_WIDTH=900
   export GRASS_HEIGHT=1200
   export GRASS_PNG_COMPRESSION=1
   export GRASS_MESSAGE_FORMAT=plain

Define a GRASS session with the last used GISDBASE, LOCATION_NAME, and MAPSET


   # path to GRASS settings file
   export GISRC=$HOME/.grassrc7

Define a GRASS session with a different GISDBASE, LOCATION_NAME, and/or MAPSET

   # path to GRASS settings file
   export GISRC=/tmp/grass7-${USER}-$GIS_LOCK/gisrc
   # remove any leftover files/folder
   rm -fr /tmp/grass7-${USER}-$GIS_LOCK
   mkdir /tmp/grass7-${USER}-$GIS_LOCK
   export TMPDIR="/tmp/grass7-${USER}-$GIS_LOCK"
   # set GISDBASE, LOCATION_NAME, and/or MAPSET
   echo "GISDBASE: /path/to/some/grassdata" >>$GISRC
   echo "LOCATION_NAME: some_location" >>$GISRC
   echo "MAPSET: some_mapset" >>$GISRC
   # start in text mode
   echo "GRASS_GUI: text" >>$GISRC

The following three settings are only recommended if you will be calling the script from another program - e.g. a PHP web page using system() or exec()

   export HOME=/var/www
   export USER=www-data
   export GROUP=www-data

Now you can test:

   # this should print the GRASS version used:
   g.version
   # check GISDBASE, LOCATION_NAME, and MAPSET
   g.gisenv
   # other calculations go here ...

If this works, you can launch other GRASS commands. The approach works within Shell scripts and also in the command line terminal.

When done, you should cleanup internal tmp files like this:

   # run GRASS' cleanup routine
   $GISBASE/etc/clean_temp
 
   # remove session tmp directory:
   rm -rf /tmp/grass7-${USER}-$GIS_LOCK

Changing the prompt:

   PS1_BACKUP="$PS1"
   export PS1="GRASS 6> "

Once you are done, you can set it back (see also next hint about unsetting variables):

   export PS1="$PS1_BACKUP"

Unsetting variables after usage:

   Using the "unset VARNAME" command you get rid of it:
   unset GISBASE
   unset GISRC
   ...

Example

Parallel GRASS jobs

See Parallel GRASS jobs for Grid Engine, PBS etc.

GRASS Batch jobs

Since GRASS GIS 6.4, there is an alternative method to easily run jobs in GRASS from a collection of commands in a shell script file. Just define the environmental variable GRASS_BATCH_JOB with the shell script file containing GRASS (or whatever) commands, preferably with full path. Then launch GRASS and it will be executed. It is best to launch GRASS in -text mode and to provide gisdbase/location/mapset as parameters. The job script needs executable file permissions (chmod on Unix). In order to get readable percentage output during the processing (0..2..4... 100%), we set the environment variable GRASS_MESSAGE_FORMAT to "plain":

Example:

#### 1) PREPARATION
# First we generate a script which contains the command(s) to be executed:
# for convenience, we save the file in our HOME directory
## You may use also a text editor for this, here we use the "echo" shell command

echo "export GRASS_MESSAGE_FORMAT=plain
# set computational region, here: UTM32N coordinates
g.region n=4900000 s=4800000 w=700000 e=800000 res=100
v.random mymap3000 n=3000
v.out.ogr input=mymap3000 output=mymap3000.shp" > $HOME/my_grassjob.sh

# verify the content of the file
cat $HOME/my_grassjob.sh

# make it user executable (this is important, use 'chmod' or via file manager)
chmod u+x $HOME/my_grassjob.sh

# create a directory (may be elsewhere) to hold the location used for processing
mkdir -p $HOME/grassdata

# create new temporary location for the job, exit after creation of this location
grass78 -c epsg:32632 $HOME/grassdata/mytemploc_utm32n -e

#### 2) USING THE BATCH JOB
# define job file as environmental variable
export GRASS_BATCH_JOB="$HOME/my_grassjob.sh"

# now we can use this new location and run the job defined via GRASS_BATCH_JOB
grass78 $HOME/grassdata/mytemploc_utm32n/PERMANENT

#### 3) CLEANUP
# switch back to interactive mode, for the next GRASS GIS session
unset GRASS_BATCH_JOB

# delete temporary location (consider to export results first in your batch job)
rm -rf $HOME/grassdata/mytemploc_utm32n

# Now you can use the resulting SHAPE file "mymap3000.shp" elsewhere.

The grass78 command starts GRASS in the given mapset, executes the contents of the job file and leaves GRASS. Since the normal startup/closure is used, all internal tmp files are properly removed.

Note: The $HOME variable (or the ~ shortcut) cannot be used in the batch job itself since the variables are not available here.

Example

Unattended execution

  • GNU_Screen is another extremely valuable tool if you need to detatch and leave long-running processes unattended. It is well worth your time to learn how to use it if you run scripts on remote systems. There are many good tutorials on the web.
Usage:
Run "screen" in the terminal. You will reach again the command line but now in screen mode. Now start GRASS.
- To disconnect from the session press Control-A, Control-D.
- To list your screens type "screen -ls" (to find it back)
- To reconnect with a disconnected screen run "screen -r [identifier]" (the "identifier" you need only if you have several screens running)
Enjoy.
  • Along with the "nohup" (no hang-up) command you can login to your machine, launch the job and leave the machine again.

The process will continue after you logged off when you start it with nohup:

       nohup grass64 ~/grassdata/spearfish60/neteler/ &

Receive a notification when finished

Maybe put email notification at the end of 'my_grassjob.sh' using the "mail" or the "mutt" program, for example like this:

       echo "Finished at `date`" > /tmp/done.txt && \
       EDITOR=touch mutt -s "Job done" \
       me@mydomain.org < /tmp/done.txt && rm -f /tmp/done.txt

or like this:

       mail -s "GRASS job $0 finished" me@mydomain.org <<EOF
         GRASS GIS has finished the batch job $0
       EOF

or simply like this:

       echo "GRASS GIS has finished the batch job $0" | mail -s "GRASS job finished" me@mydomain.org

Stupid pet tricks (don't use them!)

Note: This is highly discouraged. Keep fingers off from manually modifying the content of a GRASS GIS mapset (at least don't complain if you break things).

;Quick cd to the MAPSET directory To make a quick little function called 'g.cd' to change into the mapset dir, add this to ~/.grass.bashrc:

g.cd()
{
  MAPSET=`g.gisenv get=MAPSET`
  LOCATION_NAME=`g.gisenv get=LOCATION_NAME`
  GISDBASE=`g.gisenv get=GISDBASE`
  LOCATION="$GISDBASE/$LOCATION_NAME/$MAPSET"
  cd "$LOCATION/$1"
}

With that you can also do like: "g.cd colr/" to get to the color tables directory, or "g.cd .." to get to the LOCATION directory.

Another method would be

  alias g.home='cd `dirname "$HISTFILE"`'

Simpler command completion from command history

Add this to a file called ~/.inputrc in your home dir:

set prefer-visible-bell

# -------- Bind page up/down wih history search ---------
"\e[5~": history-search-backward
"\e[6~": history-search-forward

Then you can type a bit of a command and use PgUp and PgDn to cycle through the command history which matches in a way less clumsy that Ctrl-r. Also it tells to make the shell flash on alarm instead of sending a beep to the speaker (making tab-completion compatible with your office mates).

See also

Generic Shell script tutorials:

GRASS Shell script tutorials:

Misc: