Running command on Windows fails with unknown flag due to single quote - python

I am trying to run the IBM Rational AppScan command line tool in python to iterate through .scan files in Windows and create xml reports. I am using python3.7.4 to do this and I am using the subprocess module. What I am trying continuously fails because of an unknown flag due to a single quote.
I am trying to run this python code on a Windows Server 2012. I have tried using os.system and subprocess.run with no luck.
Here is my code. It is looking for .scan files in the specified directory and when found attempts to run the command:
appscancmd r /b $scanfile /rtm Guidefault /rf $scanfile.xml /rt xml_report
Reference here for syntax:
https://www.ibm.com/support/knowledgecenter/en/SSPH29_9.0.3/com.ibm.help.common.infocenter.aps/r_ReportCommand004.html
import sys
import os
import subprocess
directory='C:\Scans'
for filename in os.listdir(directory):
if filename.endswith(".scan"):
scanfile=str(os.path.join(directory, filename))
command=['appscancmd', 'r /b "'+scanfile+ '" /rtm GuiDefault /rf "'+scanfile+'.xml" /rt xml_report']
subprocess.run(command)
continue
else:
continue
I keep receiving the error message:
Unknown flag entered: 'r /b "c:\scans\app.scan" /rtm guidefault /rf
"c:\scans\app.scan.xml" /rt xml_report'
and I believe this is due to the single quote inserted. When I manually run:
appscancmd r /b "c:\scans\app.scan" /rtm guidefault /rf "c:\scans\app.scan.xml" /rt xml_report
it works fine. Not sure how to resolve this, so figured I would ask for help

Jason, i figured out how to break each in the command list and was able to execute successfully. Thanks! command=['appscancmd', 'r', '/b', scanfile, '/rtm', 'GuiDefault', '/rf', scanfile+'.xml', '/rt', 'xml_report'] did the trick for those wondering

Related

Got an ERROR: Invalid argument/option - '>' when I was trying to export information in task scheduler to a csv file

I wanna export all information in Windows Task Scheduler using Python, so I wrote the code as follows:
Import subprocess
subprocess.call(r'schtasks.exe / query / FO CSV > D:\tasks.csv /V')
Then I got ERROR: Invalid argument/option - '>'
But when I input schtasks.exe / query / FO CSV > D:\tasks.csv /V in cmd, it works.
Can anybody help me with this? Thank you!
In cmd it works because it's cmd interpreting the >. You aren't calling cmd here though, you are calling schtasks!
You can solve it in one of the following ways:
Use shell=True so that Python spawns a shell (presumably cmd, but that's actually determined by the COMSPEC environment variable) and runs the command there
Run cmd explicitly: cmd.exe /c "schtasks.exe /query /FO CSV > D:\tasks.csv /V"
Instead of using >, capture the output in Python and then write it into a file.

Wildcard error - "invalid option"

I am currently working on a python script in which there is a moment I want to delete a file which name is ending with .txt
To do so I just run a command line using os in python:
os.system("del working/*.txt")
When running the python script, I get the following error in cmd:
Option non valide - "*". which can be translated "Invalid option"
It seems that the wildcard isn't recognized by cmd but I know very little about this. Why is it not working ?
I know I could handle the situation with regular expressions but I'd like to understand.
Thank you in advance
In Windows, \ is the path delimiter, not /, so you should do:
os.system(r"del working\*.txt")
Note that / in Windows is for switches, hence the "invalid option" error.
I think its better use os.remove instead os.system with "del" command. Using os.system your script will not work on linux. Here a example using os.remove:
files = os.listdir("working\")
for fi in files:
if fi.endswith(".json"):
os.remove("working\{}".fomat(fi))

How to loop through the command for number of files in directory using bash?

Here iam using a bash script which runs like this
for d in os.listdir($folder_name); do
echo "Running the scanner :"
python bd.py $folder_name/$d
done
Here iam downloading some files to my directory name folder_name then i want to run the script taking arguments as each and every file name.I tried to use this logic but it failed giving me this error.
./test: line 29: syntax error near unexpected token `('
./test: line 29: `for d in os.listdir($folder_name); do'
Is there any way to repeat the loop taking each file as argument and passing it to the python file.
Presumably, you want to iterate over the files in a directory and run some python script taking each filename as argument; if so, just globbing to get the filenames would do:
for f in /directory/*; do python bd.py "$f"; done
Replace /directory/ with the actual directory name.
os.listdir() is a function from os module in python that returns a list containing the contents of a directory as strings, the same thing you can achieve with simple shell globbing in any shell.

python subprocess module can't parse filename with special characters "("

I have a Python program that reads files and then tars them into tar balls of a certain size.
One of my files not only has spaces in it but also contains parentheses. I have the following code:
cmd = "/bin/tar -cvf " + tmpname + " '" + filename + "'"
NOTE: Those are single quotes inside double quotes outside of the filename variable. It's a little difficult to see.
Where tmpname and filename are variables in a for-loop that are subject to change each iteration (irrelevant).
As you can see the filename I'm tarballing contains single quotes around the file name so that the shell (bash) interprets it literally as is and doesn't try to do variable substitution which "" will do or program execution which ` will do.
As far as I can see, the cmd variable contains the exact syntax for the shell to interpret the command as I want it to. However when I run the following subprocess command substituting the cmd variable:
cmdobj = call(cmd, shell=True)
I get the following output/error:
/bin/tar: 237-r Property Transport Request (PTR) 012314.pdf: Cannot stat: No such file or directory
/bin/tar: Exiting with failure status due to previous errors
unable to tar: 237-r Property Transport Request (PTR) 012314.pdf
I even print the command out to the console before running the subprocess command to see what it will look when running in the shell and it's:
cmd: /bin/tar -cvf tempname0.tar '237-r Property Transport Request (PTR) 012314.pdf'
When I run the above command in the shell as is it works just fine. Not really sure what's going on here. Help please!
Pass a list of args without shell=True and the full path to the file if running from a different directory:
from subprocess import check_call
check_call(["tar","-cvf",tmpname ,"Property Transport Request (PTR) 012314.pdf"])
Also use tar not 'bin/tar'. check_call will raise a CalledProcessError if the command returns a non-zero exit status.
The call method that is part of the subprocess module should have an array of strings passed.
On the command line you would call
tar -cvf "file folder with space/"
The following is equivalent in python
call(["tar", "-cvf", "file folder with space/"])
You are making this call in the shell
"tar -cvf 'file folder with space/'"
Which causes the shell to look for a program with the exact name as `tar -cvf 'file folder with space/'
This avoids string concatenation, which makes for cleaner code.

Run R script from python WINDOWS

I made this code and it is working but only in Linux.
import subprocess as sub
sub.Popen([r"Rscript","diccionari.R"])
Where "diccionari.R" is the name of my script in R.
Error text message: System can't found the specific file.
Can somebody help me and do that it works on windows please?
Thank you.
You should probably try the slashes the other way around as how I said it earlier.
Using full path to the .r script (e.g. "C:/myfolder/diccionari.R") instead of just the script file, and using OS independent slashes.
You should specify where Rscriptis located i.e
import subprocess as sub
cmd_line = [r"C:\\Program Files\\R\\R-3.6.0\\bin\\Rscript", "diccionari.R"]
sub.Popen(cmd_line)
watch for the \\ characters

Categories

Resources