microsoft / vscode-python-debugger

Python debugger (debugpy) extension for VS Code.
https://marketplace.visualstudio.com/items?itemName=ms-python.debugpy
MIT License
41 stars 17 forks source link

clarifications on stdout/stderr redirection #309

Closed xsolinsx closed 2 months ago

xsolinsx commented 2 months ago

I need to redirect stderr AND stdout to two different files at the same time, but I cannot figure out how to do it. I checked here and there on the internet and I have tried with the following section of launch.json file but it seems to only redirect the stdout to the stderr.log file, while the real stderr gets printed to the vscode terminal, which is obviously not what I wanted to obtain...

...
            "args": [
                ">",
                "stdout.log",
                "2",
                ">",
                "stderr.log"
            ]
...

I used this code to check

import sys
import time

while True:
    sys.stdout.write("abc")
    sys.stderr.write("cba")
    time.sleep(1)

What am I missing/doing wrong? Is this even possible?

karthiknadig commented 2 months ago

Can you try:

"args": ["1>stdout.log", "2>stderr.log"]

Note that this might be occurring when you are running the code under the debugger. Debugger can do its own redirection, so it really depends on how the settings for the debugger is configured as well. But your script inf you run it from the terminal with that should work

> python myscript.py 1>stdout.log 2>stderr.log
xsolinsx commented 2 months ago

this does not work because it gets printed on console and not on files, due to the '>' being escaped, the following is the command executed in the shell

cd /home/user/Projects ; /home/user/Programs/virtual_environments/venv_ml/bin/python /home/user/.vscode/extensions/ms-python.debugpy-2024.4.0-linux-x64/bundled/libs/debugpy/adapter/../../debugpy/launcher 46131 -- test.py 1\>stdout.log 2\>stderr.log

I can post the whole launch.json if needed

karthiknadig commented 2 months ago

You can try using the attach configuration instead to debug. It seems like the > will get escaped. This is a limitation of how launch works. here is something that you could do.

Create a attach configuration using the listen mode, like this:

        {
            "name": "Listen",
            "type": "debugpy",
            "request": "attach",
            "listen": { "host": "localhost", "port": 5678 },
            "justMyCode": true
        },

You can then launch your code under the debugger and see if that works. You will need to install debugpy in the environment, and add this to your code at the begining:

import debugpy
debugpy.connect(5678)

@int19h Can you recommend an alternative? I also remember there was a way to turn off shell escape, but that just does it from debugger side. VS Code terminal handler can still escape it.

int19h commented 2 months ago

VSCode has a special facility that debugpy uses to handle this properly. The way that is exposed is as follows.

If you specify "args" as an array, then all arguments are escaped (since otherwise there's no guarantee that each arg in the array corresponds to one entry in sys.argv). Thus no redirection or shell variable expansion occurs.

But if "args" is a simple string literal, then it is passed to the shell in its entirety as is, which means that all special characters like $ and > get handled by the shell, and the shell also ultimately defines how the result is then split into separate argv entries.

(I'm not sure if it's in vscode-python docs, but it is in the launch.json schema, and tooltip for "args" covers it.)

So, in this case:

"args": ">stdout.log 2>stderr.log"
xsolinsx commented 2 months ago

I tested both your solutions and they worked very well, thanks a lot to both of you!