[GRASSLIST:603] Re: How to Run GRASS modules at bash prompt
Benjamin Ducke
benjamin.ducke at ufg.uni-kiel.de
Thu Apr 6 09:39:38 EDT 2006
OK, I hacked up a little wrapper script that allows you to remotely
run GRASS commands in shell scripts.
I have attached it to this email.
What you do is:
chmod u+x grass-remote
./grass-remote GRASSDB/LOCATION/MAPSET myscript.bash
where GRASSDB/LOCATION/MAPSET is the full path to your GRASS 6 mapset.
You specify the shell script to run as second parameter.
In this case, myscript.bash could contain arbitrary GRASS commands like:
#!/bin/bash
g.list rast
g.list vect
...
needless to say that interactive modules will block the script until
the user finishes them.
You need to have GRASS 6 fully installed on your system to make this work.
Hope this helps,
Benjamin
Nagesh Bhatkar wrote:
> Hello Benjamin,
>
> Thanks for writing back and dropping in your Suggestion.
> I have installed the Entire GRASS 6.0.1 package on my system since i
> have being using GRASS extensively since
> a long time to interpolate data and carry out digitization . I agree
> with you that GRASS 6.1 is a tiny total of 72 MB in modern day era.
> I wanted to use the GRASS commands at the bash prompt. Was looking if
> anyone could give me suggestions as to how i could make that possible.
> Am aware thats its an ardous task but might as well give it a try.
> Earlier i read in the GRASSLIST archives, one of the GRASS users asking
> for the same.
>
>
>
>
> Regards
>
> Nagesh
>
>
>
>
>
>
>
> Benjamin Ducke wrote:
>
>> Nagesh,
>>
>> GRASS 6.1.cvs consumes a tiny total of ca. 72 MB on your hard disk
>> drive. With 320 GB disks costing around 150$,
>> are you sure it will be worth the trouble figuring all this out
>> to save a few megabytes? Won't it be easier to convince your
>> boss to just install GRASS?
>> Once that is done, it is easy to write scripts that start a
>> GRASS shell session, then carry out whatever action you want
>> them to.
>>
>> Best,
>>
>> Benjamin
>>
>> Nagesh Bhatkar wrote:
>>
>>>
>>>
>>> Dear GRASS users,
>>>
>>> One of my colleagues wanted to edit the islands out. I suggested him
>>> to use GRASS to edit the islands (d.rast.edit). But he didnt want me
>>> to install the entire GRASS because it
>>> would result in unneccesary consumption of memory as he wanted to use
>>> only one module of GRASS and didnt want other modules. So he asked me
>>> if i could install only the GRASS modules , libraries , which were
>>> needed by the d.rast.edit module which could work outside the GRASS
>>> enviroment at the bash prompt.
>>>
>>> I modified the existing d.rast.edit module to delete insignificant
>>> islands(in the relative sense)
>>> which were causing some errors in the model we were running. By this
>>> module , Onclick anywhere,
>>> determines if its a island and if it is gives the option to delete
>>> the entire island i.e set as ocean instead of editing each individual
>>> cell out.
>>>
>>> I wanted to know if i cud use GRASS modules at bash command prompt.
>>> I went through the GRASS SWIG/PERL implementation grass_warp.c .
>>> But didnt quiet understand how i could implement it.
>>> I have read and understood all the makefiles in
>>> ~/grass-6.0.1/include/Make/ and the init.sh file.
>>> kindly drop in suggestions if using GRASS modules at bash prompt is
>>> possible and what i need to
>>> do to accomplish that.
>>>
>>>
>>>
>>> Nagesh
>>>
>>>
>>>
>>> <http://mpa.itc.it/markus/grass61progman/swig/grass__wrap_8c.html>
>>>
>>>
>>>
>>
>
>
>
--
Benjamin Ducke, M.A.
Archäoinformatik
(Archaeo-Information Science)
Institut für Ur- und Frühgeschichte
(Institute of Archaeology)
Christian-Albrechts-Universität zu Kiel
Johanna-Mestorf-Straße 2-6
D 24098 Kiel
Germany
Tel.: ++49 (0)431 880-3378 / -3379
Fax : ++49 (0)431 880-7300
www.uni-kiel.de/ufg
-------------- next part --------------
trap "echo 'User break!' ; exit" 2 3 9 15
# Set the GISBASE variable
GISBASE=/usr/local/grass-6.1.cvs
export GISBASE
# Set the GRASS_PERL variable
GRASS_PERL=/usr/bin/perl
export GRASS_PERL
# Set GRASS version number for R interface etc (must be an env_var for MS-Windows)
GRASS_VERSION="6.1.cvs"
export GRASS_VERSION
# Get the command name
CMD_NAME=grass61
# Go through the command line options
for i in "$@" ; do
# Use a case to check the command line options
case "$i" in
# Check if the user asked for the version
-v|--version)
cat "$GISBASE/etc/license"
exit
;;
# Check if the user asked for help
help|-h|-help|--help)
echo "Usage:"
echo " $CMD_NAME [-h | -help | --help] <GISDBASE>/<LOCATION_NAME>/<MAPSET> "
echo
echo "Flags:"
echo " -h or -help or --help print this help message"
echo
echo "Parameters:"
echo " GISDBASE initial database"
echo " LOCATION_NAME initial location"
echo " MAPSET initial mapset"
echo
echo " GISDBASE/LOCATION_NAME/MAPSET fully qualified initial LOCATION directory"
echo
echo " GRASS_ADDON_PATH set additional path(s) to local GRASS modules"
exit
;;
esac
done
# Set the GIS_LOCK variable to current process id
GIS_LOCK=$$
export GIS_LOCK
# Set the global grassrc file
GISRCRC="$HOME/.grassrc6"
export GISRCRC
# Set the session grassrc file
USER="`whoami`"
## use TMPDIR if it exists, otherwise /tmp
#tmp=${TMPDIR-/tmp}
#tmp="$tmp/grass6-$USER-$GIS_LOCK"
tmp=/tmp/grass6-$USER-$GIS_LOCK
(umask 077 && mkdir "$tmp") || {
echo "Cannot create temporary directory! Exiting." 1>&2
exit 1
}
GISRC="$tmp/gisrc"
export GISRC
# remove invalid GISRC file to avoid disturbing error messages:
cat "$GISRCRC" 2>/dev/null| grep UNKNOWN >/dev/null
if [ $? -eq 0 ] ; then
rm -f "$GISRCRC"
fi
# Copy the global grassrc file to the session grassrc file
if [ -f "$GISRCRC" ] ; then
cp "$GISRCRC" "$GISRC"
if [ $? -eq 1 ] ; then
echo "Cannot copy '$GISRCRC' to '$GISRC'"
exit
fi
fi
# Copy global grassrc file to session grassrc
# At this point the GRASS user interface variable has been set from the
# command line, been set from an external environment variable, or is
# not set. So we check if it is not set
if [ ! "$GRASS_GUI" ] ; then
# Check for a reference to the GRASS user interface in the grassrc file
if [ -f "$GISRC" ] ; then
GRASS_GUI=`awk '/GRASS_GUI/ {print $2}' "$GISRC"`
fi
# Set the GRASS user interface to the default if needed - currently tcltk
if [ ! "$GRASS_GUI" ] ; then
GRASS_GUI="tcltk"
fi
fi
# Export the user interface variable
export GRASS_GUI
# Set PATH to GRASS bin, ETC to GRASS etc
ETC=$GISBASE/etc
if [ "$LC_ALL" ] ; then
LCL=`echo "$LC_ALL" | sed 's/\(..\)\(.*\)/\1/'`
elif [ "$LC_MESSAGES" ] ; then
LCL=`echo "$LC_MESSAGES" | sed 's/\(..\)\(.*\)/\1/'`
else
LCL=`echo "$LANG" | sed 's/\(..\)\(.*\)/\1/'`
fi
PATH=$GISBASE/bin:$GISBASE/scripts:$GRASS_ADDON_PATH:$PATH
export PATH
# Set LD_LIBRARY_PATH to find GRASS shared libraries
if [ ! "$LD_LIBRARY_PATH" ] ; then
LD_LIBRARY_PATH=$GISBASE/lib
else
LD_LIBRARY_PATH=$GISBASE/lib:$LD_LIBRARY_PATH
fi
export LD_LIBRARY_PATH
# Additional copy of variable to use with grass-run.sh
GRASS_LD_LIBRARY_PATH=$LD_LIBRARY_PATH
export GRASS_LD_LIBRARY_PATH
# Once the new environment system is committed we can delete these lines
# Export the PAGER environment variable for those who have it set
if [ "$PAGER" ] ; then
export PAGER
fi
# Set some environment variables if they are not set
if [ ! "$GRASS_PAGER" ] ; then
if [ -x /bin/more ] || [ -x /usr/bin/more ] ; then
GRASS_PAGER=more
else
GRASS_PAGER=less
fi
export GRASS_PAGER
fi
# Set up tcltk and wish environment
# with options for aqua tcltk with Mac OSX
if [ ! "$GRASS_TCLSH" ] ; then
if [ "$HOSTTYPE" = "macintosh" ] ; then
if [ -d "/usr/local/grasslib" ]; then
GRASS_TCLSH=/usr/local/grasslib/bin/tclsh
else
GRASS_TCLSH=tclsh
fi
else
GRASS_TCLSH=tclsh
fi
export GRASS_TCLSH
fi
#WISH_OS=`echo 'puts $tcl_platform(platform) ; exit 0' | wish`
if [ ! "$GRASS_WISH" ] ; then
if [ "$HOSTTYPE" = "macintosh" ] ; then
if [ "$osxaqua" ] ; then
if [ -d "/usr/local/grasslib/bin/Grass.app" ] ; then
GRASS_WISH=/usr/local/grasslib/bin/Grass.app/Contents/MacOS/Grass
else
GRASS_WISH=/usr/bin/wish
fi
export osxaqua
elif [ -d "/usr/local/grasslib" ] ; then
GRASS_WISH=/usr/local/grasslib/bin/wish
else
#force X11 tcl on Mac without grasslib directory:
GRASS_WISH=/usr/bin/wish
fi
else
GRASS_WISH=wish
fi
fi
export GRASS_WISH
CYGWIN=`uname | grep CYGWIN`
if [ ! "$GRASS_HTML_BROWSER" ] ; then
for i in `echo "$PATH" | sed 's/^:/.:/
s/::/:.:/g
s/:$/:./
s/:/ /g'`
do
if [ -f "$i/htmlview" ] ; then
GRASS_HTML_BROWSER=htmlview
break
elif [ -f "$i/konqueror" ] ; then
GRASS_HTML_BROWSER=konqueror
break
elif [ -f "$i/mozilla" ] ; then
GRASS_HTML_BROWSER=mozilla
break
elif [ -f "$i/mozilla-firefox" ] ; then
GRASS_HTML_BROWSER=mozilla-firefox
break
elif [ -f "$i/opera" ] ; then
GRASS_HTML_BROWSER=opera
break
elif [ -f "$i/netscape" ] ; then
GRASS_HTML_BROWSER=netscape
break
elif [ "$HOSTTYPE" = "macintosh" -o "$HOSTTYPE" = "powermac" -o "$HOSTTYPE" = "powerpc" ] ; then
GRASS_HTML_BROWSER=open
break
elif [ "$HOSTTYPE" = "arm" ] ; then
GRASS_HTML_BROWSER=dillo
break
elif [ "$HOSTTYPE" = "arm" ] ; then
GRASS_HTML_BROWSER=dillo2
break
elif [ "$CYGWIN" ] ; then
iexplore="$SYSTEMDRIVE/Program Files/Internet Explorer/iexplore.exe"
if [ -f "$iexplore" ] ; then
GRASS_HTML_BROWSER=$iexplore
else
GRASS_HTML_BROWSER="iexplore"
fi
break
fi
done
fi
if [ ! "$GRASS_HTML_BROWSER" ] ; then
echo "Searching for web browser, but neither konqueror, nor mozilla, opera, netscape found."
# so we set konqueror, though, to make lib/gis/parser.c happy:
GRASS_HTML_BROWSER=konqueror
fi
export GRASS_HTML_BROWSER
#predefine monitor size for certain architectures
if [ "$HOSTTYPE" = "arm" ] ; then
#small monitor on ARM (iPAQ, zaurus... etc)
GRASS_HEIGHT=320
GRASS_WIDTH=240
export GRASS_HEIGHT GRASS_WIDTH
fi
if [ ! "$GRASS_GNUPLOT" ] ; then
GRASS_GNUPLOT="gnuplot -persist"
export GRASS_GNUPLOT
fi
# First time user - GISRC is defined in the GRASS script
if [ ! -f "$GISRC" ] ; then
if [ ! -f "$GISBASE/locale/$LCL/etc/grass_intro" ] ; then
cat "$ETC/grass_intro"
else
cat "$GISBASE/locale/$LCL/etc/grass_intro"
fi
echo
echo "Hit RETURN to continue"
read ans
#for convenience, define pwd as GISDBASE:
echo "GISDBASE: `pwd`" > "$GISRC"
echo 'LOCATION_NAME: <UNKNOWN>' >> "$GISRC"
echo 'MAPSET: <UNKNOWN>' >> "$GISRC"
# This is a hack for not having a good initial gui - should be removed
# with next version of initialization gui
#GRASS_GUI="text"
else
echo "Cleaning up temporary files....."
("$ETC/clean_temp" > /dev/null &)
fi
echo "Starting GRASS ..."
# Check if we are running X windows by checking the DISPLAY variable
if [ "$DISPLAY" ] ; then
# Check if we need to find wish
if [ "$GRASS_GUI" = "tcltk" ] ; then
# Check if wish is working properly
echo 'exit 0' | "$GRASS_WISH" >/dev/null 2>&1
if [ "$?" = 0 ] ; then
# Set the tcltkgrass base directory
TCLTKGRASSBASE="$ETC"
export TCLTKGRASSBASE
else
# Wish was not found - switch to text interface mode
echo
echo "WARNING: The wish command does not work as expected!"
echo "Please check your GRASS_WISH environment variable."
echo "Use the -help option for details."
echo "Switching to text based interface mode."
echo
echo "Hit RETURN to continue."
read ans
GRASS_GUI="text"
fi
fi
else
# Display a message if a graphical interface was expected
if [ "$GRASS_GUI" != "text" ] ; then
# Set the interface mode to text
echo
echo "WARNING: It appears that the X Windows system is not active."
echo "A graphical based user interface is not supported."
echo "Switching to text based interface mode."
echo
echo "Hit RETURN to continue"
read ans
GRASS_GUI="text"
fi
fi
# Save the user interface variable in the grassrc file - choose a temporary
# file name that should not match another file
if [ -f "$GISRC" ] ; then
awk '$1 !~ /GRASS_GUI/ {print}' "$GISRC" > "$GISRC.$$"
echo "GRASS_GUI: $GRASS_GUI" >> "$GISRC.$$"
mv -f "$GISRC.$$" "$GISRC"
fi
# Parsing argument to get LOCATION
if [ ! "$1" ] ; then
# Try interactive startup
LOCATION=
else
# Try non-interactive startup
L=
if [ "$1" = "-" ] ; then
if [ "$LOCATION" ] ; then
L="$LOCATION"
fi
else
L="$1"
if [ `echo "$L" | cut -c 1` != "/" ] ; then
L="`pwd`/$L"
fi
fi
if [ "$L" ] ; then
MAPSET=`basename "$L"`
L=`dirname "$L"`
if [ "$L" != "." ] ; then
LOCATION_NAME=`basename "$L"`
L=`dirname "$L"`
if [ "$L" != "." ] ; then
GISDBASE="$L"
fi
fi
fi
#strip off white space from LOCATION_NAME and MAPSET: only supported for $GISDBASE
MAPSET=`echo $MAPSET | sed 's+ ++g'`
LOCATION_NAME=`echo $LOCATION_NAME | sed 's+ ++g'`
if [ "$GISDBASE" -a "$LOCATION_NAME" -a "$MAPSET" ] ; then
LOCATION="$GISDBASE/$LOCATION_NAME/$MAPSET"
if [ ! -r "$LOCATION/WIND" ] ; then
echo "$LOCATION: Not a valid GRASS location"
exit
fi
if [ -s "$GISRC" ] ; then
sed -e "s|^GISDBASE:.*$|GISDBASE: $GISDBASE|; \
s|^LOCATION_NAME:.*$|LOCATION_NAME: $LOCATION_NAME|; \
s|^MAPSET:.*$|MAPSET: $MAPSET|" "$GISRC" > "$GISRC.$$"
if [ $? -eq 0 ] ; then
mv -f "$GISRC.$$" "$GISRC"
else
rm -f "$GISRC.$$"
echo "Failed to create new $GISRC"
LOCATION=
fi
else
echo "GISDBASE: $GISDBASE" > "$GISRC"
echo "LOCATION_NAME: $LOCATION_NAME" >> "$GISRC"
echo "MAPSET: $MAPSET" >> "$GISRC"
fi
else
echo "GISDBASE, LOCATION_NAME and MAPSET variables not set properly."
echo "Interactive startup needed."
exit
fi
fi
# User selects LOCATION and MAPSET if not set
if [ ! "$LOCATION" ] ; then
echo "ERROR: Please specify GISDBASE/LOCATION/MAPSET path."
exit
fi
GISDBASE=`g.gisenv GISDBASE`
LOCATION_NAME=`g.gisenv LOCATION_NAME`
MAPSET=`g.gisenv MAPSET`
LOCATION=${GISDBASE?}/${LOCATION_NAME?}/${MAPSET?}
# Check for concurrent use
lockfile="$LOCATION/.gislock"
"$ETC/lock" "$lockfile" $$
case $? in
0) ;;
1)
echo `whoami` is currently running GRASS in selected mapset. Concurrent use not allowed.
rm -rf "$tmp" # remove session files from tmpdir
exit 1 ;;
*)
echo Unable to properly access "$lockfile"
echo Please notify system personel.
exit 1 ;;
esac
trap "" 2 3 15
# cygwin has many problems with the shell setup
# below, so i hardcoded everything here.
if [ "$CYGWIN" ] ; then
sh="cygwin"
shellname="GNU Bash (Cygwin)"
export SHELL=/usr/bin/bash.exe
export OSTYPE=cygwin
else
sh=`basename "$SHELL"`
case "$sh" in
ksh) shellname="Korn Shell";;
csh) shellname="C Shell" ;;
tcsh) shellname="TC Shell" ;;
bash) shellname="Bash Shell" ;;
sh) shellname="Bourne Shell";;
*) shellname=shell;;
esac
fi
# check for SHELL
if [ ! -x "$SHELL" ] ; then
echo "ERROR: The SHELL variable is not set" 1>&2
rm -f "$lockfile"
rm -rf "$tmp" # remove session files from tmpdir
exit 1
fi
case "$sh" in
csh|tcsh)
USERHOME="$HOME" # save original home
HOME="$LOCATION"
export HOME
cshrc="$HOME/.cshrc"
tcshrc="$HOME/.tcshrc"
rm -f "$cshrc" "$tcshrc"
echo "set home = $USERHOME" > "$cshrc"
echo "set history = 500 savehist = 500 noclobber ignoreeof" >> "$cshrc"
echo "set histfile = $HOME/.history" >> "$cshrc"
echo "set prompt = '\\" >> "$cshrc"
echo "Mapset <${MAPSET}> in Location <${LOCATION_NAME}> \\" >> "$cshrc"
echo "GRASS 6.1.cvs > '" >> "$cshrc"
echo 'set BOGUS=``;unset BOGUS' >> "$cshrc"
if [ -r "$USERHOME/.grass.cshrc" ]
then
cat "$USERHOME/.grass.cshrc" >> "$cshrc"
fi
if [ -r "$USERHOME/.cshrc" ]
then
grep '^ *set *mail *= *' "$USERHOME/.cshrc" >> "$cshrc"
fi
if [ -r "$USERHOME/.tcshrc" ]
then
grep '^ *set *mail *= *' "$USERHOME/.tcshrc" >> "$cshrc"
fi
if [ -r "$USERHOME/.login" ]
then
grep '^ *set *mail *= *' "$USERHOME/.login" >> "$cshrc"
fi
echo "set path = ( $PATH ) " | sed 's/:/ /g' >> "$cshrc"
cp "$cshrc" "$tcshrc"
"$ETC/run" "$2"
HOME="$USERHOME"
export HOME
;;
bash|msh)
USERHOME="$HOME" # save original home
HOME="$LOCATION" # save .bashrc in $LOCATION
export HOME
bashrc="$HOME/.bashrc"
rm -f "$bashrc"
echo "test -z $PROFILEREAD && . /etc/profile" > "$bashrc"
echo "test -r ~/.alias && . ~/.alias" >> "$bashrc"
echo "umask 022" >> "$bashrc"
echo "PS1='GRASS 6.1.cvs ($LOCATION_NAME):\w > '" >> "$bashrc"
echo "PROMPT_COMMAND='if test -d `g.gisenv GISDBASE`/`g.gisenv LOCATION_NAME`/`g.gisenv MAPSET`/grid3/G3D_MASK && test -f`g.gisenv GISDBASE`/`g.gisenv LOCATION_NAME`/`g.gisenv MAPSET`/cell/MASK ; then echo [Raster and Volume MASKs present] ; elif test -f `g.gisenv GISDBASE`/`g.gisenv LOCATION_NAME`/`g.gisenv MAPSET`/cell/MASK ; then echo [Raster MASK present] ; elif test -d `g.gisenv GISDBASE`/`g.gisenv LOCATION_NAME`/`g.gisenv MAPSET`/grid3/G3D_MASK ; then echo [Volume MASK present] ; fi'" >> "$bashrc"
if [ -r "$USERHOME/.grass.bashrc" ]
then
cat "$USERHOME/.grass.bashrc" >> "$bashrc"
fi
echo "export PATH=\"$PATH\"" >> "$bashrc"
echo "export HOME=\"$USERHOME\"" >> "$bashrc" # restore user home path
"$ETC/run" "$2"
HOME="$USERHOME"
export HOME
;;
cygwin)
USERHOME="$HOME" # save original home
HOME="$LOCATION" # save .bashrc in $LOCATION
export HOME
bashrc="$HOME/.bashrc"
rm -f "$bashrc"
# this does not work on cygwin for unknown reasons
# echo "test -z $PROFILEREAD && . /etc/profile" > "$bashrc"
echo "test -r ~/.alias && . ~/.alias" >> "$bashrc"
echo "umask 022" >> "$bashrc"
echo "PS1='GRASS 6.1.cvs ($LOCATION_NAME):\w > '" >> "$bashrc"
if [ -r "$USERHOME/.grass.bashrc" ]
then
cat "$USERHOME/.grass.bashrc" >> "$bashrc"
fi
echo "export PATH=\"$PATH\"" >> "$bashrc"
echo "export HOME=\"$USERHOME\"" >> "$bashrc" # restore user home path
"$ETC/run" "$2"
HOME="$USERHOME"
export HOME
;;
*)
PS1="
Mapset <$MAPSET> in Location <$LOCATION_NAME>
GRASS-GRID > "
export PS1
"$ETC/run" "$2"
;;
esac
trap 2 3 15
# GRASS session finished
tput clear
echo "Closing monitors....."
for MON in `d.mon -L | grep running | grep -v "not running" | sed 's/ .*//'`
do
echo d.mon stop=$MON
d.mon stop=$MON
done
echo "Cleaning up temporary files....."
"$ETC/clean_temp" > /dev/null
rm -f "$lockfile"
# Save GISRC
cp "$GISRC" "$GISRCRC"
rm -rf "$tmp" # remove session files from tmpdir
echo "done"
echo
echo
echo
echo "Goodbye from GRASS GIS"
echo
-------------- next part --------------
#!/bin/bash
g.list rast
More information about the grass-user
mailing list