Last active
November 13, 2025 15:29
-
-
Save KnorpelSenf/f4f65f38c8bb64fef2b7e2cc57e3254c to your computer and use it in GitHub Desktop.
Open VS Code Devcontainer From Command Line
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| code() { | |
| # Detect WSL | |
| __code_is_wsl=0 | |
| if [ -n "$WSL_DISTRO_NAME" ] || grep -qi microsoft /proc/version 2>/dev/null; then | |
| __code_is_wsl=1 | |
| fi | |
| # Check for required external commands | |
| for __code_dep in code realpath xxd; do | |
| if ! command -v "$__code_dep" >/dev/null 2>&1; then | |
| echo "Error: '$__code_dep' is required but not installed." >&2 | |
| if [ "$__code_dep" = "xxd" ]; then | |
| echo " (usually part of the vim package)" >&2 | |
| fi | |
| return 127 | |
| fi | |
| done | |
| if [ "$__code_is_wsl" -eq 1 ]; then | |
| if ! command -v wslpath >/dev/null 2>&1; then | |
| echo "Error: 'wslpath' is required in WSL but not installed." >&2 | |
| return 127 | |
| fi | |
| fi | |
| # Initialize variables | |
| __code_is_dev_container=0 | |
| __code_show_custom_help=0 | |
| __code_target="" | |
| __code_passthrough_args=() | |
| # Parse arguments | |
| for __code_arg in "$@"; do | |
| case "$__code_arg" in | |
| -c) | |
| __code_is_dev_container=1 | |
| ;; | |
| -h|--help) | |
| if [ "$__code_is_dev_container" -eq 1 ]; then | |
| __code_show_custom_help=1 | |
| fi | |
| # Keep help flag in passthrough in case we aren't in dev container mode | |
| __code_passthrough_args+=("$__code_arg") | |
| ;; | |
| -ch|-hc) | |
| __code_is_dev_container=1 | |
| __code_show_custom_help=1 | |
| ;; | |
| -*) | |
| # It's a flag (e.g. -n, --verbose, --profile), preserve it | |
| __code_passthrough_args+=("$__code_arg") | |
| ;; | |
| *) | |
| # It's not a flag. If we haven't found a target yet, this is it. | |
| if [ -z "$__code_target" ]; then | |
| __code_target="$__code_arg" | |
| else | |
| # We already have a target, treat this as an extra arg/path | |
| __code_passthrough_args+=("$__code_arg") | |
| fi | |
| ;; | |
| esac | |
| done | |
| # Show custom help if requested (-c -h) | |
| if [ "$__code_show_custom_help" -eq 1 ]; then | |
| cat <<'EOF' | |
| Usage: | |
| code -c [path] [options] Open path in VS Code Dev Container mode. | |
| code [path] -c [options] (Alternative argument order) | |
| Options: | |
| -h, --help Show this help message for Dev Container mode. | |
| Environment: | |
| CODE_SILENT=1 Suppress informational "Opening..." messages. | |
| CODE_PRESERVE_SYMLINK=1 Preserve symlink paths instead of resolving them. | |
| Standard VS Code options (like -n, --verbose) are passed through. | |
| EOF | |
| return 0 | |
| fi | |
| # Handle Dev Container mode | |
| if [ "$__code_is_dev_container" -eq 1 ]; then | |
| # Default to current directory if no target found | |
| if [ -z "$__code_target" ]; then | |
| __code_target="." | |
| fi | |
| # Resolve absolute path (Linux path) | |
| if [ -n "$CODE_PRESERVE_SYMLINK" ]; then | |
| __code_absolute_path="$(cd "$__code_target" 2>/dev/null && pwd)" || { | |
| echo "Error: Cannot resolve path '$__code_target'." >&2 | |
| return 2 | |
| } | |
| else | |
| __code_absolute_path="$(realpath "$__code_target" 2>/dev/null)" || { | |
| echo "Error: Cannot resolve path '$__code_target'." >&2 | |
| return 2 | |
| } | |
| fi | |
| # Validate directory existence | |
| if [ ! -d "$__code_absolute_path" ]; then | |
| echo "Error: Not a directory: '$__code_absolute_path'." >&2 | |
| return 2 | |
| fi | |
| if [ ! -r "$__code_absolute_path" ]; then | |
| echo "Error: Directory not readable: '$__code_absolute_path'." >&2 | |
| return 2 | |
| fi | |
| # Determine path to encode | |
| __code_base_name="$(basename "$__code_absolute_path")" | |
| [ -z "$__code_base_name" ] || [ "$__code_base_name" = "/" ] && __code_base_name="root" | |
| __code_path_to_encode="$__code_absolute_path" | |
| # Handle WSL path translation | |
| if [ "$__code_is_wsl" -eq 1 ]; then | |
| __code_windows_path="$(wslpath -w "$__code_absolute_path")" || { | |
| echo "Error: Failed to translate WSL path." >&2 | |
| return 3 | |
| } | |
| __code_path_to_encode="$__code_windows_path" | |
| fi | |
| # Hex encode | |
| __code_encoded_path="$(printf '%s' "$__code_path_to_encode" | tr -d '\n' | xxd -c 256 -p 2>/dev/null)" | |
| if [ -z "$__code_encoded_path" ]; then | |
| echo "Error: Failed to encode path." >&2 | |
| return 2 | |
| fi | |
| if [ -z "$CODE_SILENT" ]; then | |
| echo "Opening VS Code Dev Container for: $__code_absolute_path" >&2 | |
| fi | |
| # Launch VS Code with passthrough args (e.g. -n) and the folder URI | |
| command code "${__code_passthrough_args[@]}" --folder-uri="vscode-remote://dev-container+$__code_encoded_path/workspaces/$__code_base_name" | |
| else | |
| # Pass through exactly as is for non-container usage | |
| command code "$@" | |
| fi | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Why?
This script adds a
-cflag to your installation of VS Code. It allows you to open any directory in a dev container directly from the command line:This means that you no longer have to open the directory locally, wait for a pop-up to appear, and click the button “Reopen in container.” Just open it there directly.
Installation?
Either paste this at the end of your
.bashrcfile, or create a new file somewhere atpath/to/script.shand source it from.bashrcfile (or even your.bash_aliasesfile). For example, you can put this script at~/.code-c.sh.Compatibility?
It should work everywhere
shworks, i.e. basically Linux, Mac, and WSL2. If there is an issue, feel free to comment below but please note that I am not promising that I will maintain this. It works for me.Credits?
This SO answer.
Also, various LLMs, so take it with a grain of salt.