Python not recognizing the greater than sign? - python

I am using Python to create windows commands using subprocess.call(command) where command is a string I've generated for the Windows command. I need the results of my command to output to a .txt file so I use 2>> C:\Users\me\out.txt as part of command except Python does not seem to recognize the greater than character, >. I've tried using the Unicode value, u'\u003E' too.
[EDIT] If I copy command and paste it into my command prompt, then it will execute the command properly. Otherwise it won't work from my Python script.

Python has nothing to do with that.
If you do
subprocess.call("command 2>>out.txt", shell=True)
it is the shell which does this part of redirection.
If you don't work with the shell, it cannot work. In this case, you better do
with open("out.txt", "a") as outfile:
subprocess.call(["command"], stderr=outfile)

If you are using shell constructs such as redirection, you need the parameter shell=True.

Related

why the same powershell command run on the powershell console but not using os.system?

I would like to include a command to create a 7zip archive withinin a Python script. Since I am working on Windows, I need to pass the command to the powershell console. I am planning to do it with os.system (I am aware that this is not the best way to do it and that I should use subprocess, but I really just need a quick fix and it would not be time effective for me to learn to use a new module in this context).
The following command works if run from the powershell console
&'C:\\Program Files\\7-Zip\\7z' a -mx=0 X:/myarch.zip X:/myarch
So I recreate the same string within python like this:
cmdl = r"&'C:\\Program Files\\7-Zip\\7z' a -mx=0 X:/myarch.zip X:/myarch"
The string is interpreted as follow:
"&'C:\\\\Program Files\\\\7-Zip\\\\7z' a -mx=0 X:/myarch.zip X:/myarch"
Now, if I copy-paste the above string within the powershell console, it runs without problems. However, if I run it within python using os.system(cmdl) I got the following error
"The filename, directory name, or volume label syntax is incorrect"
Why is this the case and how can I fix this issue ?
os.system is meant for executing cmd commands, cmd commands can be ran in powershell maybe after all powershell is a bit advanced but I'm sure that you can't run a cmd command in powershell, henceforth your code is not working.
However a creative solution for executing a powershell command from python(not using python) would be to write your command into a .ps file(powershell script)and then run it using os.startfile()(use this code: os.startfile("script.ps"))

Run a script from different folder with arguments in python (like in cmd)

I guess I have to use either use os.system or subprocess.call, but I can't figure out how to use it.
I don't have the permission to edit the original folder.
subprocess.Popen('file.py', cwd=dirName) gives me 'The system cannot find the file specified' even though the file clearly exists
If I was typing in cmd,
cd directory
file.py -arg
Edit: Just to be clear I want to run another script using a python script
As you have tagged the question with cmd, I assume that you use Windows. Windows is kind enough to automatically use the appropriate command when you type a document name in cmd, but Python subprocess is not. So you have 2 possible ways here
use shell=True to ask a cmd interpretor to execute the command:
subprocess.Popen('file.py', cwd=dirName, shell=True)
pass explicitely the path of the Python interpretor (or the name if it is in the path)
subprocess.Popen([python_path, 'file.py'], cwd=dirName, shell=True)
At first you need to add the python in windows environment.
Then you can add the file path (the file that you want to run it on command line).
Then you can go to command line page and type the file name and use it like the line below:
FileName commands
for example :
pip install datetime
Its clear you are probably using python 3 rather than python 2. Otherwise you might use os.system as already suggested or commands. Commands is now obsolete as of python 3. To get this working I would use instead:
statusAndOutputText = subprocess.getstatusoutput( os.path.join( dirName, 'file.py' ) )
This will definitely work. I've used it many times in python 3 and it will give you the status in statusAndOutputText[0] and output buffer in statusAndOutputText[1] which are both very useful to have.

Execute bash script from Python on Windows

I am trying to write a python script that will execute a bash script I have on my Windows machine. Up until now I have been using the Cygwin terminal so executing the bash script RunModels.scr has been as easy as ./RunModels.scr. Now I want to be able to utilize subprocess of Python, but because Windows doesn't have the built in functionality to handle bash I'm not sure what to do.
I am trying to emulate ./RunModels.scr < validationInput > validationOutput
I originally wrote this:
os.chdir(atm)
vin = open("validationInput", 'r')
vout = open("validationOutput", 'w')
subprocess.call(['./RunModels.scr'], stdin=vin, stdout=vout, shell=True)
vin.close()
vout.close()
os.chdir(home)
But after spending a while trying to figure out why my access was denied, I realized my issue wasn't the file permissions but the fact that I was trying to execute a bash file on Windows in general. Can someone please explain how to execute a bash script with directed input/output on windows using a python script?
Edit (Follow up Question):
Thanks for the responses, I needed the full path to my bash.exe as the first param. Now however, command line calls from within RunModels.scr come back in the python output as command not found. For example, ls, cp, make. Any suggestions for this?
Follow up #2:
I updated my call to this:
subprocess.call(['C:\\cygwin64\\bin\\bash.exe', '-l', 'RunModels.scr'], stdin=vin, stdout=vout, cwd='C:\\path\\dir_where_RunModels\\')
The error I now get is /usr/bin/bash: RunModels.scr: No such file or directory.
Using cwd does not seem to have any effect on this error, either way the subprocess is looking in /usr/bin/bash for RunModels.scr.
SELF-ANSWERED
I needed to specify the path to RunModels.scr in the call as well as using cwd.
subprocess.call(['C:\\cygwin64\\bin\\bash.exe', '-l', 'C:\\path\\dir_where_RunModels\\RunModels.scr'], stdin=vin, stdout=vout, cwd='C:\\path\\dir_where_RunModels\\')
But another problem...
Regardless of specifying cwd, the commands executed by RunModels.scr are throwing errors as if RunModels.scr is in the wrong directory. The script executes, but cp and cd throw the error no such file or directory. If I navigate to where RunModels.scr is through the command line and execute it the old fashioned way I don't get these errors.
Python 3.4 and below
Just put bash.exe in first place in your list of subprocess.call arguments. You can remove shell=True, that's not necessary in this case.
subprocess.call(['C:\\cygwin64\\bin\\bash.exe', '-l', 'RunModels.scr'],
stdin=vin, stdout=vout,
cwd='C:\\path\\dir_where_RunModels\\')
Depending on how bash is installed (is it in the PATH or not), you might have to use the full path to the bash executable.
Python 3.5 and above
subprocess.call() has been effectively replaced by subprocess.run().
subprocess.run(['C:\\cygwin64\\bin\\bash.exe', '-l', 'RunModels.scr'],
stdin=vin, stdout=vout,
cwd='C:\\path\\dir_where_RunModels\\')
Edit:
With regard to the second question, you might need to add the -l option to the shell invocation to make sure it reads all the restart command files like /etc/profile. I presume these files contain settings for the $PATH in bash.
Edit 2:
Add something like pwd to the beginning of RunModels.scr so you can verify that you are really in the right directory. Check that there is no cd command in the rc-files!
Edit 3:
The error /usr/bin/bash: RunModels.scr: No such file or directory can also be generated if bash cannot find one of the commands that are called in the script. Try adding the -v option to bash to see if that gives more info.
A better solution than the accepted answer is to use the executable keyword argument to specify the path to your shell. Behind the curtain, Python does something like
exec([executable, '-c`, subprocess_arg_string])
So, concretely, in this case,
subprocess.call(
'./RunModels.scr',
stdin=vin, stdout=vout,
shell=True,
executable="C:/cygwin64/bin/bash.exe")
(Windows thankfully lets you use forward slashes instead of backslashes, so you can avoid the requirement to double the backslashes or use a raw string.)

Use Python to run a .exe file in Windows Command Prompt

I am trying to integrate an existing program into a developing Python 2.7 script. Currently the program can be successfully run by typing the following in the command prompt:
`C:\wisdem\plugins\JacketSE\src\jacketse\SubDyn\bin\SubDyn_Win32.exe C:\wisdem\plugins\JacketSE\src\jacketse\SubDyn\CertTest\Test04_TrialD3.txt`
This is all one line; the .txt file contains inputs needed by the .exe file. I have tried using both os.system("C:\wisdem\plugins\...) and
subprocess.Popen("C:\wisdem\plugins\...", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE).stdout.read()
to do this, but neither one is working. Also, I need the command prompt's outputs to be printed Python. Any help would be greatly appreciated!
import os
print os.popen(r'''echo "hello"''').read()
I would suggest putting the full command within the triple quotes, and attempting. This will execute the command, and then print the output.
Using a String literal with prefix r should help with any weird escape character issues you are experiencing.
Please note that there are security concerns when using the above code as well as os.popen being Deprecated since version 2.6. However, for a quick local script in 2.7, the above will suffice.

Opening IDLE from another Python script with command line paramteters

I am looking to open a Python script in edit mode in IDLE by passing in a directory from another Python script. I understand that I can use os.system to execute idle.py but I then don't know how to pass the appropriate -e parameter and get it to use a specific directory i.e. open something.py in diredtory C:\Python all from the original Python script.
Thanks for your help,
Ben
You can use subprocess.call(). By setting shell = True, the function treats the string as a literal shell command. Modify the paths as you see fit.
import subprocess
subprocess.call(r'C:\Python27\Lib\idlelib\idle.py -e C:\Python27\something.py',
shell=True)

Categories