megayeye
megayeye

Reputation: 121

How to run a script before running/debugging a python script by vscode?

I am working with ROS. ROS needs to source a few scripts e.g., /opt/ros/noetic/setup.sh before running any python programs. Otherwise I cannot import roslib or similar stuffs.

When I debug with vscode, is there any way to let vscode to source this script automatically before starting the debugger?

Upvotes: 12

Views: 3908

Answers (4)

Mlinarm
Mlinarm

Reputation: 23

Since February 2025, you can use no-config debugging in VS Code: https://devblogs.microsoft.com/python/python-in-visual-studio-code-february-2025-release/#no-config-debugging

Source your setup script in a terminal in VS Code, then to run the debugger in the same terminal, use the command that you would use to run your Python script, but replace python with debugpy, e.g.

debugpy myscript.py

However, as far as I'm aware, you cannot run a debugging configuration from launch.json this way, and there is no way to run setup scripts automatically before running the debugger, other than modifying the .bashrc file as in promethus' answer, but this will be executed whenever you open a VS Code terminal, whichever folder you open in VS Code, and possibly in other situations as well.

If you would like these features added, I suggest you upvote these requests on GitHub:

Upvotes: 1

promethus
promethus

Reputation: 21

Adding the setup scripts to your .bashrc file will ensure that they are sourced before vscode begins debugging your program. The ROS2 documentation supports this method and provides an example.

In your .bashrc file add the following:

source /opt/ros/${ROS_DISTRO}/setup.bash
source ~/ros2_ws/install/local_setup.bash

Upvotes: 2

Merramore
Merramore

Reputation: 13

If your launch script allows you to specify a python target (and finishes quickly enough), you can use pythonArgs in launch.json to insert a shim.

.vscode/launch.json

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Launch via Shell Script",
            "type": "python",
            "pythonArgs": ["debug_shim.py", "launch.sh"],
            "args": ["your", "app", "args"],
            "request": "launch",
            "program": "app.py"
        }
    ]
}

debug_shim.py

import os, subprocess, sys

launcher, debugger, debugger_args = sys.argv[1], sys.argv[2], sys.argv[3:]

sys.exit(subprocess.run(
    args=[launcher] + debugger_args,
    env=dict(os.environ, LAUNCH_TARGET=debugger),
    stdin=sys.stdin,
    stdout=sys.stdout,
    stderr=sys.stderr,
).returncode)

launch.sh

#!/usr/bin/env bash

# Or target could be passed along the command line as well.
# LAUNCH_TARGET="${1?}"

# ...stuff...

python "${LAUNCH_TARGET-app.py}" "${@}"

In my setup of v1.80.0 on WSL2, the debugger call is like so:

python python_args... debugger debugger_args... app app_args...

Then the call stack will be vscode -> shim -> launcher -> debugger -> app and the debugger will connect seamlessly, although if it takes more than several seconds VSCode will time out.

Upvotes: 1

Steven-MSFT
Steven-MSFT

Reputation: 8431

You can have a try on Task, For example:

tasks.json file:

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "Task Name",
            "type": "shell",
            "command":"the commands you want to execute",
        }
    ]
}

And add this in the launch.json file:

"preLaunchTask": "Task Name",

You can refer to the official docs for more details.

Upvotes: -6

Related Questions