I have the following code to receive list of process with sudo:
sudoPass = 'mypass'
command = "launchctl list | grep -v com.apple"
x = os.system('echo %s|sudo -S %s' % (sudoPass, command))
But, I receive answer in int. I need in str. Is it possible to convert it to str without loosing data?
os.system returns (in most cases, see https://docs.python.org/3/library/os.html#os.system) the exit value of the process. Meaning most of the time 0 is everything went fine.
What you look for is the subprocess module (https://docs.python.org/3/library/subprocess.html) that allow you to capture output like so :
import subprocess
sudoPass = 'mypass\n' #Note the new line
command = "launchctl list | grep -v com.apple"
x = subprocess.Popen('echo %s|sudo -S %s' % (sudoPass, command), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
stdout, stderr = x.communicate()
print(stdout)
The command I want to run from my python script is:
tool-manager-cli -a "somexml.xml" -c "another.xml"
My python code is:
command1 = """ tool-manager-cli -a "somexml.xml" -c "another.xml" """
subprocess.Popen(command1)
However when I run my py script, I get SyntaxError: invalid syntax as my error for this line.
How can I specify quotes(" ") in my string text without closing it or invalid syntax?
Try using single quotes to differentiate like so
command1 = """ tool-manager-cli -a 'somexml.xml' -c 'another.xml' """
You can use format method to structure your command:
command1= "{} {} {} {} {}".format("tool-managel-cli","-a", "somexml.xml","-c","another.xml")
subprocess.Popen(command1)
You can also concat by + , but its tedious ofcourse
command1 ="tool-manager-cli"+" -a"+ " somexml.xml" + " -c "+" another.xml"
I'm trying to execute 10 python scripts from python code and open each of them in a new shell window.
My code :
for i in range(10):
name_of_file = "myscript"+str(i)+".py"
cmd = "python " + name_of_file
os.system("gnome-terminal -e 'bash -c " + cmd + "'")
But each script file are not executing, I get only the live interpreter of python in the new terminal...
Thank you guys
I would suggest using the subprocess module (https://docs.python.org/2/library/subprocess.html).
In this way, you'll write something like the following:
import subprocess
cmd = ['gnome-terminal', '-x', 'bash', '-c']
for i in range(10):
name_of_file = "myscript"+str(i)+".py"
your_proc = subprocess.Popen(cmd + ['python %s' % (name_of_file)])
# or if you want to use the "modern" way of formatting string you can write
# your_proc = subprocess.Popen(cmd + ['python {}'.format(name_of_file)])
...
and you have more control over the processes you start.
If you want to keep using os.system(), build your command string first, then pass it to the function. In your case would be:
cmd = 'gnome-terminal -x bash -c "python {}"'.format(name_of_file)
os.system(cmd)
something along these lines.
Thanks to #anishsane for some suggestions!
I think that it is to do with the string quoting of the argument to os.system. Try this:
os.system("""gnome-terminal -e 'bash -c "{}"'""".format(cmd))
Basically, it's a python code from our collaborator that used to generate mesh, which is developed under Linux environment. I use Cygwin to run this code on windows. The trouble part is as follows. BiV_temp.geo is also a python script. So the command is to substitute the string <> in the script BiV_temp.geo with a predefined number and the file names.
os.system('cp BiV_fiber.geo BiV_temp.geo')
cmd = "sed -i 's/<<Meshsize>>/"+"%5.2f"%(meshsize)+"/g' BiV_temp.geo"
os.system(cmd)
cmd = "sed -i 's/<<LVfilename>>/"+"\"%s\""%(LVendocutfilename)+"/g' BiV_temp.geo"
os.system(cmd)
cmd = "sed -i 's/<<RVfilename>>/"+"\"%s\""%(RVendocutfilename)+"/g' BiV_temp.geo"
os.system(cmd)
cmd = "sed -i 's/<<Epifilename>>/"+"\"%s\""%(epicutfilename)+"/g' BiV_temp.geo"
os.system(cmd)
cmd = "gmsh -3 BiV_temp.geo -o %s"%(mshfilename)
os.system(cmd)
cmd = "rm BiV_temp.geo"
os.system(cmd)
The sane solution is for your "collaborator" to write Python code which allows you to pass in these things as parameters to a function call.
you are trying to executing command code in python?
and i notice in "%5.2f"%(meshsize) you wrote %5, for adding text you should add %sand also avoid putting plus sign, it make it really hard to read and messy, i would write all in one line like this:
meshsize = 100
cmd = "sed -i 's/<<Meshsize>>/%s5.2f/g' BiV_temp.geo" %meshsize
print cmd
if your meshsize is a list of x,y,z then write it like this:
meshsize = (100,50,20)
cmd = "sed -i 's/<<Meshsize>>/%s,%s,%s5.2f/g' BiV_temp.geo" %meshsize
print cmd
hope that help.
I'm writing a small method to replace some text in a file.
The only argument I need is the new text, as it is always the same file and text to be replaced.
I'm having a problem using the os.system() call, when I try to use the argument of the method
If I use a string like below, everything runs ok:
stringId = "GRRRRRRRRR"
cmd="sed '1,$s/MANAGER_ID=[0-9]*/MANAGER_ID=" + stringId + "/g' path/file.old > path/file.new"
os.system(cmd)
Now, if i try to give a string as a parameter like below, the command is not executed.
I do a print to see if the command is correct, and it is. I can even execute it with success if I copy / paste to my shell
import os
def updateExportConfigId(id):
stringId = "%s" % id
cmd= "sed '1,$s/MANAGER_ID=[0-9]*/MANAGER_ID=" + stringId + "/g' path/file.old > path/file.new"
print "command is " + cmd
os.system(cmd)
Does anyone knows what is wrong?
Thanks
Obligatory: don't use os.system - use the subprocess module:
import subprocess
def updateExportConfigId(m_id, source='path/file.old',
destination='path/file.new'):
if isinstance(m_id, unicode):
m_id = m_id.encode('utf-8')
cmd= [
"sed",
",$s/MANAGER_ID=[0-9]*/MANAGER_ID=%s/g" % m_id,
source,
]
subprocess.call(cmd, stdout=open(destination, 'w'))
with this code you can pass the manager id, it can have spaces, quote chars, etc. The file names can also be passed to the function, and can also contain spaces and some other special chars. That's because your shell is not unnecessarly invoked, so one less process is started on your OS, and you don't have to worry on escaping special shell characters.
Another option: Don't launch sed. Use python's re module.
import re
def updateExportConfigID(m_id, source, destination):
if isinstance(m_id, unicode):
m_id = m_id.encode('utf-8')
for line in source:
new_line = re.sub(r'MANAGER_ID=\d*',
r'MANAGER_ID=' + re.escape(m_id),
line)
destination.write(new_line)
and call it like this:
updateExportConfigID('GRRRR', open('path/file.old'), open('path/file.new', 'w'))
No new processes needed.
To help you debug it, try adding:
print repr(cmd)
It might be that some special characters slipped into the command that normal print is hiding when you copy and paste it.
Maybe some indentation problem?
The following works correctly:
import os
def updateExportConfigId(id):
stringId = "%s" % id
cmd= "sed '1,$s/MANAGER_ID=[0-9]*/MANAGER_ID=" + stringId + "/g' test.dat > test.new"
print "command is " + cmd
os.system(cmd)
updateExportConfigId("adsf")
Also do not use reserved words (id) as variables.
What is wrong is that there is some difference. Yeah, I know that's not helpful, but you need to figure out the difference.
Try running this:
import os
def updateExportConfigId(id):
stringId = "%s" % id
cmd1 = "sed '1,$s/MANAGER_ID=[0-9]*/MANAGER_ID=" + stringId + "/g' path/file.old > path/file.new"
stringId = "GRRRRRRRRR"
cmd2 = "sed '1,$s/MANAGER_ID=[0-9]*/MANAGER_ID=" + stringId + "/g' path/file.old > path/file.new"
print "cmd1:" , cmd1
print "cmd2:" , cmd2
print cmd1 == cmd2
updateExportConfigId("GRRRRRRRRR")
The code should print:
sed '1,$s/MANAGER_ID=[0-9]*/MANAGER_ID=GRRRRRRRRR/g' path/file.old > path/file.new
sed '1,$s/MANAGER_ID=[0-9]*/MANAGER_ID=GRRRRRRRRR/g' path/file.old > path/file.new
True
Thereby showing that they are exactly the same. If the last line is "False" then they are not the same, and you should be able to see the difference.
So from previous answers we now know that id is a Unicode string, which makes cmd1 a Unicode string, which os.system() is converting to a byte string for execution in the default encoding.
a) I suggest using subprocess rather than os.system()
b) I suggest not using the name of a built-in function as a variable (id).
c) I suggest explicitly encoding the string to a byte string before executing:
if isinstance(cmd,unicode):
cmd = cmd.encode("UTF-8")
d) For Lennart Regebro's suggestion add:
assert type(cmd1) == type(cmd2)
after
print cmd1 == cmd2
Maybe it helps to use only raw strings.
Finally, I found a way to run the os.system(cmd)!
Simple trick, to "clean" the cmd string:
os.system(str(cmd))
Now, I'm able to build the cmd with all arguments I need and at the end I just "clean" it with str() call before run it with os.system() call.
Thanks a lot for your answers!
swon