Linux: xterm - starting window as always on top - python

I am intresting in launching an xterm window from python code in following way:
cmd = './my_task'
subprocess.Popen(['xterm', '-t', 'my_task', '-e', cmd])
However, I want this xterm session to be set to always on top from command line.
One way I was able to do this is by doing this:
cmd = 'wmcntl -r 'my_task' -b add,above; ./my_task'
subprocess.Popen(['xterm', '-t', 'my_task', '-e', cmd])
But this requires the machine to have wmctrl installed.
Is there a standard way of doing this (I don't need a cross platform solution, just for Linux)
Thanks,
Itay

Related

How do I pass inputs to cmd prompt after I have run the os.system command?

I am trying to start kafka producer via cmd prompt (I have kube installed in my local). This is the code that I am using :
os.system('cmd /k "kubectl run kafka-producer152 -ti --image=strimzi/kafka:0.18.0-kafka-2.4.0 --rm=true --restart=Never -- bin/kafka-console-producer.sh --broker-list 17.148.115.9:32033 --topic ship"')
The topic is 'ship'.The command executes by running the producer command given above.
What should be done if I want the command to be executed (which it does now) and fetch all the data (inputs) from a file stored in same directory (values.txt) and enter those values only after executing the above kubectl command int the same cmd window.
I'm not a Windows person (thank goodness) but I think the following should do what you are asking.
import subprocess
with open(r'C:\razy\windows\path\values.txt') as values:
subprocess.run(['kubectl', 'run', 'kafka-producer152',
'-ti', '--image=strimzi/kafka:0.18.0-kafka-2.4.0',
'--rm=true', '--restart=Never',
'--', 'bin/kafka-console-producer.sh',
'--broker-list', '17.148.115.9:32033',
'--topic', 'ship'],
stdin=values,
# probably not
#cwd=r'c:\razy\windows\path',
# probably yes
check=True, text=True)

Open new gnome-terminal and run command

I'm trying to write a script that opens a new terminal then runs a separate python script from that terminal.
I've tried:
os.system("gnome-terminal 'python f.py'")
and
p = Popen("/usr/bin/gnome-terminal", stdin=PIPE)
p.communicate("python f.py")
but both methods only open a new terminal and do not run f.py. How would I go about opening the terminal AND running a separate script?
Edit:
I would like to open a new terminal window because f.py is a simply server that is running serve_forever(). I'd like the original terminal window to stay "free" to run other commands.
Like most terminals, gnome terminal needs options to execute commands:
gnome-terminal [-e, --command=STRING] [-x, --execute]
You probably need to add -x option:
x, --execute
Execute the remainder of the command line inside the terminal.
so:
os.system("gnome-terminal -x python f.py")
That would not run your process in the background unless you add & to your command line BTW.
The communicate attempt would need a newline for your input but should work too, but complex processes like terminals don't "like" being redirected. It seems like using an interactive tool backwards.
And again, that would block until termination. What could work would be to use p.stdin.write("python f.py\n") to give control to the python script. But in that case it's unlikely to work.
So it seems that you don't even need python do to what you want. You just need to run
python f.py &
in a shell.
As of GNOME Terminal 3.24.2 Using VTE version 0.48.4 +GNUTLS -PCRE2
Option “-x” is deprecated and might be removed in a later version of gnome-terminal.
Use “-- ” to terminate the options and put the command line to execute after it.
Thus the preferred syntax appears to be
gnome-terminal -- echo hello
rather than
gnome-terminal -x echo hello
Here is a complete example of how you would call a executable python file with subprocess.call Using argparse to properly parse the input.
the target process will print your given input.
Your python file to be called:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--file", help="Just A test", dest='myfile')
args = parser.parse_args()
print args.myfile
Your calling python file:
from subprocess import call
#call(["python","/users/dev/python/sandboxArgParse.py", "--file", "abcd.txt"])
call(["gnome-terminal", "-e", "python /users/dev/python/sandboxArgParse.py --file abcd.txt"])
Just for information:
You probably don't need python calling another python script to run a terminal window with a process, but could do as follows:
gnome-terminal -e "python /yourfile.py -f yourTestfile.txt"
The following code will open a new terminal and execute the process:
process = subprocess.Popen(
"sudo gnome-terminal -x python f.py",
stdout=subprocess.PIPE,
stderr=None,
shell=True
)
I am running a uWS server with this.In my case Popen didn't help(Even though it run the executable, still it couldn't communicate with a client -: socket connection is broken).This is working.Also now they recommends to use "--" instead of "-e".
subprocess.call(['gnome-terminal', "--", "python3", "server_deployment.py"])
#server_deployment.py
def run():
execution_cmd = "./my_executable arg1 arg2 dll_1 dll_2"
os.system(execution_cmd)
run()

xterm -e - do not close xterm after command

I had wrote scirpt in python which execute bash command using system.os("cmd"). I wouldn't like to have output of bash script on same terminal what I have python script output, so I execute bash command via xterm -e. My code is similar to this:
# python
import os
os.system("xterm -e 'ls'")
This code works but after ls end the new terminal disappear. I want to have stay this terminal.
You can let the the window stay until the user presses a key with read:
os.system("xterm -e 'ls; read'")
or you just run a new terminal of xterm which runs until it is closed:
os.system("xterm")
Note 1: The os.system function seems to block the python script until the external process (xterm in this case) has finished. So you can use it in a loop where each bash window has to be closed before a new one is opened.
Note 2: the python documentation suggests to use subprocess.call
The following should work. I tried it on a Mint linux box.
import os
os.system("xterm -hold -e 'ls' &")
It's almoust good, but:
import os
os.system("xterm -hold -e 'my_cmd_1' &")
os.system("xterm -hold -e 'my_cmd_2' &")
my_cmd_2 can not start before my_cmd_end_1

Python subprocess communication

I'm trying to run a python script that will open a command prompt(OSGeo4W.bat is a command prompt line). I can get it to open but now I would like to send the command prompt commands.
import subprocess
myProcess = subprocess.Popen(['C:\OSGeo4W64\OSGeo4W.bat'],shell = False) #opens command prompt
myProcess.communicate('gdal2tiles -p raster -z 0-1 new.jpg abc')
myProcess.wait()
print("my process has terminated")
I've also tried
subprocess.check_call('gdal2tiles -p raster -z 0-1 new.jpg abc', shell=False)
I keep getting errors that say "WindowsError: [Error 2] The system cannot find the file specified"
although, if I were to keep the command prompt that it opens and type in " 'gdal2tiles -p raster -z 0-1 new.jpg abc' " then it will work just as I wanted. Help would be great, thanks!
Try:
check_call('gdal2tiles -p raster -z 0-1 new.jpg abc', shell=True)
shell=True changes how the executable is searched on Windows.
Or if gdal2tiles works only in the environment created by OSGeo4W.bat:
shell = Popen(r'C:\OSGeo4W64\OSGeo4W.bat', stdin=subprocess.PIPE)
shell.communicate('gdal2tiles -p raster -z 0-1 new.jpg abc')
# you don't need shell.wait() here
Notice: r"" literal. It is necessary to avoid escaping the backslashes in the path.
For those of you that are still trying to figure this one out, this is what I found. The "stdin=subprocess.PIPE" method above works with some command line tool in OSGeo4W64 but not all. It works with gdal_translate but not pdal translate for example. Not sure why;(
My Solution:
OSGeo4Wenv = r'CALL "C:/OSGeo4W64/bin/o4w_env.bat" '
pdal_translate_String = r'c:/OSGeo4W64/bin/pdal translate c:\inputFile c:\outputFile radiusoutlier --filters.radiusoutlier.min_neighbors=2 --filters.radiusoutlier.radius=8.0 --filters.radiusoutlier.extract=true'
Cmd = str(OSGeo4Wenv)+' & '+str(pdal_translateCmd)
shell = subprocess.call(Cmd, stdout=None, shell=True)
What is going on?
1) Open shell and set up the OSGeo4W environment by calling "OSGeo4Wenv". This is normally called by the OSGeo4W.bat file. Without this, the command line programs don't know where to look for the libraries.
2) The pdal_translate command is then sent to the dos shell because in Windows, multiple commands can be separated by the "&" symbol. I use the .call method of python 2.7. It has the advantage that it waits for the end of the process. That is nice if you use the multiprocessing map.pool method to launch multiple processes at the same time.
Hope this help others!
Nicolas

Start a process in a different console window

How can I start a process to run in a different console window using Python in Linux, something similar to this in windows(using start):
import os
os.system('start dir c:\*.* /s')
xterm -e should do the trick for you.
-e program [ arguments ... ]
This option specifies the program (and its command line arguments) to be
run in the xterm window. It also sets
the window title and icon name to be
the basename of the program being
executed if neither -T nor -n are
given on the command line. This must
be the last option on the command
line.
E.g.
import os
os.system("xterm -e 'your command'")

Categories

Resources