4

What is the equivalent of xfce4-terminal -e bash -c 'myCommand' that doesn't start a new process with the terminal, but that still opens a new terminal window for the output (which will also need to take input)? I want the original terminal (which isn't visible, anyway) to halt until the new visible one is done.

Let's say I have a Python GUI that calls the aforementioned command. I want the Python script to halt while the newly opened terminal window runs its command, and to continue after it stops.

EDIT: In response to requests for more information about my situation, here it is, more specifically:

I've made an IDE, using Python 3.x, with Tkinter as the GUI. There is no terminal window open simply because it's a GUI-based program (and if there were, it would be in the background, anyway, and no one would have a particular reason to know to look and see whether it was saying anything, since the whole IDE is in a GUI).

I'm making an option to asymmetrically encrypt selected text using the gpg command-line tool (which is more convenient and documented than the Python modules for my other more prominent uses of it, which are beyond the scope of this question; plus there aren't as many licensing issues with using compiled binaries). For symmetric encryption, I don't have a problem because I don't need an open terminal window, but asymmetric encryption tends to prompt for more stuff that may or may not be important, and the user needs to respond to those prompts.

The text to be encrypted is saved to a temporary file, and gpg is to encrypt the whole file (since the text may be arbitrarily long and that might cause problems if it were outputted to a terminal instead of saved to a file).

So, when the user selects text and executes the method, I want a terminal window to pop up with the prompt from gpg. Ideally, the user would say yes or no, and press enter, and the terminal window would disappear; then the selected text would be replaced with asymmetrically encrypted text. However, what actually happens is the terminal window pops up and the program attempts to get the encrypted text before it's actually encrypted (because it doesn't wait for the user to input anything). I do not want the user to have to manually tell the IDE that it's time to encrypt it after saying yes or no.

You might think you could use pipes to route GUI-based user input to the hidden terminal. However, such as y | gpg -a --encrypt --recipient [email protected] tempFile.txt does not work for some odd reason.

4
  • 1
    I have the feeling that you are not asking the real problem, just the solution you have in mind. Describe why you need this. See meta.stackexchange.com/questions/66377/what-is-the-xy-problem
    – SPRBRN
    Jan 20, 2016 at 8:24
  • Try xfce4-terminal -e bash -c 'myCommand;bash' to remain terminal open
    – Pandya
    Jan 20, 2016 at 13:36
  • 1
    @SPRBRN I responded to your concern in an edit to my question. Jan 22, 2016 at 11:11
  • 1
    @Shule - thanks! Giving this information makes the question a lot better. We can stop wondering and spend our energy on the problem, or not if we don't know it, like me. It takes up a lot more time to create such a question, but sometimes writing that out will save you time when a good answer arrives sooner. And sometimes writing it out helps you to figure the problem out yourself. I've had that many times.
    – SPRBRN
    Jan 22, 2016 at 11:44

2 Answers 2

4

When you run a new terminal emulator, that creates a new terminal (/dev/pts/NUMBER on Linux). A program doesn't have to be started by that terminal to output there (try running tty in a terminal, then in another terminal run echo hello >/dev/pts/NUMBER). So you can tell your Python script to read and write from the terminal; all you need is to find out the path to the device file.

With xterm, it's pretty easy: run xterm -e 'tty >&3; myCommand' with file descriptor 3 connected to a pipe from which your program reads the path to the terminal device.

p = subprocess.Popen("xterm -e 'tty >&3; exec sleep 99999999' 3>&1",
                     shell=True, stdout=subprocess.PIPE)
tty_path = readline(p.stdout)
tty = open(tty_path, 'r+')

Your Python program can now read and write to tty. When you've finished, kill the terminal emulator (os.kill(p.pid, signal.SIGTERM)).

With a terminal emulator that's based on a single process for multiple windows such as xfce4-terminal, what you want to do is considerably harder. Running xfce4-terminal breaks links between the parent process and the child of the terminal emulator, and doesn't give you a nice PID that you can kill. You could use a named pipe to communicate but it's a bot harder to set up.

1

Seems like what you should do is exactly the opposite of the way you hope to achieve it. For example - why is your python terminal not visible anyway? It seems to me like that is the terminal you ought to use, and not muck around with grabbing some new one.

This how I think I would do it:

  1. Start a -monitoring shell in your original terminal.

  2. Iconify the terminal window.

  3. Start your Python thing.

  4. When you would otherwise call up your second terminal, instead have Python send itself a SIGSTOP.

  5. Show the terminal.

  6. Call your command.

  7. When it completes, hide your terminal again and fg your Python.

6
  • I responded to your question about why the terminal is not visible in an edit to my question. Also, note that it's not a Python terminal (but Python is launching the terminal). Jan 22, 2016 at 11:12
  • @Shule - I didn't mean it was a Python terminal - I don't know if there is such a thing - but I still don't understand why you don't just do the simple thing and suspend to the host terminal and after resume. You're using Tkinter - just foreground the backgrounded terminal window. That's super simple, and no hassles about window mangers/versions.
    – mikeserv
    Jan 22, 2016 at 11:32
  • No worries. If I had a terminal window open that would probably be great. However, the problem is that I don't want a background terminal window to be open in the first place (although as a programmer of the IDE, it's nice for displaying errors, but for regular users, it would just be extra clutter that they would only ever use with this feature of the program). That would be kind of like requiring a terminal window to be opened with your web browser, or a calculator program. I don't know if I'm understanding what you mean, exactly, though. Jan 22, 2016 at 11:44
  • I'm thinking about just requiring users to have any keys they use be signed and trusted so they won't have to give any input. Jan 22, 2016 at 11:45
  • 1
    @Shule - But wouldn't you just iconify it? Maybe not - whatever works you know. If it is a whole IDE then you ought to be able to spawn terminals - I agree. And for that sort of thing the xterm solution is probably ideal. You should also look at its -S option in that vein as well, I think.
    – mikeserv
    Jan 22, 2016 at 11:48

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .