I have to run terminal codes via os.system()
in Python. Two commands should be run in two terminals separately. Is it possible to specify a unique name/ID to the terminal windows to run each command in its specified terminal window?
1 Answer
Each terminal you open gets a uniquely numbered file (a pseudoterminal slave (PTS) device to be exact) in /dev/pts/
with whom it can be recognized and addressed. To get the correspondent filename of a terminal window you can use e.g. tty
(see this answer for alternatives; read man pts
for more):
$ tty
/dev/pts/4
You can use this filename for instance to redirect output to a different terminal window like so:
$ echo test >/dev/pts/4 # run anywhere
test # printed in terminal window 4
You can't really run a command in another terminal, simply because it's not the terminal that runs a command, but rather the shell which normally runs in a terminal. You can however emulate the behaviour of a command run in a terminal window with redirections as follows (taken from Linux pseudo-terminals: executing string sent from one terminal in another):
echo test </dev/pts/4 &>/dev/pts/4
If you want to display the command you ran as well I recommand writing a function (How do I use $* while omitting certain input variables like $1 and $2 in bash script?), e.g.:
run_in(){
t=/dev/pts/$1 &&
echo "${*:2}" >$t &&
eval "${@:2}" <$t &>$t
}
In one line:
run_in(){ t=/dev/pts/$1&&echo "${*:2}" >$t&&eval "${@:2}" <$t &>$t;}
Use it like so:
$ run_in 4 echo test # run anywhere
$ echo test # printed in terminal window 4 (if prompt was already there)
test # printed in terminal window 4
In this scenario the only unknown are the /dev/pts/?
numbers that your Python program shall use. One possible way to get these numbers is to launch your own terminal windows, which will output their 'numbers' in to a file, then you can read it [ref]. Let's assume you are using gnome-terminal
, the relevant part of the Python code could be something as follow [ref]:
#!/usr/bin/python
import os
import subprocess
os.system("gnome-terminal -x bash -c 'tty > /tmp/my-app-tty-1; exec bash'")
my_terminal_1 = subprocess.Popen(["cat", "/tmp/my-app-tty-1"], stdout=subprocess.PIPE).communicate()[0]
command = "echo Test on: $(date) >" + my_terminal_1
print my_terminal_1
print command
os.system(command)
If it is a Perl script [ref]
#!/usr/bin/perl
os.system("gnome-terminal -x bash -c 'tty > /tmp/my-app-tty-1; exec bash'");
my $my_terminal_1 = `cat /tmp/my-app-tty-1`;
my $command = "echo Test on: \$\(date\) > $my_terminal_1";
print ("$my_terminal_1");
print ("$command");
os.system("$command");
-
Thanks for your help, Itried to run this command
os.system("echo "+stopDBCommand+" >/dev/pts/20")
in whichstopDBCommand=/home/esarah/workspace/vt -stop /home/esara/workspace/home/mydb
, it prints the command on terminal, but not running it, i should press enter to run it. It is not running the command, but it randomly ran the command once. how to solve this?– sc241Apr 9, 2018 at 20:02 -
@sc241 Did you read my whole post yet? I explained this and provided a solution in the second part of my answer…– dessertApr 9, 2018 at 20:05
-
Appendix: (1) The python program can execute
gnome-terminal --working-directory='/home/<user>/project' -x bash -c "tty > /tmp/my-app-tty-1; exec bash"
to open a new terminal... then we can read the file/tmp/my-app-tty-1
to get thepts
number (reference); (2) We can usetmux
(orscreen
) instead of a terminal (reference).– pa4080Apr 9, 2018 at 20:07 -
1
-
1@sc241,
#!/usr/bin/perl
is shebang. The code that I added is a working example of a Perl script (sorry for the ugly example, this is my first attempt with Perl). Place the lines in to a file (let's call itfile.pl
), make it executable (chmod +x file.pl
), and execute it (./file.pl
) to see the result.run_in()
is a bash function, you can place it in your~/.bashrc
file, then executesource ~/.bashrc
and it will be accessible as shell command. Better idea is to create your own Perl function on its base.– pa4080Apr 9, 2018 at 22:15