VSCode: How to run a command after each terminal open?

24,924

Solution 1

On Linux systems you should use:

"terminal.integrated.shellArgs.linux"

On Windows and OSX:

terminal.integrated.shellArgs.windows

and

terminal.integrated.shellArgs.osx

respectively.

If you want to apply shellArgs setting on a per-workspace basis - you can, despite the fact that documentation says:

The first time you open a workspace which defines any of these settings, VS Code will warn you and subsequently always ignore the values after that

At least version 1.42 of VSCode asks you something like:

"This workspace wants to set shellArgs, do you want to allow it?"

See issue 19758


On Linux, if you are using bash (default for shell in VSCode), there are some subtleties:

  1. "terminal.integrated.shellArgs.linux": ["your_init_script.sh"]
    
    will execute the script and close terminal right away. To prevent this you'll have to end the script with $SHELL command.
    #!/bin/bash
    echo "init"
    export PATH=$PATH:/xxx/yyy/zzz # or do whatever you want
    $SHELL
    
    But that way you end up in a subshell. Sometimes it's unacceptable (Read 1) (Read 2).
  2. "terminal.integrated.shellArgs.linux": ["--init-file", "your_init_script.sh"]
    
    will leave you in the initial shell, but will not execute the .bashrc init file. So you may want to source ~/.bashrc inside your_init_script.sh
    #!/bin/bash
    source ~/.bashrc
    echo "init"
    export PATH=$PATH:/xxx/yyy/zzz # or do whatever you want
    
  3. And if you already have some_init_script.sh in a repository, and for some reason don't feel like adding source ~/.bashrc into it, you can use this:
    "terminal.integrated.shellArgs.linux": ["--init-file", "your_init_script.sh"]
    
    your_init_script.sh:
    #!/bin/bash
    source ~/.bashrc
    source some_init_script.sh
    
    some_init_script.sh:
    #!/bin/bash
    echo "init"
    export PATH=$PATH:/xxx/yyy/zzz # or do whatever you want
    

    Outside of VSCode you can do without creating extra file. Like this
    bash --init-file <(echo "source ~/.bashrc; source some_init_script.sh")
    
    But I could not pass this string into terminal.integrated.shellArgs.linux - it needs to be split into array somehow. And none of the combinations I've tried worked.

Also, you can open terminal at a specific folder:

terminal.integrated.cwd

Change env:

"terminal.integrated.env.linux"
"terminal.integrated.env.windows"
"terminal.integrated.env.osx"

And even change terminal to your liking with

terminal.integrated.shell.linux
terminal.integrated.shell.windows
terminal.integrated.shell.osx

Or

terminal.external.linuxExec
terminal.external.osxExec
terminal.external.windowsExec

Solution 2

You can do the following:

"terminal.integrated.shellArgs.windows": ["start-ssh-agent.cmd"]

Modified from: https://code.visualstudio.com/docs/editor/integrated-terminal#_shell-arguments

Solution 3

I actually found a pretty neat Linux solution for this. It should also work on Windows if you use a shell like Bash. I'm not sure if it's possible using vanilla CMD.

Add something like this to your .bashrc or .zshrc:

#
# Allow parent to initialize shell
#
# This is awesome for opening terminals in VSCode.
#
if [[ -n $ZSH_INIT_COMMAND ]]; then
    echo "Running: $ZSH_INIT_COMMAND"
    eval "$ZSH_INIT_COMMAND"
fi

Now, in your VSCode workspace setting, you can set an environment variable like this:

"terminal.integrated.env.linux": {
    "ZSH_INIT_COMMAND": "source dev-environment-setup.sh"
}

Now the script "dev-environment-setup.sh" will be automatically sourced in all new VSCode terminal windows.

Solution 4

The other answer are great but a little outdated. You will get a warning in VSCode. Here is what I'm doing in my XXX.code-workspace file on linux:

    "terminal.integrated.profiles.linux": {
      "BashWithStartup": {
        "path": "bash",
        "args": [
          "--init-file",
          "./terminal_startup.sh"
        ]
      }
    },
    "terminal.integrated.defaultProfile.linux": "BashWithStartup"

Be sure to make sure your terminal_startup.sh script is executable:

chmod u+x terminal_startup.sh

Solution 5

For anyone using the wonderful cmder, you'll need something akin to the following in your settings.json

{
    "terminal.integrated.shell.windows": "cmd.exe",
    "terminal.integrated.env.windows": {
        "CMDER_ROOT": "C:\\path\\to\\cmder"
    },
    "terminal.integrated.shellArgs.windows": [
        "/k",
        "%CMDER_ROOT%\\vendor\\bin\\vscode_init.cmd"
    ],
}

And then you can add any aliases into the user_aliases.cmd file that should already exist in %CMDER_ROOT%\\config\\user_aliases.cmd

Share:
24,924

Related videos on Youtube

Sébastien
Author by

Sébastien

Updated on July 09, 2022

Comments

  • Sébastien
    Sébastien almost 2 years

    On Windows I have to run the command start-ssh-agent.cmd on each new terminal session I open. My development environment is VSCode, and I open a dozen new terminals each day. After each terminal open, I have to manually run this command.

    Is there is a way to run this command on the terminal each time I open one ?

    enter image description here

    This may take the form of a VSCode extension, VSCode configuration (settings) or a Windows environment configuration.

    Any idea?

  • Voyager
    Voyager almost 5 years
    use /K command to process command as an immediate command in terminal such as set CLASSPATH, ["/K", "C:\\cmder\\vendor\\init.bat"]
  • Hubro
    Hubro about 4 years
    Surely there has to be more to this answer? If you just set shellArgs.linux to a script, won't the shell just execute the script and exit?
  • x00
    x00 about 4 years
    After a little bit of digging found a better solution: --init-file. Updated the answer. Also that may be helpful serverfault.com/questions/368054/…
  • Hubro
    Hubro about 4 years
    Well, the man page says Execute commands from file instead of the standard personal initialization file ~/.bashrc if the shell is interactive
  • Sébastien
    Sébastien about 4 years
    Really interesting! Thanks for sharing @Hubro
  • x00
    x00 about 4 years
    @Hubro, you're right. That took me a while. But I think I've made it. Updated the answer.
  • x00
    x00 about 4 years
    It looks nicer than my answer. But wouldn't it require editing .bashrc of every team member? And so require extra work, extra documentation, and can even introduce conflicts, if ZSH_INIT_COMMAND (or any name for that matter) already in use in someone's .bashrc.
  • Hubro
    Hubro about 4 years
    @x00 Yes, but that's fine. The only part of this that is shared with the team is the dev session setup script. Everything else is local to my PC. My team members can choose to source the script manually, or they can replicate my setup if they want.
  • Zitrax
    Zitrax over 3 years
    Note that to add ["--init-file", "your_init_script.sh"] in the settings ui (not the json) you need to add --init-file and your_init_script.sh as two separate items.
  • touch my body
    touch my body about 3 years
    This is a very thorough answer. Kudos to you!
  • FlySoFast
    FlySoFast over 2 years
    This is so elegant! Thanks man!
  • Jordan Mitchell Barrett
    Jordan Mitchell Barrett about 2 years
    terminal.integrated.shellArgs is now deprecated - see @Robert's answer below for a modern solution.