How to redirect default program output? - python

I am trying to pipe output of my python scripts to pygmentize.
In registry I've set it like this:
"C:\Anaconda\python.exe" "%1"%* | pygmentize
not working (not piping anything at all), what is wrong?

You can use powershell for this
C:\ PowerShell -Command " python [yourprogram.py] | pygmentize -l py3t"
-Command
Executes the specified commands (and any parameters) as though they were typed at the Windows PowerShell command prompt, and then exits, unless the NoExit parameter is specified. Essentially, any text after -Command is sent as a single command line to PowerShell (this is different from how -File handles parameters sent to a script).
The value of Command can be "-", a string. or a script block. If the value of Command is "-", the command text is read from standard input.
Script blocks must be enclosed in braces ({}). You can specify a script block only when running PowerShell.exe in Windows PowerShell. The results of the script are returned to the parent shell as deserialized XML objects, not live objects.
If the value of Command is a string, Command must be the last parameter in the command, because any characters typed after the command are interpreted as the command arguments.
To write a string that runs a Windows PowerShell command, use the format:
"& {<command>}"
where the quotation marks indicate a string and the invoke operator (&) causes the command to be executed.
The above documentation for Command can be found here

Related

How to make Paramiko use PowerShell by default?

I'm SSHing to a Windows machine with Paramiko and I'm stressed out by how hard it is to write a command because:
exec_command runs in cmd prompt console, which has limited functionality so I need PowerShell, meaning I should prefix the command with pwsh -c "the command"
However, cmd prompt doesn't support multi-line nor multiple commands naturally, so I need to stick in caret ^s and &&s in the command.
Inside the command I'm calling Python with python -c 'print("hello")\nprint("world")', however I'm already using " for pwsh -c "the command" meaning I need to escape it with backticks `".
This is fiendishly complex and ugly, the code is a mess, it's Python and PowerShell and cmd prompt special characters intertwined at once. I'm almost 100% sure I'm missing something and there is an easier way to do it hence I'm asking whether Paramiko can run do exec_command in PowerShell by default.
The client (Paramiko) has no control over how the command is interpreted. It's about the server.
Windows Win32-OpenSSH definitely can use PowerShell as the default shell.

Output of shell script run on Windows contains prompt

I have a Python script which is running a shell script using the subprocess library. It has to run on any platform so I have 2 shell scripts, one for Linux/MacOS (cm) and one for Windows (cm.cmd).
Let's say they both contain just a single command example_command -param.
The code which is running the shell script looks like the following:
json = subprocess.run(['cm'], shell=True)
This way, thanks to the shell handling the execution of the script (shell=True), it runs the script cm on Linux/MacOS platforms and cm.cmd on Windows.
The output of the script is a JSON and it works properly on Linux/MacOS platforms, the only problem is with Windows where the output contains the shell prompt which breaks the JSON obviously.
The captured output in the json variable may look like this:
My prompt c:\ $ example_command -param
{ "json_data": ... }
How to avoid printing of the prompt to the subprocess output?
It's caused by the feature called command echoing which is enabled by default but it may be disabled using the echo command. From the documentation:
Syntax
echo [on | off]
Parameters
[on | off] Turns on or off the command echoing feature. Command echoing is on by default.
If you add echo off at the first line of the script, it will disable the command echoing for all subsequent commands but it will echo the echo off command itself. To suppress even echoing of that command, simply prefix it with #.
At sign (#) as a command prefix has the same effect as echo off but only for a single command.
So to summarize it: Simply add #echo off at the first line of the shell script (or batch in Windows terminology) and that's it. Only the output of command(s) executed in the script will be sent to stdout.

Executing Python script using subprocess behaves differently on Ubuntu and Windows machines

Could you help to check what's going on with subprocess, it performs differently on different machines with same Python version, but one is on Ubuntu docker and one is on Windows.
Ubuntu docker
I use subprocess to execute an external Python script with parameter shell=True, actually it opens a new process for me without executing the specified script, so I have to remove the parameter shell=True and then everything works as expected.
You can see from the screenshot below, I need to exit() after executing the first subprocess, and ran the second subprocess without shell=True.
Windows
In Windows, shell=True works same as I execute subprocess in Ubuntu without shell=True parameter.
Quoting https://docs.python.org/3/library/subprocess.html#popen-constructor:
On POSIX with shell=True, the shell defaults to /bin/sh. If args is a
string, the string specifies the command to execute through the shell.
This means that the string must be formatted exactly as it would be
when typed at the shell prompt. This includes, for example, quoting or
backslash escaping filenames with spaces in them. If args is a
sequence, the first item specifies the command string, and any
additional items will be treated as additional arguments to the shell
itself.
(emphasis mine)
That means, in your first example with run(['python', 'script.py'], shell=True) you are actually only starting an interactive Python session and not passing the script to the interpreter.
Further:
The only time you need to specify shell=True on Windows is when the
command you wish to execute is built into the shell (e.g. dir or
copy). You do not need shell=True to run a batch file or console-based
executable.
Conclusion: Whenever possible, pass the arguments as a list (as you did), but do not use shell=True.

Escape sequence not working in python script run from a shell script

I have a shell script that needs to run a python script. The python script may be passed an argument.
python pgm32.py $args
But when the argument passed has an escape sequence or if I encase it in quotes, the python scripts does not recognize it.
For instance say args contains "Open drive" OR Open\ drive
then python script's sys.argv=['pgm32.py', '"Open', 'drive"'] OR sys.argv=['pgm32.py', '"Open', 'drive"'] respectively.
But when I call the python script directly from the command line, and pass an argument like "Open drive" or Open\ drive, the script's sys.arv=['pgm32.py', 'Open drive']
How can I fix this issue?
It's really quite simple. Quote the argument in the shell command:
$ python pgm32.py "$args"
You already did this yourself:
But when I call the python script directly from the command line, and
pass an argument like "Open drive" or Open\ drive, the script's
sys.arv=['pgm32.py', 'Open drive']
Which worked because in these lines you protected the space from shell word splitting; in the other examples you didn't. It is all about the shell and has nothing to do with Python.
This worked:
eval python pgm32.py $args
More details on Setting an argument with bash
Thanks #Barmar.
Assuming this is Bash, you could use an array variable.
declare -a args # Make args an array.
args=("Open Drive" -d output_dir) # Assign three elements.
python pgm32.py "${args[#]}" # Pass to pgm32.py as array.

Python not recognizing the greater than sign?

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.

Categories