Vscode: Using WSL - Running a task using existing environment variables and without the "Press any key to close the terminal" requirement

Created on 18 Apr 2017  路  17Comments  路  Source: microsoft/vscode

  • VSCode Version: 1.11.2
  • OS Version: Windows 10 (Version 1703), with WSL enabled.

I use Bash On Ubuntu On Windows, and I try to make it my default terminal in VSCode. In my User Settings :

"terminal.integrated.shell.windows": "C:\\Windows\\sysnative\\bash.exe"

It is a Node application written in TypeScript. I use Gulp to run tasks and it works well if I use the terminal directly. But now I try to make CTRL-SHIFT-B run the build command task, which has to call "node_modules/.bin/gulp compile" to run the transpilation from TypeScript to Javascript.

Thanks to this thread, I'm able to at least start the compilation with this tasks.json file :

{
    "version": "2.0.0",
    "command": "node_modules/.bin/gulp",
    "isShellCommand": true,
    "suppressTaskName": true,
    "tasks": [
        {
            "taskName": "tsc",
            "args": [
                "compile"
            ],
            "isBuildCommand": true,
            "problemMatcher": "$tsc"
        }
    ]
}

The compilation starts but _fails_ because it involves the oracledb library which needs some environment variables to be set :

export LD_LIBRARY_PATH=/usr/local/oracle/instantclient:$LD_LIBRARY_PATH
export OCI_LIB_DIR=/usr/local/oracle/instantclient
export OCI_INC_DIR=/usr/local/oracle/instantclient/sdk/include

When I run env directly in the terminal, I see those variables since they are exported in my ~/.bashrc file, and this is why the direct compilation works. But when the compilation is ran from the task, those variable are not set, for some reason!

1) How can I make the task to automatically source my ~\.bashrc file? Or should I define the exports in another file for them to work?

2) At the end of the task, a "_Press any key to close the terminal_" message is displayed. Is there a way to output the task to the "output" console instead? Or at least is it possible to remove the requirement to press a key at the end? I'd prefere to not have to do that each time I build using CTRL-SHIFT-B.

*out-of-scope tasks

Most helpful comment

The solution for this would be to let the user control whether to source the env or not when executing a task. As a workaround for now this can be done:

        {
            "taskName": "My Task",
            "type": "shell",
            "command": "....",
            "options": {
                "shell": {
                    "executable": "bash",
                    "args": ["-i", "-c"]
                }
            }
        }

All 17 comments

@dbaeumer May should be able to look into this further.

As a workaround, can you try using a script:

tasks.json:

{
    "version": "2.0.0",
    "isShellCommand": true,
    "tasks": [
        {
            "taskName": "test",
            "command": "./run.sh",
            "args": [
                "compile"
            ]
        }
    ],
    "showOutput": "always"
}

run.sh:

#!/bin/bash
source ~/.bashrc
tsc "$@"

You may have to chmod +x ./run.sh

@mjbvz I did find something similar and it works indeed for the environment variables. But it would be so much easier if the ~/.bashrc was automatically sourced.

@Tyriar any idea why these environment variables are not source from .bashrc. All the task framework does is to create a terminal with the default settings and passing -c to close the bash after executing?

@electrotype there is no need to close the terminal after every run. If you press Ctrl+Shift+B a second time the terminal is actually reused. So it behaves like a 'single' build command output.

What we plan to add is a options to close the terminal automatically. But showing the output in the output channel will not happen since it would require to have full ANSI support in the output windows. This is why we move to the terminal.

AFAIK the env should be set when you use -c so perhaps this is a WSL issue? What's the output when you run env in the task?

@dbaeumer I understand for the terminal, thanks.

@Tyriar :

julien@T470 templates # env
SHELL=/bin/bash
TERM=xterm-256color
JRE_HOME=/usr/local/java/jre1.8.0_121
USER=julien
NAME=T470
LD_LIBRARY_PATH=/usr/local/oracle/instantclient:
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;
44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.
t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*
.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=
01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=0
1;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=0
1;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;3
5:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.m
id=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:
HOSTTYPE=x86_64
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/mnt/c/Python27:/mnt/c/Python27/Scripts:/mnt/c/jdk1.8.0_121/bin:/
mnt/c/ProgramData/Oracle/Java/javapath_target_245871218:/mnt/c/Program Files/Docker/Docker/resources/bin:/mnt/c/Windows/System32:/mnt/c/Windows:/mnt/c/Windows/
System32/wbem:/mnt/c/Windows/System32/WindowsPowerShell/v1.0:/mnt/c/Program Files/Intel/WiFi/bin:/mnt/c/Program Files/Common Files/Intel/WirelessCommon:/mnt/c/
Program Files/TortoiseGit/bin:/mnt/c/Git/cmd:/mnt/c/_julien/job-sync/alias:/mnt/c/nodejs:/mnt/c/apache-maven-3.5.0/bin:/mnt/c/Program Files/Microsoft DNX/Dnvm:
/mnt/c/Program Files (x86)/Windows Kits/8.1/Windows Performance Toolkit:/mnt/c/Program Files/Microsoft SQL Server/130/Tools/Binn:/mnt/c/oracle/instantclient:/m
nt/c/Users/julien/AppData/Local/Microsoft/WindowsApps:/mnt/c/Program Files (x86)/Microsoft VS Code/bin:/mnt/c/Users/julien/AppData/Roaming/npm:/usr/local/java/
jre1.8.0_121/bin:/usr/local/java/jdk1.8.0_121/bin
PWD=/mnt/c/_julien/dev/mtl/generator-mtl-node-api/generators/app/templates
JAVA_HOME=/usr/local/java/jdk1.8.0_121
LANG=en_US.UTF-8
SHLVL=1
HOME=/home/julien
LOGNAME=julien
LESSOPEN=| /usr/bin/lesspipe %s
OCI_INC_DIR=/usr/local/oracle/instantclient/sdk/include
OCI_LIB_DIR=/usr/local/oracle/instantclient
LESSCLOSE=/usr/bin/lesspipe %s %s
_=/usr/bin/env

The three variables I need are there.

And running the task using VSCode :

Error: libclntsh.so.12.1: cannot open shared object file: No such file or directory
    at Object.Module._extensions..node (module.js:598:18)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
    at Module.require (module.js:498:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/mnt/c/_julien/dev/mtl/generator-mtl-node-api/generators/app/templates/node_modules/oracledb/lib/oracledb.js:35:19)
    at Module._compile (module.js:571:32)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
    at Module.require (module.js:498:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/mnt/c/_julien/dev/mtl/generator-mtl-node-api/generators/app/templates/node_modules/oracledb/index.js:1:18)
    at Module._compile (module.js:571:32)
Press any key to close the terminal

@electrotype I mean configure your tasks.json to run env and view the output of it.

Sorry about that.

Here's the output :

TERM=xterm-256color
SHELL=/bin/bash
NAME=T470
USER=julien
HOSTTYPE=x86_64
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/mnt/c/Python27:/mnt/c/Python27/Scripts:/mnt/c/jdk1.8.0_121/bin:/
mnt/c/ProgramData/Oracle/Java/javapath_target_245871218:/mnt/c/Program Files/Docker/Docker/resources/bin:/mnt/c/Windows/System32:/mnt/c/Windows:/mnt/c/Windows/
System32/wbem:/mnt/c/Windows/System32/WindowsPowerShell/v1.0:/mnt/c/Program Files/Intel/WiFi/bin:/mnt/c/Program Files/Common Files/Intel/WirelessCommon:/mnt/c/
Program Files/TortoiseGit/bin:/mnt/c/Git/cmd:/mnt/c/_julien/job-sync/alias:/mnt/c/nodejs:/mnt/c/apache-maven-3.5.0/bin:/mnt/c/Program Files/Microsoft DNX/Dnvm:
/mnt/c/Program Files (x86)/Windows Kits/8.1/Windows Performance Toolkit:/mnt/c/Program Files/Microsoft SQL Server/130/Tools/Binn:/mnt/c/oracle/instantclient:/m
nt/c/Users/julien/AppData/Local/Microsoft/WindowsApps:/mnt/c/Program Files (x86)/Microsoft VS Code/bin:/mnt/c/Users/julien/AppData/Roaming/npm
_=/usr/bin/env
PWD=/mnt/c/_julien/dev/mtl/generator-mtl-node-api/generators/app/templates
LANG=en_US.UTF-8
HOME=/home/julien
SHLVL=2
LOGNAME=julien
Press any key to close the terminal

And here's the task I use :

{
    "version": "2.0.0",
    "command": "env",
    "isShellCommand": true,
    "showOutput": "always",
    "suppressTaskName": true,
    "tasks": [
        {
            "taskName": "env"
        }
    ]
}

In my user settings :

"terminal.integrated.shell.windows": "C:\\Windows\\sysnative\\bash.exe"

I think this is an issue with WSL that ~/.bashrc is not being sourced when running bash.exe -c, could you file an issue to https://github.com/Microsoft/BashOnWindows?

@Tyriar

I found the WSL issue about this : .bashrc not used when bash.exe -c "echo $ENV".

If I understand it properly, this is not something they are going to fix though! Does this mean that it may be up to VSCode to change the way it calls bash -c? Otherwise, the integration will never be perfect.

I read through the referenced issue and we need to change starting bash in the task framework to something like bash -c "source ~/.bashrc; command" to make this work

Try using bash -ic command instead, this correctly loads .bashrc
See issue: https://github.com/Microsoft/BashOnWindows/issues/2075

The reason for this is the following code block at the beginning of the .bashrc file in the Ubuntu subsystem:

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

The actually exit the .bashrc when not in interactive mode. As @nelak points out to source the .bashrc when running a command -c you need to pass -i -c.

I am reluctant to make it the default since running a command should usually not source the .bashrc since it might alter the environment again.

The solution for this would be to let the user control whether to source the env or not when executing a task. As a workaround for now this can be done:

        {
            "taskName": "My Task",
            "type": "shell",
            "command": "....",
            "options": {
                "shell": {
                    "executable": "bash",
                    "args": ["-i", "-c"]
                }
            }
        }

Since the need to control the sourceing of the bashrc is small and a way to control this via the options property exists I will close the issue as out of scope.

There is a general issue to track tasks to be executed in WSL.

This iteration we focus on issue grooming. This issue is being closed to keep the number of issues in our inbox on a manageable level, we are closing issues that are not going to be addressed in the foreseeable future: We look at the number of votes the issue has received and the number of duplicate issues filed. More details here. If you disagree and feel that this issue is crucial: We are happy to listen and to reconsider.

If you wonder what we are up to, please see our roadmap and issue reporting guidelines.

Thanks for your understanding and happy coding!

@dbaeumer Sorry for the dumb question - could you help elaborate on how do I set my tasks.json such that when it runs a task that I specify, it uses bash -ic rather than bash -c to source the ~/.bashrc?

I used the following and it seems to be working. If you don't mind, could you help confirm that I was doing right, and maybe future readers may also benefit from this small change?

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "options": {"shell": {"args": ["-ic"]}},  // ADD THIS LINE HERE!
    "tasks": [
        {
            "label": "build dbg",
            "type": "shell",
            // Skipping the lines below

@yw5aj yes this is the correct way to configure this.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

filfat picture filfat  路  246Comments

ghost picture ghost  路  234Comments

Brakkar picture Brakkar  路  364Comments

Tyriar picture Tyriar  路  187Comments

misolori picture misolori  路  282Comments