Write commands with python and execute in powershell - python

I have a python script that builds commands based off input gotten via rest.
The commands work when printed out and copied and pasted into powershell.
My question is how to make it actually execute the commands?
So far I have tried writing the commands to a file in the same directory and running like so:
import subprocess, sys
p = subprocess.Popen(["powershell.exe", "test.ps1"],stdout=sys.stdout)
p.communicate()
But I get an error:
Traceback (most recent call last): File
"C:/Users/pschaefer/src/python/executePowerShell.py", line 2, in
p = subprocess.Popen(["powershell.exe", "test.ps1"],stdout=sys.stdout) File "C:\Python27\lib\subprocess.py",
line 703, in init
errread, errwrite), to_close = self._get_handles(stdin, stdout, stderr) File "C:\Python27\lib\subprocess.py", line 850, in
_get_handles
c2pwrite = msvcrt.get_osfhandle(stdout.fileno()) UnsupportedOperation: fileno
Update
removing ,stdout=sys.stdout1 gets rid of the previous error and now I see
test.ps1 cannot be loaded because running \r\nscripts is disabled on
this system.
I have tried switching the command to ".\\test.ps1 Set-ExecutionPolicy -ExecutionPolicy unrestricted" and still have the issue.
Also, would it be possible to build the commands as strings and execute them one by one as built instead of creating a .ps1 file? Big kudos to anyone that can figure that out!

Is your machine you are running the script on enabled to run powershell scripts? You can set this via the Set-ExecutionPolicy cmdlet, or you can pass the -ExecutionPolicy Bypass parameter to run the script with lowered permissions.

Running such scripts from an IDE isn't supported because IDEs redirect stdout to their own stream, which doesn't support fileno properly most of the time.
Running those commands in a real system shell works, though.
The workaround which works in both shell & IDE is to remove stdout=sys.stdout but you can't get the error messages or retrieve the output, or even better: redirect the output/error streams using Popen capabilities:
import subprocess, sys
p = subprocess.Popen(["powershell.exe", "test.ps1"],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
out,err = p.communicate()
print(out,err)
on my machine, since test.ps1 doesn't exist, I get a clear powershell error message.
EDIT: my answer doesn't answer to your edit of your question which shows the actual error message now. This Q&A may help you: PowerShell says "execution of scripts is disabled on this system."

Related

execute a command from remotedly using paramiko

I have board server, in which i want to execute a gstreamer command from parmiko which will take the input file as a argument
this one is working
stdin,stdout,stderr=ssh_client.exec_command('ls')
want to execute below command but not working
stdin,stdout,stderr=ssh_client.exec_command('gst_app /media/card/pipeline.cfg')
want to execute a gst_app /media/card/pipeline.cfg command from ssh_client.exec_command
can anyone please help
If a command does not work, start by reading its error output.
Use stderr.readlines() for that.
Quite often the error is "<command> not found". For that see
Some Unix commands fail with "<command> not found", when executed using Python Paramiko exec_command

Passing absolute paths to subprocess.call() [Python]

I'm working on a script that should call an external executable file, which takes a path as an argument(and generates another file). I used the following syntax:
call(['C:/program.exe', 'C:/input.txt'])
It should generate an output.txt in the same directory.
My problem is that I don't get any output, or error message. If I run that command manually in cmd, everything works fine.
How can I solve this?
You could use Popen to get an error message.
from subprocess import PIPE, Popen
Popen(['C:/program.exe', 'C:/input.txt'], stdout=PIPE)
for line in process.stdout:
print(line)
I also suspect that your executable isn't working, because the working directory is different.

Scheduling a Python Script via Windows Task Scheduler

Observe the following Python script, "Script.py":
import subprocess
src_directory = 'Z:\z_7z\Some_Directory'
zip_file_name = 'Test.7z'
cmd = ['7z', 'a', zip_file_name, src_directory, '-mx9']
subprocess.Popen(cmd, stderr = subprocess.STDOUT, stdout = subprocess.PIPE)
My intent is to schedule a Python script using Windows Task Scheduler. I have successfully done this using other Python scripts before. However, I am unable to execute the script shown above via scheduling. I am unsure as to whether this is a Windows Task Scheduler problem or a Python problem, but here is what I know:
"Script.py", as shown above, is a script for running a 7zip compression on a "Some_Directory" directory. The script itself and the 7z.exe application which it is invoking are both stored in the "Y:\z_7z" directory.
The script seems to be working fine when executed manually. I can double-click on the script and it will execute properly. Also, I can execute the script from the command line via the following command:
Y:\z_7z\Script.py
However, I cannot execute the script manually by navigating to the "C:\Python27" directory and attempting the following:
python Y:\z_7z\Script.py
This yields the following error:
Line 5 in module subprocess.Popen(cmd, stderr = subprocess.STDOUT, ...)
WindowsError: [Error 2] The system cannot find the file specified
Provided all of that information, the real problem I am having is that Windows Task Scheduler cannot execute this script (Last Run Result = 0x1). I have tried various Windows Task Scheduler configurations, including the one which seems to be ideal which goes as follows:
Program/script: "C:\Python27\python.exe"
Add arguments (optional): "Y:\z_7z\Script.py"
Run whether user is logged on or not
Again, I have scheduled other Python scripts before which have run successfully. This Windows Task Scheduler task seems to be configured properly. I browsed through some of the more advanced settings and did not find anything suspicious with this particular task.
Don't just launch 7z. Provide the full path to the executable.
cmd = [r'C:\Program Files\7zip\7z.exe', 'a', zip_file_name, src_directory, '-mx9']
Would work, considering that C:\Program Files\7zip\7z.exe is the executable path.
Try not running the python process with the script as an argument. Run the python script itself.
Your zip_file_name is relative. I'm not sure the argument is a filename. It may be a path. In that case, the .7z file may be created on C:\Windows\System32. To fix it, set zip_file_name to be a full path.

Executing an xmgrace batch with subprocess.Popen()

I have to make graphs from several files with data. I already found a way to run a simple command
xmgrace -batch batch.bfile -nosafe -hardcopy
in which batch.bfile is a text file with grace commands to print the graph I want. I already tried it manually and it works perfectly. To do this with several files I just have to edit one parameter inside batch.bfile and run the same command every time I make a change.
I have already written a python code which edits batch.bfile and goes through all the data files with a for cycle. In each cycle step I want to run the mentioned command directly in the command line.
After searching a bit I found two solutions, one with os.system() and another with subprocess.Popen() and I could only make subprocess.Popen() work without giving any errors by writing:
subprocess.Popen("xmgrace -batch batch.bfile -nosafe -hardcopy", shell=True)
Problem is, this doesn't do anything in practice, i.e., it just isn't the same as running the command directly in the command line. I already tried writing the full directory for the batch.bfile but nothing changed.
I am using Python 2.7 and Mac OS 10.7
Have you checked running xmgrace from the command line using sh? (i.e. invoke /bin/sh, then run xmgrace... which should be the same shell that Popen is using when you set shell=true).
Another solution would be to create a shell script (create a file like myscript.sh, and run chmod +x from the terminal). In the script call xmgrace:
#!/bin/bash
xmgrace -batch batch.bfile -nosafe -hardcopy
You could then test that myscript.sh works, which ought to pick up any environment variables that might be in your profile that might differ from python. If this works, you could call the script from python's subprocess.Popen('myscript.sh'). You can check what the environment variables are set in python for subprocess by running:
import os
os.environ
You may want to check out http://sourceforge.net/projects/graceplot/
When use use Popen, you can capture the application's output to stdout to stderr and print it within your application - this way you can see what is happening:
from subprocess import Popen, PIPE
ps = Popen(reportParameters,bufsize=512, stdout = PIPE, stderr = PIPE)
if ps:
while 1:
stdout = ps.stdout.readline()
stderr = ps.stderr.readline()
exitcode = ps.poll()
if (not stdout and not stderr) and (exitcode is not None):
break
if stdout:
stdout = stdout[:-1]
print stdout
if stderr:
stderr = stderr[:-1]
print stderr

running command in background

I am using python subprocess module to run some command and store its output in background. The command is deployed on my machine. Now whenever i run the command from shell prompt it works fine. But when I try to run the same command using subprocess module it gives following error
The command to be executed is vxswadm listswitch all
process = subprocess.Popen('vxswadm listswitch all > tmp.txt &',shell=True)
>>> Traceback (most recent call last):
File "/usr/bin/vxswadm", line 30, in <module>
l.uname = os.getlogin()
OSError: [Errno 25] Inappropriate ioctl for device
Can anyone help me out to fix this error . Any suggestions will be helpful. Thanks in advance
Tazim
The problem is likely due to the bash shell terminating immediately after the & and sending the SIGHUP singal to all of it's subprocesses (standard shell behavior).
You can use the subprocess module to directly execute the command and can redirect the output to tmp.txt yourself by first opening the file and then by passing it's file handle to the stdout argument of the Popen call.
There is a problem with os.getlogin() and subprocessing and python.
See http://code.activestate.com/lists/python-list/288845/
You need to use something else, such as:
pwd.getpwuid(os.getuid()).pw_name (Unix only)
See also the discussion on a portable way to get the username.
Try changing it to ['vxswadm', 'listswitch', 'all', '>', 'tmp.txt','&'] and/or changing shell to False.
I think it might be the shell bit, though (if that fixes it).
You may also try adding stdin=subprocess.PIPE, stdout=subprocess.PIPE, though I doubt that will affect it.

Categories

Resources