[GRASS-dev] [GRASS GIS] #2284: Keep pressing Ctrl+C in command line

#2284: Keep pressing Ctrl+C in command line
-------------------------+--------------------------------------------------
Reporter: hcho | Owner: grass-dev@…
     Type: enhancement | Status: new
Priority: normal | Milestone: 7.0.0
Component: Startup | Version: svn-trunk
Keywords: | Platform: Linux
      Cpu: x86-64 |
-------------------------+--------------------------------------------------
Since we changed the init script to python, I've been getting the
following message whenever I keep pressing Ctrl+C in command line:
{{{
^CTraceback (most recent call last):
   File "/home/grass/trunk/dist.x86_64-unknown-linux-gnu/etc/prompt.py",
line 3, in <module>
     import os
KeyboardInterrupt
}}}

It doesn't cause any real problems, but it doesn't look nice. Also, the
overall responsiveness of the prompt became much slower than when we were
in init.sh.

Can we fix this? Or can we opt to use the old init.sh, which I think is
gone now?

I believe the main motivation of this migration to python was to support
MS-Windows, but it somehow hurts performance on Unix.

--
Ticket URL: <http://trac.osgeo.org/grass/ticket/2284&gt;
GRASS GIS <http://grass.osgeo.org>

#2284: Keep pressing Ctrl+C in command line
-------------------------+--------------------------------------------------
Reporter: hcho | Owner: grass-dev@…
     Type: enhancement | Status: new
Priority: normal | Milestone: 7.0.0
Component: Startup | Version: svn-trunk
Keywords: | Platform: Linux
      Cpu: x86-64 |
-------------------------+--------------------------------------------------

Comment(by glynn):

Replying to [ticket:2284 hcho]:

> Can we fix this? Or can we opt to use the old init.sh, which I think is
gone now?

There's no reason to revert to init.sh, but we could replace prompt.py
with the bash version (prompt.sh) from 6.x. The prompt script is only used
if you're using bash as your shell, so portability isn't an issue.

You can disable the fancy prompt with "unset PROMPT_COMMAND".

The error could probably be avoided by wrapping the entire prompt.py
script in a try/except block, but that wouldn't help with performance.
Ignoring the signal wouldn't work reliably, because you'd have to import
the signal module first, and any signal raised during that time would
still result in the KeyboardInterrupt exception.

--
Ticket URL: <http://trac.osgeo.org/grass/ticket/2284#comment:1&gt;
GRASS GIS <http://grass.osgeo.org>

Would I miss any functionalities by using prompt.sh? I mean other than portability between OSs, does prompt.py provide other benefits? If there’s nothing to lose in Unix by falling back to prompt.sh, I’d like to bring it into 7 and let the user choose. Maybe if the user is in Unix, there is no reason at all to use prompt.py?

I don’t know about Windows, but what benefits would this python startup bring compared to native cmd.exe? Just wondering…

On May 10, 2014 2:11 PM, “GRASS GIS” <trac@osgeo.org> wrote:

#2284: Keep pressing Ctrl+C in command line
-------------------------±-------------------------------------------------
Reporter: hcho | Owner: grass-dev@…
Type: enhancement | Status: new
Priority: normal | Milestone: 7.0.0
Component: Startup | Version: svn-trunk
Keywords: | Platform: Linux
Cpu: x86-64 |
-------------------------±-------------------------------------------------

Comment(by glynn):

Replying to [ticket:2284 hcho]:

Can we fix this? Or can we opt to use the old init.sh, which I think is
gone now?

There’s no reason to revert to init.sh, but we could replace prompt.py
with the bash version (prompt.sh) from 6.x. The prompt script is only used
if you’re using bash as your shell, so portability isn’t an issue.

You can disable the fancy prompt with “unset PROMPT_COMMAND”.

The error could probably be avoided by wrapping the entire prompt.py
script in a try/except block, but that wouldn’t help with performance.
Ignoring the signal wouldn’t work reliably, because you’d have to import
the signal module first, and any signal raised during that time would
still result in the KeyboardInterrupt exception.


Ticket URL: <http://trac.osgeo.org/grass/ticket/2284#comment:1>
GRASS GIS <http://grass.osgeo.org>

Huidae Cho wrote:

Would I miss any functionalities by using prompt.sh?

No.

I mean other than portability between OSs,

prompt.py doesn't provide that. The only way in which the script is
executed is by setting the bash variable PROMPT_COMMAND. If set, bash
treats its value as a command to execute prior to displaying the
primary prompt ($PS1).

If you're using bash, you can use either prompt.sh or prompt.py (or
something of your own devising, or nothing). If you aren't using bash,
neither of those scripts are of any use to you.

does prompt.py provide other benefits? If there's
nothing to lose in Unix by falling back to prompt.sh, I'd like to bring it
into 7 and let the user choose. Maybe if the user is in Unix, there is no
reason at all to use prompt.py?

I'm not sure that we need a choice. Actually, I'm not sure that we
even need a separate script (in any language). $PROMPT_COMMAND can be
any bash command; it doesn't have to be an external program. We could
just insert the appropriate code as a bash function into the custom
<mapset>/.bashrc file generated by the startup script.

IOW, in lib/init/grass.py, replace
    
    f.write("PROMPT_COMMAND=\"'%s'\"\n" % os.path.join(gisbase, 'etc',
                                                       'prompt.py'))

with

    f.write("""
grass_prompt () {
LOCATION="`g.gisenv GISDBASE`/`g.gisenv LOCATION_NAME`/`g.gisenv MAPSET`"
if test -d "$LOCATION/grid3/G3D_MASK" && test -f "$LOCATION/cell/MASK" ; then
    echo [Raster and Volume MASKs present]
elif test -f "$LOCATION/cell/MASK" ; then
    echo [Raster MASK present]
elif test -d "$LOCATION/grid3/G3D_MASK" ; then
    echo [Volume MASK present]
fi
}
PROMPT_COMMAND=grass_prompt
""")

--
Glynn Clements <glynn@gclements.plus.com>

Ok, Let me understand it. So the keyboard interrupted exception is coming from prompt.py, not from grass.py. If I replace prompt.py with prompt.sh, I’m out of python completely and not facing performance hit either?

I thought as long as grass.py launches bash with whatever PROMPT_COMMAND either being prompt.py or prompt.sh, I’m inside a python process and cannot avoid keyboard interuption exceptions and slow performance.

Huidae

On May 12, 2014 6:37 PM, “Glynn Clements” <glynn@gclements.plus.com> wrote:

Huidae Cho wrote:

Would I miss any functionalities by using prompt.sh?

No.

I mean other than portability between OSs,

prompt.py doesn’t provide that. The only way in which the script is
executed is by setting the bash variable PROMPT_COMMAND. If set, bash
treats its value as a command to execute prior to displaying the
primary prompt ($PS1).

If you’re using bash, you can use either prompt.sh or prompt.py (or
something of your own devising, or nothing). If you aren’t using bash,
neither of those scripts are of any use to you.

does prompt.py provide other benefits? If there’s
nothing to lose in Unix by falling back to prompt.sh, I’d like to bring it
into 7 and let the user choose. Maybe if the user is in Unix, there is no
reason at all to use prompt.py?

I’m not sure that we need a choice. Actually, I’m not sure that we
even need a separate script (in any language). $PROMPT_COMMAND can be
any bash command; it doesn’t have to be an external program. We could
just insert the appropriate code as a bash function into the custom
/.bashrc file generated by the startup script.

IOW, in lib/init/grass.py, replace

f.write(“PROMPT_COMMAND="‘%s’"\n” % os.path.join(gisbase, ‘etc’,
‘prompt.py’))

with

f.write(“”"
grass_prompt () {
LOCATION=“g.gisenv GISDBASE/g.gisenv LOCATION_NAME/g.gisenv MAPSET
if test -d “$LOCATION/grid3/G3D_MASK” && test -f “$LOCATION/cell/MASK” ; then
echo [Raster and Volume MASKs present]
elif test -f “$LOCATION/cell/MASK” ; then
echo [Raster MASK present]
elif test -d “$LOCATION/grid3/G3D_MASK” ; then
echo [Volume MASK present]
fi
}
PROMPT_COMMAND=grass_prompt
“”")


Glynn Clements <glynn@gclements.plus.com>

I just tested with your code above and it works great! No delay between enters and no keyboard interrupt exceptions. If prompt.py is just for bash and it’s causing issues, I’d like to replace it with grass_prompt.

···

On Mon, May 12, 2014 at 6:56 PM, Huidae Cho <grass4u@gmail.com> wrote:

Ok, Let me understand it. So the keyboard interrupted exception is coming from prompt.py, not from grass.py. If I replace prompt.py with prompt.sh, I’m out of python completely and not facing performance hit either?

I thought as long as grass.py launches bash with whatever PROMPT_COMMAND either being prompt.py or prompt.sh, I’m inside a python process and cannot avoid keyboard interuption exceptions and slow performance.

Huidae

On May 12, 2014 6:37 PM, “Glynn Clements” <glynn@gclements.plus.com> wrote:

Huidae Cho wrote:

Would I miss any functionalities by using prompt.sh?

No.

I mean other than portability between OSs,

prompt.py doesn’t provide that. The only way in which the script is
executed is by setting the bash variable PROMPT_COMMAND. If set, bash
treats its value as a command to execute prior to displaying the
primary prompt ($PS1).

If you’re using bash, you can use either prompt.sh or prompt.py (or
something of your own devising, or nothing). If you aren’t using bash,
neither of those scripts are of any use to you.

does prompt.py provide other benefits? If there’s
nothing to lose in Unix by falling back to prompt.sh, I’d like to bring it
into 7 and let the user choose. Maybe if the user is in Unix, there is no
reason at all to use prompt.py?

I’m not sure that we need a choice. Actually, I’m not sure that we
even need a separate script (in any language). $PROMPT_COMMAND can be
any bash command; it doesn’t have to be an external program. We could
just insert the appropriate code as a bash function into the custom
/.bashrc file generated by the startup script.

IOW, in lib/init/grass.py, replace

f.write(“PROMPT_COMMAND="‘%s’"\n” % os.path.join(gisbase, ‘etc’,
‘prompt.py’))

with

f.write(“”"
grass_prompt () {
LOCATION=“g.gisenv GISDBASE/g.gisenv LOCATION_NAME/g.gisenv MAPSET
if test -d “$LOCATION/grid3/G3D_MASK” && test -f “$LOCATION/cell/MASK” ; then
echo [Raster and Volume MASKs present]
elif test -f “$LOCATION/cell/MASK” ; then
echo [Raster MASK present]
elif test -d “$LOCATION/grid3/G3D_MASK” ; then
echo [Volume MASK present]
fi
}
PROMPT_COMMAND=grass_prompt
“”")


Glynn Clements <glynn@gclements.plus.com>

#2284: Keep pressing Ctrl+C in command line
--------------------------+-------------------------------------------------
  Reporter: hcho | Owner: grass-dev@…
      Type: enhancement | Status: closed
  Priority: normal | Milestone: 7.0.0
Component: Startup | Version: svn-trunk
Resolution: fixed | Keywords:
  Platform: Linux | Cpu: x86-64
--------------------------+-------------------------------------------------
Changes (by hcho):

  * status: new => closed
  * resolution: => fixed

Comment:

Fixed in r60216

--
Ticket URL: <https://trac.osgeo.org/grass/ticket/2284#comment:2&gt;
GRASS GIS <http://grass.osgeo.org>

#2284: Keep pressing Ctrl+C in command line
--------------------------+-------------------------------------------------
  Reporter: hcho | Owner: grass-dev@…
      Type: enhancement | Status: reopened
  Priority: normal | Milestone: 7.0.0
Component: Startup | Version: svn-trunk
Resolution: | Keywords:
  Platform: All | Cpu: x86-64
--------------------------+-------------------------------------------------
Changes (by neteler):

  * status: closed => reopened
  * platform: Linux => All
  * resolution: fixed =>

Comment:

Replying to [comment:2 hcho]:
> Fixed in r60216
> resolution set to fixed

In case this also works for Windows, what about backporting to relbr7? Has
it been tested on Windows?

{{{
1457 elif sh in ['bash', 'msh', 'cygwin']:
1458 bash_startup()
}}}

--
Ticket URL: <https://trac.osgeo.org/grass/ticket/2284#comment:3&gt;
GRASS GIS <http://grass.osgeo.org>

Huidae Cho wrote:

Ok, Let me understand it. So the keyboard interrupted exception is coming
from prompt.py, not from grass.py.

Yes; from the original bug report:

^CTraceback (most recent call last):
  File "/home/grass/trunk/dist.x86_64-unknown-linux-gnu/etc/prompt.py",

                                                              ^^^^^^^^^

line 3, in <module>
    import os
KeyboardInterrupt

If I replace prompt.py with prompt.sh,
I'm out of python completely and not facing performance hit either?

I haven't really looked into the performance hit, but I would expect
Python to have a higher startup overhead than bash.

Both scripts do essentially the same thing, i.e. they use g.gisenv to
determine the mapset directory, check for the existence of raster
and/or volume masks, then print a message if either or both of those
exist.

If PROMPT_COMMAND is set, the command is run immediately before bash
prints a primary prompt (when it's time for a new command, as opposed
to a secondary prompt which is printed at the start of each
continuation line in a multi-line command).

I suspect that most of the overhead is from Python starting up and
importing modules. It imports os, sys and gettext directly, as well as
grass.script.core, which in turn imports os, sys, types, re, atexit,
subprocess, shutil, locale, codecs, and gettext.

This overhead is likely to be insignificant for a "real" script which
does non-trivial processing, but for a trivial script which is run for
each prompt, it may be an issue.

OTOH, the Python version only executes g.gisenv once, whereas the
shell version executes it 3 times (once for each variable).

I thought as long as grass.py launches bash with whatever PROMPT_COMMAND
either being prompt.py or prompt.sh, I'm inside a python process and cannot
avoid keyboard interuption exceptions and slow performance.

The process running the grass.py script still exists as the shell's
parent process, but it's just in a blocking wait for the shell to
exit.

--
Glynn Clements <glynn@gclements.plus.com>

#2284: Keep pressing Ctrl+C in command line
--------------------------+-------------------------------------------------
  Reporter: hcho | Owner: grass-dev@…
      Type: enhancement | Status: reopened
  Priority: normal | Milestone: 7.0.0
Component: Startup | Version: svn-trunk
Resolution: | Keywords:
  Platform: All | Cpu: x86-64
--------------------------+-------------------------------------------------

Comment(by glynn):

Replying to [comment:3 neteler]:

> In case this also works for Windows, what about backporting to relbr7?
Has
> it been tested on Windows?

I can't think of any reason why it wouldn't. It should only be used for
bash (even in the script tries to use bash_startup() for something other
than bash, the code in question is written to .bashrc, which shouldn't be
read by anything which isn't actually bash), and Windows versions of bash
go to some lengths to maintain compatibility (they wouldn't be of much use
otherwise).

--
Ticket URL: <https://trac.osgeo.org/grass/ticket/2284#comment:4&gt;
GRASS GIS <http://grass.osgeo.org>

#2284: Keep pressing Ctrl+C in command line
--------------------------+-------------------------------------------------
  Reporter: hcho | Owner: grass-dev@…
      Type: enhancement | Status: reopened
  Priority: normal | Milestone: 7.0.0
Component: Startup | Version: svn-trunk
Resolution: | Keywords: prompt
  Platform: All | Cpu: x86-64
--------------------------+-------------------------------------------------
Changes (by neteler):

  * keywords: => prompt

Comment:

I have backported r60216 + r60222 + r60223 to relbr7 in r60735, hopefully
without side-effects. Please test on Windows + MacOSX.

--
Ticket URL: <https://trac.osgeo.org/grass/ticket/2284#comment:5&gt;
GRASS GIS <http://grass.osgeo.org>

#2284: Keep pressing Ctrl+C in command line
--------------------------+-------------------------------------------------
  Reporter: hcho | Owner: grass-dev@…
      Type: enhancement | Status: closed
  Priority: normal | Milestone: 7.0.0
Component: Startup | Version: svn-trunk
Resolution: fixed | Keywords: prompt
  Platform: All | Cpu: x86-64
--------------------------+-------------------------------------------------
Changes (by neteler):

  * status: reopened => closed
  * resolution: => fixed

Comment:

Seems to work ok, closing.

--
Ticket URL: <http://trac.osgeo.org/grass/ticket/2284#comment:6&gt;
GRASS GIS <http://grass.osgeo.org>