Skip to content
This repository has been archived by the owner on Aug 11, 2023. It is now read-only.

VSCode terminal broken when using Remote WSL extension and scripts from this repo #33

Open
benjamincburns opened this issue Jul 29, 2020 · 9 comments · May be fixed by #34
Open

VSCode terminal broken when using Remote WSL extension and scripts from this repo #33

benjamincburns opened this issue Jul 29, 2020 · 9 comments · May be fixed by #34

Comments

@benjamincburns
Copy link

This was originally reported at, microsoft/vscode#102628, however I believe that the issue at play is in the scripts used here, not in VSCode.

Observed problem

When running VSCode's Remote WSL extension with this script in place on the most recent Windows Insider build (20175.1000), the terminal fails to start. It flashes the following errors briefly before closing.

xargs: unmatched double quote; By default quotes are special to xargs unless you use the -0 option

Usage: login [-p] name
       login [-p] [-h host] [-f name]
       login [-p] [-r host]

Underlying problems

The output above points to two separate issues:

  1. xargs is choking because of bad quoting somewhere, and
  2. the login command is being run with arguments that it doesn't expect.

Xargs issue

The xargs error above comes from the usage of the xargs command at line 47 of enter-systemd-namespace.

When the WSL Remote extension connects, it creates/modifies ~/.systemd-env. The line below is from that file. When I delete only this line and run the command manually, the xargs error goes away.

SUDO_COMMAND="/bin/bash -c set -a; [ -f \"\$HOME/.systemd-env\" ] && source \"\$HOME/.systemd-env\"; set +a; exec bash -c \\'/home/myuser/.vscode-server/bin/91899dcef7b8110878ea59626991a18c8a6a1b3e/node\\'\\ -p\\ \\'\\\"f3cfc37ff7a5\\\"\\ +\\ JSON.stringify\\(process.env\\)\\ +\\ \\\"f3cfc37ff7a5\\\"\\'"

Fix

I couldn't make sense of that mess of escape sequences, so I simply edited enter-systemd-namespace to use \n as a delimiter by replacing xargs printf ' %q' with xargs -d '\n' printf ' %q' at line 47 of enter-systemd-namespace. This appears to make things work as expected.

Login command issue

Regardless of whether the xargs fix above is in place, the VSCode terminal shows the following error immediately prior to exiting.

With the xargs fix in place, the login command that's failing now looks like the following on my machine

/bin/login -p -f myuser 'AMD_ENTRYPOINT="vs/server/remoteExtensionHostProcess"' 'APPLICATION_INSIGHTS_NO_DIAGNOSTIC_CHANNEL="true"' <other env vars snipped>

Unfortunately I don't yet have a fix for this one. I assume the failure is either because of the single quotes causing the double quotes to be passed as part of the env var args, or because login doesn't expect a list of env vars when the -f flag is used, as shown at the top of the login man page, which I've included below:

NAME
       login - begin session on the system

SYNOPSIS
       login [-p] [-h host] [username] [ENV=VAR...]

       login [-p] [-h host] -f username

       login [-p] -r host
@benjamincburns benjamincburns changed the title Invalid use of login command - breaks VSCode terminal when using Remote WSL extension. VSCode terminal broken when using Remote WSL extension and scripts from this repo Jul 29, 2020
@benjamincburns
Copy link
Author

benjamincburns commented Jul 29, 2020

Actually it turns out that removing the SUDO_COMMAND variable definition from ~/.systemd-env prior to running that login command gets rid of the problem.

On closer inspection it's once again due to bad escaping (single quotes this time).

Running the following with VSCode attached to my WSL instance

echo /bin/login -p -f "$SUDO_USER" $([ -f "$USER_HOME/.systemd-env" ] && /bin/cat "$USER_HOME/.systemd-env" | xargs -d '\n' printf ' %q')

Gives me the following output (irrelevant ENV vars have been removed for clarity):

/bin/login -p -f myuser <snipped> 'SUDO_COMMAND="/bin/bash -c set -a; [ -f \"\$HOME/.systemd-env\" ] && source \"\$HOME/.systemd-env\"; set +a; exec bash -c \\'\''/home/myuser/.vscode-server/bin/91899dcef7b8110878ea59626991a18c8a6a1b3e/node\\'\''\\ -p\\ \\'\''\\\"f3cfc37ff7a5\\\"\\ +\\ JSON.stringify\\(process.env\\)\\ +\\ \\\"f3cfc37ff7a5\\\"\\'\''"' <snipped>

@lucyllewy
Copy link

lucyllewy commented Jul 29, 2020

Can you try changing the command to the following to see if it fixes things? I've done a quick test with this change for sanity and it seems to work for me with the change. (the else and fi lines are already in the file and I've put them here to indicate that the three-line command needs to condense to the one-line below)

else
    exec /usr/bin/nsenter -t "$SYSTEMD_PID" -a /bin/login -p -f "$SUDO_USER"
fi

The terminal inside vscode when using this change starts in the wrong folder, but I can work on that tomorrow once we confirm that your use-case is improved by the fix here.

@benjamincburns
Copy link
Author

benjamincburns commented Jul 29, 2020

I haven't tried that yet, but replacing the final if block in enter-systemd-namespace with the following does seem to work. I'll try your fix next.

if [ -n "$SYSTEMD_PID" ] && [ "$SYSTEMD_PID" != "1" ]; then
    if [ -n "$1" ] && [ "$1" != "bash --login" ] && [ "$1" != "/bin/bash --login" ]; then
        exec /usr/bin/nsenter -t "$SYSTEMD_PID" -a \
            /usr/bin/sudo -H -u "$SUDO_USER" \
            /bin/bash -c 'set -a; [ -f "$HOME/.systemd-env" ] && source "$HOME/.systemd-env"; set +a; exec bash -c '"$(printf "%q" "$@")"
    else
        exec /usr/bin/nsenter -t "$SYSTEMD_PID" -a \
            bash -c '/bin/login -p -f "$SUDO_USER" $([ -f "$USER_HOME/.systemd-env" ] && /bin/cat "$USER_HOME/.systemd-env" | xargs -d '\''\n'\'')'
    fi
    echo "Existential crisis"
    exit 1
fi

@benjamincburns
Copy link
Author

Yeah, your fix works as well (and puts me in the correct directory), so I assume that'll do it.

lucyllewy pushed a commit to lucyllewy/ubuntu-wsl2-systemd-script that referenced this issue Jul 29, 2020
* VSCode WSL-remote fails: issue DamionGans#33
* `/bin/login` does not support environment variable setting via the command line when used with the `-f` flag that allows login to operate without requesting a password.

Signed-off-by: Daniel Llewellyn <[email protected]>
@lucyllewy lucyllewy linked a pull request Jul 29, 2020 that will close this issue
@leganck
Copy link

leganck commented Aug 6, 2020

I haven't tried that yet, but replacing the final if block in enter-systemd-namespace with the following does seem to work. I'll try your fix next.

if [ -n "$SYSTEMD_PID" ] && [ "$SYSTEMD_PID" != "1" ]; then
    if [ -n "$1" ] && [ "$1" != "bash --login" ] && [ "$1" != "/bin/bash --login" ]; then
        exec /usr/bin/nsenter -t "$SYSTEMD_PID" -a \
            /usr/bin/sudo -H -u "$SUDO_USER" \
            /bin/bash -c 'set -a; [ -f "$HOME/.systemd-env" ] && source "$HOME/.systemd-env"; set +a; exec bash -c '"$(printf "%q" "$@")"
    else
        exec /usr/bin/nsenter -t "$SYSTEMD_PID" -a \
            bash -c '/bin/login -p -f "$SUDO_USER" $([ -f "$USER_HOME/.systemd-env" ] && /bin/cat "$USER_HOME/.systemd-env" | xargs -d '\''\n'\'')'
    fi
    echo "Existential crisis"
    exit 1
fi

Problem solved. Thanks for your help!

@fabio-pardo
Copy link

Thank you for this!

@david50407
Copy link
Contributor

david50407 commented Sep 6, 2020

I use this to replace the else block, it works on VSCode but it seems that won't bring you to the project directory, but at least, it works:

exec /usr/bin/nsenter -t "$SYSTEMD_PID" -a \
    /bin/bash -c 'set -a; [ -f '"$USER_HOME/.systemd-env"' ] && source '"$USER_HOME/.systemd-env"'; set +a; exec /bin/login -p -f '"$SUDO_USER"

EDIT:

assign PRE_NAMESPACE_PWD to PWD inside .systemd-env works to enter correct directory:

        exec /usr/bin/nsenter -t "$SYSTEMD_PID" -a \
            /bin/bash -c 'set -a; [ -f '"$USER_HOME/.systemd-env"' ] && source '"$USER_HOME/.systemd-env"'; export PRE_NAMESPACE_PWD="$PWD"; set +a; exec /bin/login -p -f '"$SUDO_USER"

@tomershukhman
Copy link

tomershukhman commented Oct 4, 2020

I haven't tried that yet, but replacing the final if block in enter-systemd-namespace with the following does seem to work. I'll try your fix next.

if [ -n "$SYSTEMD_PID" ] && [ "$SYSTEMD_PID" != "1" ]; then
    if [ -n "$1" ] && [ "$1" != "bash --login" ] && [ "$1" != "/bin/bash --login" ]; then
        exec /usr/bin/nsenter -t "$SYSTEMD_PID" -a \
            /usr/bin/sudo -H -u "$SUDO_USER" \
            /bin/bash -c 'set -a; [ -f "$HOME/.systemd-env" ] && source "$HOME/.systemd-env"; set +a; exec bash -c '"$(printf "%q" "$@")"
    else
        exec /usr/bin/nsenter -t "$SYSTEMD_PID" -a \
            bash -c '/bin/login -p -f "$SUDO_USER" $([ -f "$USER_HOME/.systemd-env" ] && /bin/cat "$USER_HOME/.systemd-env" | xargs -d '\''\n'\'')'
    fi
    echo "Existential crisis"
    exit 1
fi

Bash not crashing anymore which is great but the current directory is still not correct.
opens c..../.vscode/extensions/ms-vscode-remote.remote-wsl-0.44.5

@ThebaultLouis
Copy link

I have the same issue as tomershukhman.
I have tried all your fixes but no one is working.

saltyming pushed a commit to saltyming/ubuntu-wsl2-systemd-script that referenced this issue Mar 29, 2021
* VSCode WSL-remote fails: issue DamionGans#33
* `/bin/login` does not support environment variable setting via the command line when used with the `-f` flag that allows login to operate without requesting a password.

Signed-off-by: Daniel Llewellyn <[email protected]>
Signed-off-by: Sung Mingi <[email protected]>
saltyming pushed a commit to saltyming/ubuntu-wsl2-systemd-script that referenced this issue Apr 25, 2021
* VSCode WSL-remote fails: issue DamionGans#33
* `/bin/login` does not support environment variable setting via the command line when used with the `-f` flag that allows login to operate without requesting a password.

Signed-off-by: Daniel Llewellyn <[email protected]>
Signed-off-by: Sung Mingi <[email protected]>
saltyming pushed a commit to saltyming/ubuntu-wsl2-systemd-script that referenced this issue May 6, 2021
* VSCode WSL-remote fails: issue DamionGans#33
* `/bin/login` does not support environment variable setting via the command line when used with the `-f` flag that allows login to operate without requesting a password.

Signed-off-by: Daniel Llewellyn <[email protected]>
Signed-off-by: Sung Mingi <[email protected]>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants