2

I have a python script that needs to call the defined $EDITOR or $VISUAL. When the Python script is called alone, I am able to launch the $EDITOR without a hitch, but the moment I pipe something to the Python script, the $EDITOR is unable to launch. Right now, I am using nano which shows

Received SIGHUP or SIGTERM

every time. It appears to be the same issue described here.

sinister:Programming [1313]$ echo "import os;os.system('nano')" > "sample.py" 
sinister:Programming [1314]$ python sample.py
# nano is successfully launched here.
sinister:Programming [1315]$ echo "It dies here." | python sample.py 
Received SIGHUP or SIGTERM

Buffer written to nano.save.1

EDIT: Clarification; inside the program, I am not piping to the editor. The code is as follows:

editorprocess = subprocess.Popen([editor or "vi", temppath])
editorreturncode = os.waitpid(editorprocess.pid, 0)[1]
Community
  • 1
  • 1
Eric Pruitt
  • 1,825
  • 3
  • 21
  • 34

2 Answers2

4

When you pipe something to a process, the pipe is connected to that process's standard input. This means your terminal input won't be connected to the editor. Most editors also check whether their standard input is a terminal (isatty), which a pipe isn't; and if it isn't a terminal, they'll refuse to start. In the case of nano, this appears to cause it to exit with the message you included:

% echo | nano
Received SIGHUP or SIGTERM

You'll need to provide the input to your Python script in another way, such as via a file, if you want to be able to pass its standard input to a terminal-based editor.

Now you've clarified your question, that you don't want the Python process's stdin attached to the editor, you can modify your code as follows:

editorprocess = subprocess.Popen([editor or "vi", temppath],
                                 stdin=open('/dev/tty', 'r'))
Nicholas Riley
  • 43,532
  • 6
  • 101
  • 124
  • @eric, But `echo hi | vidir` still fails, same as your script. `echo hi | mutt` doesn't even try to start the editor, it tries to run in `mail(1)`-like fashion... – sarnold May 13 '11 at 02:28
  • Well, you can feel free to rewrite your kernel, but seriously, that's how Unix-like OSes work. When `mutt` spawns an editor, it uses a temporary file for exactly this reason. – Nicholas Riley May 13 '11 at 02:31
  • @sarnold try `vidir -` instead; `find -type f | vidir -` – Eric Pruitt May 13 '11 at 02:32
  • `vidir` uses `/dev/tty`, which may not work everywhere, but if you don't mind that, close standard input and reopen it with that file. – Nicholas Riley May 13 '11 at 02:35
  • @Nicholas I am using a temporary file; inside the program I call ["nano", tempfile] and that still doesn't fix the issue. I am not piping to the editor. – Eric Pruitt May 13 '11 at 02:36
  • @Nicholas how do I go about replicating the `/dev/tty` usage in vidir? I looked at the source code, but I am unable to functionally replicate it in Python. – Eric Pruitt May 13 '11 at 02:51
  • @Eric: See my edited answer. It's pretty simple to do it. (When in doubt, more information and code is always better :-) – Nicholas Riley May 13 '11 at 03:08
  • @Nicholas Thanks. I was doing it the os.open way as shown in sarnold's post, but I was trying `sys.std = os.open(...)`. – Eric Pruitt May 13 '11 at 03:32
2

The specific case of find -type f | vidir - is handled here:

foreach my $item (@ARGV) {
    if ($item eq "-") {
        push @dir, map { chomp; $_ } <STDIN>;
        close STDIN;
        open(STDIN, "/dev/tty") || die "reopen: $!\n";
    }

You can re-create this behavior in Python, as well:

#!/usr/bin/python

import os
import sys

sys.stdin.close()
o = os.open("/dev/tty", os.O_RDONLY)
os.dup2(o, 0)
os.system('vim')

Of course, it closes the standard input file descriptor, so if you intend on reading from it again after starting the editor, you should probably duplicate its file descriptor before closing it.

sarnold
  • 102,305
  • 22
  • 181
  • 238
  • This works as well, but I am marking Nicholas' reply as the preferred solution since it does not require stdin to be closed. Thank you. – Eric Pruitt May 13 '11 at 03:38
  • @Eric, yeah, his answer struck me as quite elegant when I saw it :) more useful for library routines. – sarnold May 13 '11 at 03:41