Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #12368 > unrolled thread

killing a script

Started by"Russ P." <russ.paielli@gmail.com>
First post2011-08-28 18:15 -0700
Last post2011-08-29 07:52 +0100
Articles 20 on this page of 24 — 11 participants

Back to article view | Back to comp.lang.python


Contents

  killing a script "Russ P." <russ.paielli@gmail.com> - 2011-08-28 18:15 -0700
    Re: killing a script MRAB <python@mrabarnett.plus.com> - 2011-08-29 02:52 +0100
      Re: killing a script "Russ P." <russ.paielli@gmail.com> - 2011-08-28 19:41 -0700
        Re: killing a script Chris Angelico <rosuav@gmail.com> - 2011-08-29 12:51 +1000
          Re: killing a script "Russ P." <russ.paielli@gmail.com> - 2011-08-28 20:08 -0700
            Re: killing a script Chris Rebert <clp2@rebertia.com> - 2011-08-28 20:16 -0700
              Re: killing a script "Russ P." <russ.paielli@gmail.com> - 2011-08-28 20:22 -0700
              Re: killing a script "Russ P." <russ.paielli@gmail.com> - 2011-08-29 14:26 -0700
            Re: killing a script Thomas Jollans <t@jollybox.de> - 2011-08-29 09:49 +0200
            Re: killing a script Arnaud Delobelle <arnodel@gmail.com> - 2011-08-29 23:53 +0100
              Re: killing a script Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-08-30 14:13 +1000
                Re: killing a script Hans Mulder <hansmu@xs4all.nl> - 2011-08-30 12:40 +0200
                Re: killing a script Cameron Simpson <cs@zip.com.au> - 2011-09-09 10:03 +1000
                  Re: killing a script Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-09-09 19:07 +1000
                    Re: killing a script Hans Mulder <hansmu@xs4all.nl> - 2011-09-09 12:13 +0200
                      Re: killing a script Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-09-09 22:16 +1000
                        Re: killing a script Cameron Simpson <cs@zip.com.au> - 2011-09-10 08:29 +1000
                          Re: killing a script Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-09-10 11:25 +1000
                            Re: killing a script Chris Angelico <rosuav@gmail.com> - 2011-09-10 11:37 +1000
                            Re: killing a script Cameron Simpson <cs@zip.com.au> - 2011-09-10 18:49 +1000
                              Re: killing a script Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-09-11 15:08 +1000
                            Re: killing a script Nobody <nobody@nowhere.com> - 2011-09-10 10:47 +0100
        Re: killing a script Paul Rubin <no.email@nospam.invalid> - 2011-08-28 19:53 -0700
    Re: killing a script Nobody <nobody@nowhere.com> - 2011-08-29 07:52 +0100

Page 1 of 2  [1] 2  Next page →


#12368 — killing a script

From"Russ P." <russ.paielli@gmail.com>
Date2011-08-28 18:15 -0700
Subjectkilling a script
Message-ID<22a0dae6-8a60-4e68-82a5-31a949bd69d5@y8g2000prd.googlegroups.com>
I have a Python (2.6.x) script on Linux that loops through many
directories and does processing for each. That processing includes
several "os.system" calls for each directory (some to other Python
scripts, others to bash scripts).

Occasionally something goes wrong, and the top-level script just keeps
running with a stack dump for each case. When I see that, I want to
just kill the whole thing and fix the bug. However, when I hit Control-
C, it apparently just just kills whichever script happens to be
running at that instant, and the top level script just moves to the
next line and keeps running. If I hit Control-C repeatedly, I
eventually get "lucky" and kill the top-level script. Is there a
simple way to ensure that the first Control-C will kill the whole darn
thing, i.e, the top-level script? Thanks.

--Russ P.

[toc] | [next] | [standalone]


#12373

FromMRAB <python@mrabarnett.plus.com>
Date2011-08-29 02:52 +0100
Message-ID<mailman.528.1314582745.27778.python-list@python.org>
In reply to#12368
On 29/08/2011 02:15, Russ P. wrote:
> I have a Python (2.6.x) script on Linux that loops through many
> directories and does processing for each. That processing includes
> several "os.system" calls for each directory (some to other Python
> scripts, others to bash scripts).
>
> Occasionally something goes wrong, and the top-level script just keeps
> running with a stack dump for each case. When I see that, I want to
> just kill the whole thing and fix the bug. However, when I hit Control-
> C, it apparently just just kills whichever script happens to be
> running at that instant, and the top level script just moves to the
> next line and keeps running. If I hit Control-C repeatedly, I
> eventually get "lucky" and kill the top-level script. Is there a
> simple way to ensure that the first Control-C will kill the whole darn
> thing, i.e, the top-level script? Thanks.
>
You could look at the return value of os.system, which may tell you the
exit status of the process.

[toc] | [prev] | [next] | [standalone]


#12376

From"Russ P." <russ.paielli@gmail.com>
Date2011-08-28 19:41 -0700
Message-ID<e52d78f9-7adb-4046-9368-3d35c5b20d0b@m4g2000pri.googlegroups.com>
In reply to#12373
On Aug 28, 6:52 pm, MRAB <pyt...@mrabarnett.plus.com> wrote:
> On 29/08/2011 02:15, Russ P. wrote:> I have a Python (2.6.x) script on Linux that loops through many
> > directories and does processing for each. That processing includes
> > several "os.system" calls for each directory (some to other Python
> > scripts, others to bash scripts).
>
> > Occasionally something goes wrong, and the top-level script just keeps
> > running with a stack dump for each case. When I see that, I want to
> > just kill the whole thing and fix the bug. However, when I hit Control-
> > C, it apparently just just kills whichever script happens to be
> > running at that instant, and the top level script just moves to the
> > next line and keeps running. If I hit Control-C repeatedly, I
> > eventually get "lucky" and kill the top-level script. Is there a
> > simple way to ensure that the first Control-C will kill the whole darn
> > thing, i.e, the top-level script? Thanks.
>
> You could look at the return value of os.system, which may tell you the
> exit status of the process.

Thanks for the suggestion. Yeah, I guess I could do that, but it seems
that there should be a simpler way to just kill the "whole enchilada."
Hitting Control-C over and over is a bit like whacking moles.

--Russ P.

[toc] | [prev] | [next] | [standalone]


#12377

FromChris Angelico <rosuav@gmail.com>
Date2011-08-29 12:51 +1000
Message-ID<mailman.530.1314586278.27778.python-list@python.org>
In reply to#12376
On Mon, Aug 29, 2011 at 12:41 PM, Russ P. <russ.paielli@gmail.com> wrote:
> On Aug 28, 6:52 pm, MRAB <pyt...@mrabarnett.plus.com> wrote:
>> You could look at the return value of os.system, which may tell you the
>> exit status of the process.
>
> Thanks for the suggestion. Yeah, I guess I could do that, but it seems
> that there should be a simpler way to just kill the "whole enchilada."
> Hitting Control-C over and over is a bit like whacking moles.

I believe the idea of this suggestion is for the outer script to
notice that the inner script terminated via Ctrl-C, and would then
immediately choose to terminate itself - thus avoiding the
whack-a-mole effect.

ChrisA

[toc] | [prev] | [next] | [standalone]


#12380

From"Russ P." <russ.paielli@gmail.com>
Date2011-08-28 20:08 -0700
Message-ID<fd1e808a-7bc1-49dc-8a6c-eb0ca144abce@x11g2000prb.googlegroups.com>
In reply to#12377
On Aug 28, 7:51 pm, Chris Angelico <ros...@gmail.com> wrote:
> On Mon, Aug 29, 2011 at 12:41 PM, Russ P. <russ.paie...@gmail.com> wrote:
> > On Aug 28, 6:52 pm, MRAB <pyt...@mrabarnett.plus.com> wrote:
> >> You could look at the return value of os.system, which may tell you the
> >> exit status of the process.
>
> > Thanks for the suggestion. Yeah, I guess I could do that, but it seems
> > that there should be a simpler way to just kill the "whole enchilada."
> > Hitting Control-C over and over is a bit like whacking moles.
>
> I believe the idea of this suggestion is for the outer script to
> notice that the inner script terminated via Ctrl-C, and would then
> immediately choose to terminate itself - thus avoiding the
> whack-a-mole effect.
>
> ChrisA

Yes, but if I am not mistaken, that will require me to put a line or
two after each os.system call. That's almost like whack-a-mole at the
code level rather than the Control-C level. OK, not a huge deal for
one script, but I was hoping for something simpler. I was hoping I
could put one line at the top of the script and be done with it.

--Russ P.

[toc] | [prev] | [next] | [standalone]


#12381

FromChris Rebert <clp2@rebertia.com>
Date2011-08-28 20:16 -0700
Message-ID<mailman.532.1314587781.27778.python-list@python.org>
In reply to#12380
On Sun, Aug 28, 2011 at 8:08 PM, Russ P. <russ.paielli@gmail.com> wrote:
> On Aug 28, 7:51 pm, Chris Angelico <ros...@gmail.com> wrote:
>> On Mon, Aug 29, 2011 at 12:41 PM, Russ P. <russ.paie...@gmail.com> wrote:
>> > On Aug 28, 6:52 pm, MRAB <pyt...@mrabarnett.plus.com> wrote:
>> >> You could look at the return value of os.system, which may tell you the
>> >> exit status of the process.
>>
>> > Thanks for the suggestion. Yeah, I guess I could do that, but it seems
>> > that there should be a simpler way to just kill the "whole enchilada."
>> > Hitting Control-C over and over is a bit like whacking moles.
>>
>> I believe the idea of this suggestion is for the outer script to
>> notice that the inner script terminated via Ctrl-C, and would then
>> immediately choose to terminate itself - thus avoiding the
>> whack-a-mole effect.
>>
>> ChrisA
>
> Yes, but if I am not mistaken, that will require me to put a line or
> two after each os.system call.

Er, just write a wrapper for os.system(), e.g.:

def mysystem(cmd):
    if os.system(cmd):
        sys.exit()

Also, you may want to switch to using the `subprocess` module instead.

Cheers,
Chris

[toc] | [prev] | [next] | [standalone]


#12382

From"Russ P." <russ.paielli@gmail.com>
Date2011-08-28 20:22 -0700
Message-ID<b80d87cc-99fb-4b43-973d-025af6cb9e36@x14g2000prn.googlegroups.com>
In reply to#12381
On Aug 28, 8:16 pm, Chris Rebert <c...@rebertia.com> wrote:
> On Sun, Aug 28, 2011 at 8:08 PM, Russ P. <russ.paie...@gmail.com> wrote:
> > On Aug 28, 7:51 pm, Chris Angelico <ros...@gmail.com> wrote:
> >> On Mon, Aug 29, 2011 at 12:41 PM, Russ P. <russ.paie...@gmail.com> wrote:
> >> > On Aug 28, 6:52 pm, MRAB <pyt...@mrabarnett.plus.com> wrote:
> >> >> You could look at the return value of os.system, which may tell you the
> >> >> exit status of the process.
>
> >> > Thanks for the suggestion. Yeah, I guess I could do that, but it seems
> >> > that there should be a simpler way to just kill the "whole enchilada."
> >> > Hitting Control-C over and over is a bit like whacking moles.
>
> >> I believe the idea of this suggestion is for the outer script to
> >> notice that the inner script terminated via Ctrl-C, and would then
> >> immediately choose to terminate itself - thus avoiding the
> >> whack-a-mole effect.
>
> >> ChrisA
>
> > Yes, but if I am not mistaken, that will require me to put a line or
> > two after each os.system call.
>
> Er, just write a wrapper for os.system(), e.g.:
>
> def mysystem(cmd):
>     if os.system(cmd):
>         sys.exit()
>
> Also, you may want to switch to using the `subprocess` module instead.
>
> Cheers,
> Chris

Sounds like a good idea. I'll give it a try. Thanks.

--Russ P.

[toc] | [prev] | [next] | [standalone]


#12421

From"Russ P." <russ.paielli@gmail.com>
Date2011-08-29 14:26 -0700
Message-ID<01954f13-f3b4-4be1-8038-e452b06b2c7b@fv14g2000vbb.googlegroups.com>
In reply to#12381
On Aug 28, 8:16 pm, Chris Rebert <c...@rebertia.com> wrote:
> On Sun, Aug 28, 2011 at 8:08 PM, Russ P. <russ.paie...@gmail.com> wrote:
> > On Aug 28, 7:51 pm, Chris Angelico <ros...@gmail.com> wrote:
> >> On Mon, Aug 29, 2011 at 12:41 PM, Russ P. <russ.paie...@gmail.com> wrote:
> >> > On Aug 28, 6:52 pm, MRAB <pyt...@mrabarnett.plus.com> wrote:
> >> >> You could look at the return value of os.system, which may tell you the
> >> >> exit status of the process.
>
> >> > Thanks for the suggestion. Yeah, I guess I could do that, but it seems
> >> > that there should be a simpler way to just kill the "whole enchilada."
> >> > Hitting Control-C over and over is a bit like whacking moles.
>
> >> I believe the idea of this suggestion is for the outer script to
> >> notice that the inner script terminated via Ctrl-C, and would then
> >> immediately choose to terminate itself - thus avoiding the
> >> whack-a-mole effect.
>
> >> ChrisA
>
> > Yes, but if I am not mistaken, that will require me to put a line or
> > two after each os.system call.
>
> Er, just write a wrapper for os.system(), e.g.:
>
> def mysystem(cmd):
>     if os.system(cmd):
>         sys.exit()
>
> Also, you may want to switch to using the `subprocess` module instead.
>
> Cheers,
> Chris

I ended up with this:

def systemx(cmd):

    if system(cmd): exit("\nERROR: " + cmd + " failed\n")

This is good enough for my purposes in this case. Thanks for all the
suggestions.

--Russ P.

[toc] | [prev] | [next] | [standalone]


#12397

FromThomas Jollans <t@jollybox.de>
Date2011-08-29 09:49 +0200
Message-ID<mailman.540.1314604147.27778.python-list@python.org>
In reply to#12380
On 2011-08-29 05:08, Russ P. wrote:
> Yes, but if I am not mistaken, that will require me to put a line or 
> two after each os.system call. That's almost like whack-a-mole at the 
> code level rather than the Control-C level. OK, not a huge deal for 
> one script, but I was hoping for something simpler. I was hoping I 
> could put one line at the top of the script and be done with it.

It's perfectly normal error-handling procedure. In Python, errors are 
usually handled by exceptions, but if you embed a system that doesn't 
support exceptions, e.g. external processes or a C library via ctypes, 
you will of course have to write a little more code in order to handle 
errors correctly.

T

[toc] | [prev] | [next] | [standalone]


#12424

FromArnaud Delobelle <arnodel@gmail.com>
Date2011-08-29 23:53 +0100
Message-ID<mailman.560.1314658396.27778.python-list@python.org>
In reply to#12380
On 29 August 2011 04:08, Russ P. <russ.paielli@gmail.com> wrote:
> On Aug 28, 7:51 pm, Chris Angelico <ros...@gmail.com> wrote:
>> On Mon, Aug 29, 2011 at 12:41 PM, Russ P. <russ.paie...@gmail.com> wrote:
>> > On Aug 28, 6:52 pm, MRAB <pyt...@mrabarnett.plus.com> wrote:
>> >> You could look at the return value of os.system, which may tell you the
>> >> exit status of the process.
>>
>> > Thanks for the suggestion. Yeah, I guess I could do that, but it seems
>> > that there should be a simpler way to just kill the "whole enchilada."
>> > Hitting Control-C over and over is a bit like whacking moles.
>>
>> I believe the idea of this suggestion is for the outer script to
>> notice that the inner script terminated via Ctrl-C, and would then
>> immediately choose to terminate itself - thus avoiding the
>> whack-a-mole effect.
>>
>> ChrisA
>
> Yes, but if I am not mistaken, that will require me to put a line or
> two after each os.system call. That's almost like whack-a-mole at the
> code level rather than the Control-C level. OK, not a huge deal for
> one script, but I was hoping for something simpler. I was hoping I
> could put one line at the top of the script and be done with it.

Write a function!  That's what they're for after all :)

-- 
Arnaud

[toc] | [prev] | [next] | [standalone]


#12427

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2011-08-30 14:13 +1000
Message-ID<4e5c6376$0$29983$c3e8da3$5496439d@news.astraweb.com>
In reply to#12424
On Tue, 30 Aug 2011 08:53 am Arnaud Delobelle wrote:

[...]
>> Yes, but if I am not mistaken, that will require me to put a line or
>> two after each os.system call. That's almost like whack-a-mole at the
>> code level rather than the Control-C level. OK, not a huge deal for
>> one script, but I was hoping for something simpler. I was hoping I
>> could put one line at the top of the script and be done with it.
> 
> Write a function!  That's what they're for after all :)


I'm not sure that this is actually as simple as that, especially using
os.system.

As I understand it, the scenario is this:

The main script looks something like this:

for x in whatever:
    os.system('something.py x')

Each time through the loop, a new Python process is started. Each process
runs in the foreground, capturing standard input, and so hitting Ctrl-C
kills *that* process, not the main script. Unless, by chance, the Ctrl-C
happens after the system call returns, but before the next one starts, it
is completely invisible to the parent process (the main script). Wrapping
os.system in a function does nothing to fix that.

Possibly using the subprocess module may help. 

Otherwise, the only way around this I can think of is to ensure that
the 'something.py' script (or scripts!) each return an error code for "User
Cancelled":

for x in whatever:
    result = os.system('something.py x')
    if result == 3:  # User Cancelled
        break

But if the 'something.py' scripts are arbitrary scripts, I don't think you
have any easy way around it. Perhaps use threads, and have the main script
ask the thread to kill the child process?

Regardless, this is a hard problem, and it isn't possible to just have some
magic switch at the top of your script to make it work. You actually have
to do the work yourself.

(But of course you can do the work inside a function, and re-use it
elsewhere.)
 

-- 
Steven

[toc] | [prev] | [next] | [standalone]


#12434

FromHans Mulder <hansmu@xs4all.nl>
Date2011-08-30 12:40 +0200
Message-ID<4e5cbe1a$0$2468$e4fe514c@news2.news.xs4all.nl>
In reply to#12427
On 30/08/11 06:13:41, Steven D'Aprano wrote:
> On Tue, 30 Aug 2011 08:53 am Arnaud Delobelle wrote:
>
> [...]
>>> Yes, but if I am not mistaken, that will require me to put a line or
>>> two after each os.system call. That's almost like whack-a-mole at the
>>> code level rather than the Control-C level. OK, not a huge deal for
>>> one script, but I was hoping for something simpler. I was hoping I
>>> could put one line at the top of the script and be done with it.
>>
>> Write a function!  That's what they're for after all :)
>
>
> I'm not sure that this is actually as simple as that, especially using
> os.system.
>
> As I understand it, the scenario is this:
>
> The main script looks something like this:
>
> for x in whatever:
>      os.system('something.py x')
>
> Each time through the loop, a new Python process is started. Each process
> runs in the foreground, capturing standard input, and so hitting Ctrl-C
> kills *that* process, not the main script. Unless, by chance, the Ctrl-C
> happens after the system call returns, but before the next one starts, it
> is completely invisible to the parent process (the main script). Wrapping
> os.system in a function does nothing to fix that.
>
> Possibly using the subprocess module may help.

Using the subprocess module is likely to help, because unlike os.system,
subprocess does not set control-C to 'ignore' in the parent process

> Otherwise, the only way around this I can think of is to ensure that
> the 'something.py' script (or scripts!) each return an error code for "User
> Cancelled":
>
> for x in whatever:
>      result = os.system('something.py x')
>      if result == 3:  # User Cancelled
>          break

On my system, os.system returns 2 if the subprocess was killed by a
control-C.  The portable way is to use the constant SIGINT from the
signal module.

Not that os.system does not return 2 if the child ended by doing
sys.exit(2); in that case, os.system in the parent returns 2<<8.

> But if the 'something.py' scripts are arbitrary scripts, I don't think you
> have any easy way around it.

If the arbitrary script does not trap SIGINT, then os.system
will return the number of the signal that kill the script, i.e.
signal.SIGINT.

If the script traps SIGINT and does some cleanup and then
exits, the best you can hope for, is that in the error case,
the script exits with a special value.  And you have to
remember the <<8 issue.

> Perhaps use threads, and have the main script
> ask the thread to kill the child process?

How would that help?

The problem is that the parent process ignores control-C while
os.system is running (by design).  If the parent uses threads,
it still won't receive the signal, because signal state is
global.

> Regardless, this is a hard problem, and it isn't possible to just have some
> magic switch at the top of your script to make it work. You actually have
> to do the work yourself.

You could monkey-patch the os module and replace os.system by
(untested):

def sub_system(command):
     pr = subprocess.Popen(command, shell=True)
     status = os.waitpid(pr.pid, 0)[1]
     return status

That should have the same effect as os.system, except it does
not ignore control-C.

> (But of course you can do the work inside a function, and re-use it
> elsewhere.)

Even if you don't re-use it, you should still do it in a
function, if only for readability.

Hope this helps,

-- HansM


[toc] | [prev] | [next] | [standalone]


#12982

FromCameron Simpson <cs@zip.com.au>
Date2011-09-09 10:03 +1000
Message-ID<mailman.887.1315526624.27778.python-list@python.org>
In reply to#12427
On 30Aug2011 14:13, Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote:
| On Tue, 30 Aug 2011 08:53 am Arnaud Delobelle wrote:
| >> Yes, but if I am not mistaken, that will require me to put a line or
| >> two after each os.system call. That's almost like whack-a-mole at the
| >> code level rather than the Control-C level. OK, not a huge deal for
| >> one script, but I was hoping for something simpler. I was hoping I
| >> could put one line at the top of the script and be done with it.
| > 
| > Write a function!  That's what they're for after all :)
| 
| I'm not sure that this is actually as simple as that, especially using
| os.system.
| 
| As I understand it, the scenario is this:
| 
| The main script looks something like this:
| 
| for x in whatever:
|     os.system('something.py x')
| 
| Each time through the loop, a new Python process is started. Each process
| runs in the foreground, capturing standard input, and so hitting Ctrl-C
| kills *that* process, not the main script. Unless, by chance, the Ctrl-C
| happens after the system call returns, but before the next one starts, it
| is completely invisible to the parent process (the main script). Wrapping
| os.system in a function does nothing to fix that.

Presuming you're talking about UNIX, this is not correct.

Ctrl-C at the terminal delivers SIGINT to _every_ process in the controlling
process group for the terminal. It also has _nothing_ to do with the standard
input.

When you run a script, yea even a Python script, thus:

  myscript ...

then job control capable shells (all of them, these days) put the python
process running "myscript" in its own process group as the leader
(being, initially, the only process in the group). If myscript forks
other processes, as happens in os.system(), they are _also_ in that
process group. _ALL_ of them receive the SIGINT from your Ctrl-C.

Cheers,
-- 
Cameron Simpson <cs@zip.com.au> DoD#743
http://www.cskk.ezoshosting.com/cs/

DRM: the functionality of refusing to function. - Richard Stallman

[toc] | [prev] | [next] | [standalone]


#13010

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2011-09-09 19:07 +1000
Message-ID<4e69d74d$0$29979$c3e8da3$5496439d@news.astraweb.com>
In reply to#12982
Cameron Simpson wrote:

> On 30Aug2011 14:13, Steven D'Aprano <steve+comp.lang.python@pearwood.info>
> wrote:
> | On Tue, 30 Aug 2011 08:53 am Arnaud Delobelle wrote:
> | >> Yes, but if I am not mistaken, that will require me to put a line or
> | >> two after each os.system call. That's almost like whack-a-mole at the
> | >> code level rather than the Control-C level. OK, not a huge deal for
> | >> one script, but I was hoping for something simpler. I was hoping I
> | >> could put one line at the top of the script and be done with it.
> | > 
> | > Write a function!  That's what they're for after all :)
> | 
> | I'm not sure that this is actually as simple as that, especially using
> | os.system.
> | 
> | As I understand it, the scenario is this:
> | 
> | The main script looks something like this:
> | 
> | for x in whatever:
> |     os.system('something.py x')
> | 
> | Each time through the loop, a new Python process is started. Each
> | process runs in the foreground, capturing standard input, and so hitting
> | Ctrl-C kills *that* process, not the main script. Unless, by chance, the
> | Ctrl-C happens after the system call returns, but before the next one
> | starts, it is completely invisible to the parent process (the main
> | script). Wrapping os.system in a function does nothing to fix that.
> 
> Presuming you're talking about UNIX, this is not correct.
> 
> Ctrl-C at the terminal delivers SIGINT to _every_ process in the
> controlling process group for the terminal. It also has _nothing_ to do
> with the standard input.

There may be something to what you say, but the behaviour experienced by the
Original Poster still needs explaining. See below.

> When you run a script, yea even a Python script, thus:
> 
>   myscript ...
> 
> then job control capable shells (all of them, these days) put the python
> process running "myscript" in its own process group as the leader
> (being, initially, the only process in the group). If myscript forks
> other processes, as happens in os.system(), they are _also_ in that
> process group. _ALL_ of them receive the SIGINT from your Ctrl-C.


I can replicate to OP's problem with these two simple Python scripts:

[steve@sylar ~]$ cat script.py
#!/usr/bin/python
print "inside script.py"
print "type Ctrl-C to exit"
while True:
    pass

[steve@sylar ~]$ cat test.py
import os
print "calling script.py with os.system"
for i in range(3):
    os.system('./script.py')


And now run them:

[steve@sylar ~]$ python test.py
calling script.py with os.system
inside script.py
type Ctrl-C to exit
Traceback (most recent call last):
  File "./script.py", line 4, in <module>
    while True:
KeyboardInterrupt
inside script.py
type Ctrl-C to exit
Traceback (most recent call last):
  File "./script.py", line 5, in <module>
    pass
KeyboardInterrupt
inside script.py
type Ctrl-C to exit
Traceback (most recent call last):
  File "./script.py", line 4, in <module>
    while True:
KeyboardInterrupt


Sure enough, I now have to hit Ctrl-C repeatedly, once per invocation of
script.py. While script.py is running, it receives the Ctrl-C, the calling
process does not.



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#13015

FromHans Mulder <hansmu@xs4all.nl>
Date2011-09-09 12:13 +0200
Message-ID<4e69e6da$0$2551$e4fe514c@news2.news.xs4all.nl>
In reply to#13010
On 9/09/11 11:07:24, Steven D'Aprano wrote:
> Sure enough, I now have to hit Ctrl-C repeatedly, once per invocation of
> script.py. While script.py is running, it receives the Ctrl-C, the calling
> process does not.

You misinterpret what you are seeing: the calling process *does* receive
the ctrl-C, it just chooses to ignore it.

This is documented behaviour of os.system.  It you don't want this, then
use the subprocess module, which does not behave this way.

-- HansM

[toc] | [prev] | [next] | [standalone]


#13021

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2011-09-09 22:16 +1000
Message-ID<4e6a0382$0$29982$c3e8da3$5496439d@news.astraweb.com>
In reply to#13015
Hans Mulder wrote:

> On 9/09/11 11:07:24, Steven D'Aprano wrote:
>> Sure enough, I now have to hit Ctrl-C repeatedly, once per invocation of
>> script.py. While script.py is running, it receives the Ctrl-C, the
>> calling process does not.
> 
> You misinterpret what you are seeing: the calling process *does* receive
> the ctrl-C, it just chooses to ignore it. 
>
> This is documented behaviour of os.system. 

Documented where? Neither the on-line documentation nor the function
docstring mentions anything about it that I can see:

http://docs.python.org/py3k/library/os.html#os.system

>>> help(os.system)
Help on built-in function system in module posix:

system(...)
    system(command) -> exit_status

    Execute the command (a string) in a subshell.




-- 
Steven

[toc] | [prev] | [next] | [standalone]


#13037

FromCameron Simpson <cs@zip.com.au>
Date2011-09-10 08:29 +1000
Message-ID<mailman.917.1315607348.27778.python-list@python.org>
In reply to#13021
On 09Sep2011 22:16, Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote:
| Hans Mulder wrote:
| > On 9/09/11 11:07:24, Steven D'Aprano wrote:
| >> Sure enough, I now have to hit Ctrl-C repeatedly, once per invocation of
| >> script.py. While script.py is running, it receives the Ctrl-C, the
| >> calling process does not.
| > 
| > You misinterpret what you are seeing: the calling process *does* receive
| > the ctrl-C, it just chooses to ignore it. 
| >
| > This is documented behaviour of os.system. 
| 
| Documented where? Neither the on-line documentation nor the function
| docstring mentions anything about it that I can see:
| 
| http://docs.python.org/py3k/library/os.html#os.system

My copy of the 2.7 docs says:

  This is implemented by calling the Standard C function system(), and
  has the same limitations.

and sure enough, "man 3 system" says:

  The system() function hands the argument command to the command
  interpreter sh(1).  The calling process waits for the shell to finish
  executing the command, ignoring SIGINT and SIGQUIT, and blocking
  SIGCHLD.

os.system() is very convenient for simple stuff, but one size does not
fit all. Continuing with the Python docs for os.system:

  On Unix, the return value is the exit status of the process encoded in
  the format specified for wait().

and it is easy to inspect that value for "the subprocess died from a
signal". Not inspecting the exit status correctly will always be an
opportunity for incorrect app behaviour.

Cheers,
-- 
Cameron Simpson <cs@zip.com.au> DoD#743
http://www.cskk.ezoshosting.com/cs/

Mac OS X. Because making Unix user-friendly is easier than debugging Windows.
- Mike Dawson, Macintosh Systems Administrator and Consultation.
  mdawson@mac.com http://herowars.onestop.net

[toc] | [prev] | [next] | [standalone]


#13045

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2011-09-10 11:25 +1000
Message-ID<4e6abc95$0$29995$c3e8da3$5496439d@news.astraweb.com>
In reply to#13037
Cameron Simpson wrote:

> On 09Sep2011 22:16, Steven D'Aprano <steve+comp.lang.python@pearwood.info>
> wrote:
> | Hans Mulder wrote:
> | > On 9/09/11 11:07:24, Steven D'Aprano wrote:
> | >> Sure enough, I now have to hit Ctrl-C repeatedly, once per invocation
> | >> of script.py. While script.py is running, it receives the Ctrl-C, the
> | >> calling process does not.
> | > 
> | > You misinterpret what you are seeing: the calling process *does*
> | > receive the ctrl-C, it just chooses to ignore it.
> | >
> | > This is documented behaviour of os.system.
> | 
> | Documented where? Neither the on-line documentation nor the function
> | docstring mentions anything about it that I can see:
> | 
> | http://docs.python.org/py3k/library/os.html#os.system
> 
> My copy of the 2.7 docs says:
> 
>   This is implemented by calling the Standard C function system(), and
>   has the same limitations.
> 
> and sure enough, "man 3 system" says:

I don't consider having to look up documentation for a function in a
completely different language (in this case, C) as "documented behaviour of
os.system". 

Does the C standard define the behaviour of system(), or is that
implementation dependent? It sounds to me that the Python developers are
implicitly refusing responsibility for the detailed behaviour of os.system
by noting that it depends on the C function. What do Jython, PyPy and
IronPython do?

Perhaps the docs for os.system should explicitly note that the behaviour is
implementation dependent, rather than just hint at it. Either that or
explicitly state what os.system does.


> os.system() is very convenient for simple stuff, but one size does not
> fit all. 

I never said it does. Back in my first comment on this thread, I said

"Possibly using the subprocess module may help."


> Continuing with the Python docs for os.system: 
> 
>   On Unix, the return value is the exit status of the process encoded in
>   the format specified for wait().
> 
> and it is easy to inspect that value for "the subprocess died from a
> signal". Not inspecting the exit status correctly will always be an
> opportunity for incorrect app behaviour.

Except that the subprocess can catch the KeyboardInterrupt before exiting,
and there's no guarantee that it will return an appropriate error code.

You're right though, os.system is good for simple stuff and not much more.


-- 
Steven

[toc] | [prev] | [next] | [standalone]


#13046

FromChris Angelico <rosuav@gmail.com>
Date2011-09-10 11:37 +1000
Message-ID<mailman.923.1315618676.27778.python-list@python.org>
In reply to#13045
On Sat, Sep 10, 2011 at 11:25 AM, Steven D'Aprano
<steve+comp.lang.python@pearwood.info> wrote:
>>   This is implemented by calling the Standard C function system(), and
>>   has the same limitations.
>>
>> and sure enough, "man 3 system" says:
>
> I don't consider having to look up documentation for a function in a
> completely different language (in this case, C) as "documented behaviour of
> os.system".
>

The Python docs chain to the C docs. It'd be nice to have a link
somewhere, but that's platform-dependent - the online docs could link
to an online man page, but local docs can't, etc. It's fairly normal
for high level languages to expose a lot of C API functions, with all
the concerns and features given. Not a lot of point bloating the
Python docs with every little detail, imho.

ChrisA

[toc] | [prev] | [next] | [standalone]


#13055

FromCameron Simpson <cs@zip.com.au>
Date2011-09-10 18:49 +1000
Message-ID<mailman.928.1315644591.27778.python-list@python.org>
In reply to#13045
On 10Sep2011 11:25, Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote:
| Cameron Simpson wrote:
| > My copy of the 2.7 docs says:
| >   This is implemented by calling the Standard C function system(), and
| >   has the same limitations.
| > and sure enough, "man 3 system" says:
| 
| I don't consider having to look up documentation for a function in a
| completely different language (in this case, C) as "documented behaviour of
| os.system". 

You're kidding, surely? A wrapper function for a system supplied function
should recite everything about the wrapped function's behaviour (including
the system dependent stuff) in the wrapper doco?

| Does the C standard define the behaviour of system(), or is that
| implementation dependent?

The standard specifies the core behaviour - the behaviour guarrenteed to
be present everywhere. Plenty of stuff has platform dependent minor
nuances. As long as portable code relies only on the standard behaviour
everybody wins.

| It sounds to me that the Python developers are
| implicitly refusing responsibility for the detailed behaviour of os.system
| by noting that it depends on the C function.

Of course they are, and they are right to do so. But noting that it
calls the standard function does guarrentee various things about what it
does.

| What do Jython, PyPy and
| IronPython do?
| 
| Perhaps the docs for os.system should explicitly note that the behaviour is
| implementation dependent, rather than just hint at it. Either that or
| explicitly state what os.system does.

I find it hard to understand how anyone can read this text:

  This is implemented by calling the Standard C function system(), and
  has the same limitations

and not imagine it to be dependent on the specification for system().

| > Continuing with the Python docs for os.system: 
| > 
| >   On Unix, the return value is the exit status of the process encoded in
| >   the format specified for wait().
| > 
| > and it is easy to inspect that value for "the subprocess died from a
| > signal". Not inspecting the exit status correctly will always be an
| > opportunity for incorrect app behaviour.
| 
| Except that the subprocess can catch the KeyboardInterrupt before exiting,

This is very true, though such programs usually have a special reason to
do so - the default aborting behaviour is often sufficient.

| and there's no guarantee that it will return an appropriate error code.

Of course. However, the subprocess should still exit with a nonzero exit
status (unless it it written badly). If the caller considers success of
the called program to be important, it should probably be aborting if
the returned value is nonzero anyway.

But yeah, people should probably be reaching for subprocess if they want
to notice SIGINT specially.

Cheers,
-- 
Cameron Simpson <cs@zip.com.au> DoD#743
http://www.cskk.ezoshosting.com/cs/

But pessimism IS realism!       - D.L.Bahr

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.python


csiph-web