I need to invoke a powershell script and capture the output as generated from it.
Since I need to capture the output, I chose to use subprocess.run()
Powershell invocation
powershell DeleteResults -resultscsv '1111,2222,3333,4444'
Python(Python 3.5.2 :: Anaconda 4.1.1 (64-bit)) code
command = "powershell DeleteResults -resultscsv '{}'".format(resultscsv)
output = subprocess.run(command, stdout=subprocess.PIPE).stdout.decode('utf-8')
All goes fine as long as the length of command is less than 33K(approx)
However, subprocess.call() throws error when the length exceeds 33K (There is no issue on the powershell side as it works perfectly fine when invoked directly)
ERROR: [WinError 206] The filename or extension is too long
Traceback (most recent call last):
File "D:\path\to\python\wrapper.py", line 154, in <module>
output = subprocess.run(command, stdout=subprocess.PIPE).stdout.decode('utf-8')
File "D:\Anaconda3\lib\subprocess.py", line 693, in run
with Popen(*popenargs, **kwargs) as process:
File "D:\Anaconda3\lib\subprocess.py", line 947, in __init__
restore_signals, start_new_session)
File "D:\Anaconda3\lib\subprocess.py", line 1224, in _execute_child
startupinfo)
Any pointer will be great help.
Not sure if relevant - the python script is invoked via Control-M on a windows environment.
--Edit--
Adding this section to add more details in response to answer by Alex.
We don't own the ps script DeleteResults
. So, we can't modify it. We just consume it.
As it is done today,
- The resultscsv(80K chars) is stored in a
results.ini
file - A small piece of ps inline code parses .ini file and then invokes DeleteResults. Note: There is powershell call inside the outer powershell invocation(invocation below).
- This approach works perfectly fine even if chars >80K.
- However, we don't want the inline ini parser to be part of invocation - looks ugly.
- So, the idea is to write a python wrapper which will parse .ini file and invoke the powershell
powershell -NoLogo -NonInteractive -Command "Get-Content 'results.ini' | foreach-object -begin {$h=@{}} -process { $k = [regex]::split($_,'='); if(($k[0].compareTo(' ') -ne 0) -and ($k[0].startswith('[') -ne $True)) {$h.Add($k[0], $k[1]) }}; powershell DeleteResults -resultscsv $h.Get_Item('resultscsv')"
So, wondering why the above ps 1-liner not hitting the char length limit ? Is it that the line powershell DeleteResults -resultscsv $h.Get_Item('resultscsv')
is NOT actually expanded inline - thereby not hitting the char length limit ?