Until recently, when I've launched the integrated terminal in Visual Studio Code, bash runs both my .bashrc and my .bash_profile files. But now it's only running the .bashrc file. I need it to run both.
Some details: VSC 1.70.1 (latest), with the "Remote - SSH" extension, running under Windows 10 (updated) with WSL 2 installed. When I launch a Microsoft terminal, it runs both .bashrc and .bash_profile, but VSC's integrated terminal only runs the former. This probably means I have s.t. wrong in my VSC config, but the settings there seem to change frequently and it's hard to keep up. The relevant parts seem to be
"terminal.integrated.defaultProfile.windows": "WSL",
"terminal.integrated.profiles.windows": {
"bash":{
"path": "C:\\Windows\\System32\\bash.exe",
"args": ["-l"]
},
"WSL": {
"path": "C:\\WINDOWS\\System32\\wsl.exe",
"args": [ ],
"icon": "terminal-ubuntu"
}
},
but that doesn't work, nor do any of the variants I've tried on the two "args" parameters, nor changing the defaultProfile to "bash" instead of "WSL".
Before I give in and put all my startup settings in my .bashrc file and get rid of my .bash_profile file, what do I yet lack?
The historical presumption on UNIX is that .bash_profile runs once when you log in, then .bashrc runs in each new shell. Thus, things that are inherited by child processes (like environment variables) go in .bash_profile so they can only run once per login (often, as a parent process to xinit or otherwise GUI startup), whereas things that need to be separately configured for each new shell (like aliases, non-exported functions, prompt settings, etc) go in .bashrc.
If, however, you're in an environment where .bash_profile isn't run during session creation, you might want to invoke it during .bashrc operation (so it happens during setup of any new interactive shell). Consider adding the following to your .bash_profile:
# put this at the top of your .bash_profile
[[ $profile_already_sourced ]] && return
declare -x profile_already_sourced=1 # export so we only run once per process tree
# ...set up your environment variables here...
[[ -s ~/.bashrc ]] && source ~/.bashrc
...and the following to your .bashrc:
# put this at the top of your .bashrc
[[ $bashrc_already_sourced ]] && return
declare -- bashrc_already_sourced=1 # do not export this!
# ...do your non-exported shell-local configuration here...
[[ -s ~/.bash_profile ]] && source ~/.bash_profile
...that way you can have each file source the other when needed without causing an infinite loop.
I can't reproduce this after even after upgrading to 1.70.1, so I'd recommend trying out these things:
try
"path": "C:\\WINDOWS\\System32\\wsl.exe",
"args": ["-e", "bash", "-li"]
to make sure that a login shell is started
if this changed after upgrading, read Help -> Release Notes to find out what might be responsible, e.g. the Shell integration is now enabled by default, so you might try "terminal.integrated.shellIntegration.enabled": false
sync / backup your settings, re-install vanilla VSC, check if behaviour is still the same
Related
MacOS Ventura 13.1
M2 Silicon
Trying to set up a new mac. On my existing Mac, I have a .zshrc, and in it, I have the following:
## begin Git branch prompt
git_branch_test_color() {
local ref=$(git symbolic-ref --short HEAD 2> /dev/null)
if [ -n "${ref}" ]; then
if [ -n "$(git status --porcelain)" ]; then
local gitstatuscolor='%F{red}'
else
local gitstatuscolor='%F{green}'
fi
echo "${gitstatuscolor} (${ref})"
else
echo ""
fi
}
setopt PROMPT_SUBST
PROMPT='%/ $(git_branch_test_color)%F{none} $ '
# add 24h time the right side
RPROMPT='%D{%m-%d-%Y %k:%M:%S}'
## end Git branch prompt
And I would get something like:
/Users/jmac/Development/repos/p1 (development) $ 02-16-2023 19:20:56
(development) is in red, because I have not checked in my changes and the full path is there for me to see.
On the new Mac, there is no .zshrc by default, so I added the code to the .zprofile file, and it's not working the same. I see the date/time on the right, but I don't see the full path and the prompt looks like this:
/Users/jmac p1 % 02-16-2023 19:20:56
Any ideas? prompt modification is not my forte.
The short answer: create a ~/.zshrc file and move that code into it.
The slightly longer answer: something is overriding the value in the PROMPT variable. There isn't anything in the default zsh installation that'll turn the $ in your prompt into a %.
That 'something' could be in a few different forms. There may be code that is modifying the PS1 variable, which is essentially a synonym for PROMPT. Or there may be something hidden in scripts or functions called from ~/.zprofile (for example, oh-my-zsh does this, albeit usually from ~/.zshrc).
Some options
Try to trace what's happening in the zprofile file. One way to do that is to run these commands:
setopt xtrace
. ~/.zprofile
The main challenge here is often the sheer volume of the output; it may be difficult to find the spot where the prompt is being set.
Move the PROMPT assignment to the bottom of ~/.zprofile. Then your assignment should override whatever is setting the value earlier in the process.
Move the PROMPT assignment into ~/.zshrc. This is a better place for the assignment anyway, since .zshrc is only loaded for interactive shells, and setting the prompt is only used in interactive shells.
The code in ~/.zshrc is loaded after the code in ~/.zprofile, so this has a similar effect to the prior option.
If none of these options have any effect, then you'll need to look for other startup files, e.g. ~/.zlogin. There's a nice overview of how the various dot files are handled in zsh in this answer.
I have the following files to handle shell configuration:
#~/.bash_profile
if [ -f ~/.bashrc ]; then
source ~/.bashrc
fi
and
#~/.bashrc
... configure shell
If I open VSCode from the command line using code, my .bashrc is loaded whenever I add a new instance of the integrated shell.
However if I open VSCode via its icon, only my .profile is loaded.
How can I ensure my .bashrc is loaded instead?
I've tried various settings for the terminal.integrated.shellArgs.osx setting without any luck.
Simply add shell arguments to the VsCode settings.json file.
Paths to the settings.json file are as follows:
Windows: C:\Users\<username>\AppData\Roaming\Code\User\settings.json`
Linux: $HOME/.config/Code/User/settings.json
Mac: $HOME/Library/Application\ Support/Code/User/settings.json
Add one of the following:
"terminal.integrated.shellArgs.windows": ["-l"],
"terminal.integrated.shellArgs.linux": ["-l"],
"terminal.integrated.shellArgs.osx": ["-l"],
This will launch your shell of choice with the login argument. This will thus execute any user profile that is setup.
VSCode has deprecated "terminal.integrated.shellArgs.osx" in favor of using profiles. This does the trick for bash in osx. Omit the first line if you don't want bash to be your default profile:
"terminal.integrated.defaultProfile.osx": "bash",
"terminal.integrated.profiles.osx": {
"bash": {
"path": "bash",
"args": ["-l"]
}
}
Another possible solution that just worked for me. The settings.json file (whcih you can access in File > Preferences > Settings > Features > terminal > Integrated > Automation Shell: Linux) had a parameter
"terminal.integrated.inheritEnv": false
set to false by default. Changing it to true fixed the problem in my case.
I had the same problem with the Intellij Idea terminal on a Mac, the solution is the same for both. In settings change the path to the integrated terminal to "/bin/bash". Hope that helps.
You could also try the following:
1 Create a file named /usr/local/bin/bash-login and add :
#!/bin/bash
bash -l
2 Run:
chmod +x /usr/local/bin/bash-login
to make it executable.
3 On your VSC user settings add
{ "terminal.integrated.shell.osx": "/usr/local/bin/bash-login" }
The solution was described at https://github.com/Microsoft/vscode/issues/7263.
Hope it helps
"terminal.integrated.shellArgs.osx": ["-l"] is deprecated.
I personally wanted to use .bash_profile, so I made a .bashrc with this:
if [ -f ~/.bashrc ]; then
source ~/.bash_profile
fi
And then I had to do a full computer restart (just restarting VS code didn't work).
Bash will load various DotFiles sequentially:
~/.bash_profile
~/.bash_login
~/.profile
If ~/.bash_profile been loaded, the second and third one will not be loaded.
If ~/.bash_profile is not loaded, bash will find second one. If ~/.bash_login been loaded, the third one will not be loaded.
If ~/.bash_profile and ~/.bash_login are both not loaded, Bash will try to load ~/.profile file.
A fresh Ubuntu installation will only contains ~/.profile file. So I think it will be better NOT to use the ~/.bash_profile to avoid issues happening. Just use the ~/.profile file. Then your VSCode won't need to config anything.
I was having this issue too. But in my case I was on windows with Visual Studio code opening a remote dev env inside my CentOS WSL.
So fixing the configuration of this use case was a bit different.
In the IDE open settings. Then at the top select "Remote [WSL: XXX]"
The scroll down to Integrated -> Profiles: Linux
And click edit in settings.json
Then I added the following to the file:
"terminal.integrated.defaultProfile.linux": "bash",
"terminal.integrated.profiles.linux": {
"bash": {
"path": "bash",
"args": ["-l"]
}
}
Save the settings file and the next terminal you open will respect your ~/.bash_profile.
NOTE: my ~/.bash_profile had the same lines that someone else recommended adding to load the bashrc file in it already.
I've used bash for two years, and just tried to switch to zsh shell on my OS X via homebrew. And I set my default (login) shell to zsh, and I confirmed it's set properly by seeing that when I launch my Terminal, it's zsh shell that is used in default.
However, when I try to enter bash shell from within zsh, it looks like not loading ~/.bash_profile, since I cannot run my command using aliases, which is defined in my ~/.bash_profile like alias julia="~/juila/julia", etc.. Also, the prompt is not what I set in the file and instead return bash-3.2$.
For some reasons, when I set my login shell to bash, and enter zsh from within bash, then ~/.zshrc is loaded properly.
So why is it not loaded whenever I run bash from within zsh? My ~/.bash_profile is symbolic linked to ~/Dropbox/.bash_profile in order to sync it with my other computers. Maybe does it cause the issue?
Open ~/.zshrc, and at the very bottom of the file, add the following:
if [ -f ~/.bash_profile ]; then
. ~/.bash_profile;
fi
Every time you open the terminal, it will load whatever is defined in ~/.bash_profile (if the file exist). With that, you can keep your custom settings for zsh (colors, and etc). And you get to keep your custom shell settings in .bash_profile file.
This is much cleaner than using bash -l IMO.
If you prefer putting your settings in .bashrc, or .bash_login, or .profile , you can do the same for them.
Similarly, you could also move the common profile settings to separate file, i.e. .my_common_profile, and add the following to both .bash_profile and .zshrc:
if [ -f ~/.my_common_profile ]; then
. ~/.my_common_profile;
fi
An interactive bash reads your ~/.bash_profile if it's a login shell, or your ~/.bashrc if it's not a login shell.
A typical .bash_profile will contain something like:
if [ -f ~/.bashrc ]; then . ~/.bashrc; fi
so .bashrc can contain commands to be executed by either login or non-login shells.
If you run bash -l rather than just bash, it should read your .bash_profile.
Reference: https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html
For those who have just installed zsh and want their alias from bash to work on zsh do the following
Open .zshrc file in vim like so
vi ~/.zshrc
Scroll to the bottom
click "i" to enable write mode
Tell zsh to load items from bash_profile when needed like so
source ~/.bash_profile
Write and quit like so
:wq
Refresh your zsh like so
source ~/.zshrc
That's it. Now all your saved alias in .bash_profile will be ready to use in zsh.
To complement #Keith Thompson's excellent answer:
macOS:
As #chepner puts it succinctly (emphasis mine):
In OS X, bash is not used as part of the initial [at boot time] login process, and the Terminal.app (or other terminal emulators) process exists outside any pre-existing bash sessions, so each new window [or tab - read: interactive bash shell] (by default) treats itself as a new login session.
As a result, some OSX users only ever create ~/.bash_profile, and never bother with ~/.bashrc, because ALL interactive bash shells are login shells.
Linux:
On Linux, the situation is typically reversed:
bash shells created interactively are [interactive] NON-login shells, so it is ~/.bashrc that matters.
As a result, many Linux users only ever deal with ~/.bashrc.
To maintain bash profiles that work on BOTH platforms, use the technique #Keith Thompson mentions:
Put your definitions (aliases, functions, ...) in ~/.bashrc
Add the following line to ~/.bash_profile
[[ -f ~/.bashrc ]] && . ~/.bashrc
Copy the contents from ~/.bash_profile and paste them at the bottom of ~/.zshrc file.
For ZSH users on MacOs, I ended up with a one liner.
At the very bottom of the ~/.zshrc I added the following line :
bash -l
What it does is simply load the .bash_profile settings(aliases, function, export $PATH, ...)
If you decide to get rid of ZSH and go back to plain BASH, you'll be back to normal with no hassle at all.
If this is something that you do infrequently, or it just isn't appropriate to make changes, you can also 'source' the .bash_profile after launching the child bash shell.
. ~/.bash_profile
This will pull in the settings you make in the .bash_profile script for the life of that shell session. In most cases, you should be able to repeat that command, so it's also an easy way to test any changes that you make without needing to do a full login, as well as bring all of your existing shell sessions up-to-date if you make upgrades to the .bash_profile &/or .bashrc files.
For macOS Big Sur (Version 11.5.2)
Open .zshrc
For example: sudo nano ~/.zshrc
At the end of the file add source ~/.bash_profile
Every time you open the terminal the contents inside the bash profile will be loaded.
Recently I installed oh-my-zsh on OS X and set zsh as default shell and faced the same problem.
I solved this problem by adding source ~/.bash_profile at the end of .zshrc file.
I am using a zsh framework called oh my zsh and I have tried most of the solutions listed here and it broke the format for my custom theme. However, these steps worked for me.
Add new alias(es) at the bottom of my .bash_profile
vi ~/.bash_profile
Make zsh to load items from .bash_profile
source ~/.bash_profile
Refresh zsh
source ~/.zshrc
Restart OSX Terminal app
Try your new alias!
If you'd like to be "profile-centric", you can create .profile as a single source of truth, then load it from both .bash_profile and .zprofile.
.profile
export PATH="/usr/local/opt/python/libexec/bin:$PATH"
# etc., etc.
.bash_profile and .zprofile
if [ -f ~/.profile ]; then
. ~/.profile;
fi
I found this helped bash scripts find the right PATH, etc., and helped me keep configuration in one place.
I am using Lion. I have an error that outputs on every new terminal session:
-bash: __rvm_add_to_path: command not found
It's an almost brand new user account.. RVM is installed on the other account on the machine.. ~/.bashrc & ~/.bash_profile are both blank.. the out put of env is:
TERM_PROGRAM=Apple_Terminal
SHELL=/bin/bash
TERM=xterm-256color
TMPDIR=/var/folders/ry/8zsyknmx7dj4_2zzvn1n71500000gn/T/
Apple_PubSub_Socket_Render=/tmp/launch-jsfKPw/Render
TERM_PROGRAM_VERSION=303
TERM_SESSION_ID=3EBC0F1A-9867-41E5-8873-75E84B9F712F
USER=incorvia
COMMAND_MODE=unix2003
SSH_AUTH_SOCK=/tmp/launch-ZQqgPj/Listeners
Apple_Ubiquity_Message=/tmp/launch-u3d1lp/Apple_Ubiquity_Message
__CF_USER_TEXT_ENCODING=0x1F5:0:0
PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin:/usr/local/git/bin
PWD=/bin
LANG=en_US.UTF-8
HOME=/Users/incorvia
SHLVL=1
LOGNAME=incorvia
DISPLAY=/tmp/launch-0B0I8s/org.x:0
_=/usr/bin/env
I see nothing related to RVM here.. where else can I look?
=====
/etc/bashrc
# System-wide .bashrc file for interactive bash(1) shells.
if [ -z "$PS1" ]; then
return
fi
PS1='\h:\W \u\$ '
# Make bash check its window size after a process completes
shopt -s checkwinsize
# Tell the terminal about the working directory at each prompt.
if [ "$TERM_PROGRAM" == "Apple_Terminal" ] && [ -z "$INSIDE_EMACS" ]; then
update_terminal_cwd() {
# Identify the directory using a "file:" scheme URL,
# including the host name to disambiguate local vs.
# remote connections. Percent-escape spaces.
local SEARCH=' '
local REPLACE='%20'
local PWD_URL="file://$HOSTNAME${PWD//$SEARCH/$REPLACE}"
printf '\e]7;%s\a' "$PWD_URL"
}
PROMPT_COMMAND="update_terminal_cwd; $PROMPT_COMMAND"
fi
=========
Fixed...
In the bottom of my /etc/profile it was sourcing /etc/profile.d/rvm.sh
Don't know how that got there...
Bash loads a series of files during startup. A good overview of the bash startup process can be found here.
Generally, the global settings, /etc/profile, /etc/bashrc, and the associated personalized settings, ~/.profile and ~/.bashrc are loaded, although that is slightly distribution-dependant (and on Mac OS X, for example, by default /etc/profile doesn't exist).
From the RVM Installation page:
Multi-User:
The rvm function will be automatically configured for every user on the system if you install as root. This is accomplished by loading /etc/profile.d/rvm.sh on login. Most Linux distributions default to parsing /etc/profile which contains the logic to load all files residing in the /etc/profile.d/ directory. Once you have added the users you want to be able to use RVM to the rvm group, those users MUST log out and back in to gain rvm group membership because group memberships are only evaluated by the operating system at initial login time.
I'd guess that the other use has installed in Multi-User mode;
/etc/profile probably loads /etc/profile.d/rvm.sh.
To stop it being loaded, you could remove the source RVM line from /etc/profile - this will stop it being loaded for all users, though.
For the account that had a working profile, I had the following .rvmrc:
root#sc-27617:~# cat .rvmrc
export rvm_prefix="/usr/local/lib/sc"
export rvm_path="/usr/local/lib/sc/rvm"
To get the error to go away for my other accounts, I simply copied this file to the other accounts and fixed the permissions (chown johndoe:johndoe /home/johndoe/.rvmrc)...
In Ubuntu 12.04, by default, the /etc/profile.d/rvm.sh will not be loaded when starting a new terminal. So every time, when starting a new termail, cmd as follows must be used to start rvm:
source /etc/profile.d/rvm.sh
And there are two ways to fix it:
open a new terminal-> right click and select Profiles->Profile Preferences->Title and Command->select "Run command as a login shell".
open a new terminal->run cmd as follows then the /etc/profile.d/rvm.sh will be auto loaded in a new terminal:
echo '[[ -s "/etc/profile.d/rvm.sh" ]] && . "/etc/profile.d/rvm.sh" # Load RVM function' >> ~/.bashrc
As some explanation here to say the 1st solution is not a nice one but the 2nd is suggested.
So in other way round, if you do not want the terminal to run something in a new terminal, you need to check whether the auto load is coursed by the two ways:
check whether the "Run command as a login shell" is selected and unselect it.
open the ~/.bashrc file ,find the lines related loading the function and delete it.
I had the same file (/etc/profile.d/rvm.sh) from a previous rvm installation. Deleting that file worked for me as well.
For the sake of being thorough, logging out of the shell seems to be required.
In your /etc/profile change the line:
source /etc/profile.d/rvm.sh
into:
if [ "${SHELL}" != "/bin/sh" ]; then
source /etc/profile.d/rvm.sh
fi
Why?
In Mac OS X the default shell of superuser (root) is a POSIX shell, not a pure Bash. Adding such condition will disable rvm for (possibly) emerygency shell /bin/sh, used by system administrator. That is good. If you would like to install something using root's account, you can always type bash and then rvm … in a command line.
Debian 6.1 scans the /etc/profile.d/ file for all .sh files and includes them, so there's no listing for rvm in any of the profiles or .bashrc files anywhere. Deleting rvm.sh from /etc/profile.d/ solves this.
if you have ZSH or OH-MY-ZSH, then you need to remove source /etc/profile.d/rvm.sh from /etc/zprofile
I would like to create an alias that does the following:
Opens TextMate with ~/.bashrc and allows me to edit it
Once I close TextMate, "sources" ~/.bashrc (so if I add a new alias, for example, it will be available immediately)
I tried the following:
alias b="/usr/bin/mate -w ~/.bashrc; source ~/.bashrc"
but it doesn't work: when I close TextMate, the shell doesn't return.
Any ideas?
I hesitate to suggest it, but if this is a feature you really want, you can make something similar happen by setting the PROMPT_COMMAND variable to something clever.
PROMPT_COMMAND is run every time the shell shows the shell prompt So, if you're okay with the shells updating only after you hit Enter or execute a command, this should nearly do it.
Put export PROMPT_COMMAND="source ~/.bashrc" into your ~/.bashrc file. Re-source it into whichever shell sessions you want the automatically updating behavior to work in.
This is wasteful -- it re-sources the file with every prompt. If you can get your editor to leave the old version in a specific file, say ~/.bashrc~ (where the first ~ means your home directory and the last ~ is just a ~, a common choice for backup filenames) then you could do something more like (untested):
export PROMPT_COMMAND="[ ~/.bashrc -nt ~/.bashrc~ ] && touch ~/.bashrc~ && source ~/.bashrc "
then it would stat(2) the two files on every run, check which one is newer, and re-source only if the ~/.bashrc is newer than its backup. The touch command is in there to make the backup look newer and fail the test again.