How to "source" ~/.bashrc automatically once it has been edited? - macos

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.

Related

echo $PATH not reflecting saved paths

I have attempted to add, export PATH="$PATH:/Users/My_Name/desktop/My_Folder", to .bash_profile, .bashrc, and .profile. I executed the command source ~/.bash_profile, source ~/.bashrc, and source ~/.profile to refresh the $PATH and it does reflect that when I execute echo $PATH.
However, when I open a new terminal and execute echo $PATH it is unchanged.
The issue is my system (macOS Big Sur) will not recognize the updated $PATH when I open a new terminal unless I execute the source command every time to refresh my $PATH.
For context, I edited all three because I have scoured multiple sites for suggestions and have exhausted all my options.
Solution: I realized that I was using zsh. To change I executed chsh -s /bin/bash to change my shell to bash.
Solution: I realized that I was using zsh. To change I executed chsh -s /bin/bash to change my shell to bash.
You need to open your .profile file in an editor like nano or pico and make sure your command is at the bottom of the file. Also, make sure you close your quotes like this:
export PATH="$PATH:/Users/My_Name/desktop/My_Folder"
You might also consider placing the new path at the front like this:
export PATH="/Users/My_Name/desktop/My_Folder:$PATH"
I have an alias in my profile folder called reBASH looks like this
alias reBASH='source ~/.bash_profile'
So that when I change .bash_profile, I merely type reBASH, hit enter and it gets applied to the current session ... just something you might consider as a convenience when doing things like this.

ZSH always requires to restart terminal in order to access alias

I have added several aliases to my .zshrc file and they ONLY work if I restart terminal or use the source ~/.zshrc If I just open terminal, then type the alias, it will not recognize it, until I call source ~/.zshrc
So I know it's not a problem with the alias I created, I just have to load up the .zshrc file every time I want to use them.
What is going on? How can I fix this?
Well, you don't expect that you only have to edit a file and then, by magic, all your current zsh instances somehow ingest the changes, do you?
From the zsh man page, section STARTUP/SHUTDOWN FILES :
if the shell is interactive, commands are read from /etc/zshrc and then $ZDOTDIR/.zshrc
($ZDOTDIR defaults to your $HOME). Hence, if you are in your terminal, you have three choices. Two of them you already found out (restart the terminal, source .zshrc manually). The third choice would be to just open a zsh subshell (by typing zsh).
Actually, there is a trick to do some "magic" in reading the file automatically: Zsh allows you to define a so-called precmd hook, which allows you to establish an arbitrary command to be executed just before a command prompt will be displayed. You could use it to source any file you like. If you want to use this feature, I strongly recommend against sourcing all of .zshrc. Sooner or later, you will have stuff in .zshrc that you don't want to be executed every time.
Instead, put your alias definitions into a separate file, say $HOME/.aliases, and in Zsh define the hook
function precmd {
source $HOME/.aliases
}
If you later change the .aliases file, you would still have to type a Carriage Return in your shell, in order to provoke a new prompt to be written and the precmd to be executed, but this is less cumbersome than sourcing the file manually.

How to load ~/.bash_profile when entering bash from within zsh?

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.

Why do I need to source bash_profile every time

I have installed Hadoop and every time I want to run it, first I have to do this:
source ~/.bash_profile
or it won't recognize the command hadoop
Why is that?
I am on OSX 10.8
Now that we've narrowed down the problem:
Run ps -p $$ at the command line to check if you are, in fact, using a bash shell.
Realize that you are in zsh, which means you should be editing your profile in .zshrc.
Copy the offending lines from .bash_profile to .zshrc, OR
Modify your .zshrc to directly source your .bash_profile.
UPDATE: Do what #TC1 mentions in the comments and keep the shell-specific code in each shell's own profile, and from those profiles, only source shell-agnostic code.
On Mac Catalina, I just had to open "preferences" on terminal and change the "shells open with" from "default" to "Command(complete path)", which the default path was "/bin/zsh". touch ~/.zshrc, if that file doesn't exist already, and copy/paste your stuff from ".bash_profile" into the ".zshrc" file.
To elaborate, with terminal running, I opened "settings" from the Terminal menu on the Mac navbar. On the "General" tab, look for "Shells open with" select "Command (complete path)", and type in /bin/zsh.
bash_profile.sh is applicable for bash shell.
if your default shell is not bash and if your default shell is someother shell for example zsh then you have to manually load the .bash_profile using source ~/.bash_profile.
You can always change the default shell to bash shell so that the .bash_profile file will be automatically loaded.
Inorder to automatically load .bash_profile, you can update your default shell to bash using the command chsh -s /bin/bash
cat /etc/shells will list the default shells available in the
machine
echo $SHELL will display the currently active shell in your machine
To change active shell to a different shell, use chsh -s /bin/bash.
Then echo $SHELL to verify if the shell has changed.
Terminal -> Preference -> profile -> Shell -> Run command : source ~/.bash_profile
Tick on run inside shell.
After doing all those , just logout and check weather everything works fine or not
I tried the approved answer. Changing the .zshrc file works for one of my machines. But for the other one, when I run ps -p $$, it is -sh under the command. And I changed both bash and zsh files, neither of them works for me this time.
So I found this
https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html
it mentioned
"When Bash is invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first reads and executes commands from the file /etc/profile, if that file exists. "
so I went to that file /etc/profile and add "source ~/.bashrc" in that file. Then it works since every time a terminal is opened, it runs the command in that /etc/profile file.
Not sure if this is the best solution but it works.
sudo nano /etc/bashrc and change that, restarted the terminal and it finally remembered with command. Tried ~/.bash_profile and ~/.bashrc without success, just wasn't sourcing it.
Go to “Preferences/Profiles then look in the right window and find “shell”.
Once in that if your “Startup Run Command” hasn’t been turned on. Click the box to turn it on and in the command section type:
(If you made a .zsh file)
source .zsh ; clear
(If you made a .bash_profile)
source .bash_profile ; clear
Doing this ; clear
Will clear your terminal to a new page so that you don’t see your terminal display:
“Last login: etc
User#user-Mac ~ % source .zsh
If you typed the commands as I said you should just get this:
User#user-Mac ~ %
That way you will be greeted with a clear page with no extra jumbo. Also to make sure that your .zsh or .bash_profile aliases work type the following command to see a list of your custom aliases:
Alias
One alias I like to do is
alias LL=“ls -la”
This will display a tree or the directory you are in as well as hidden files.

How to reload .bash_profile from the command line

How can I reload file .bash_profile from the command line?
I can get the shell to recognize changes to .bash_profile by exiting and logging back in, but I would like to be able to do it on demand.
Simply type source ~/.bash_profile.
Alternatively, if you like saving keystrokes, you can type . ~/.bash_profile.
. ~/.bash_profile
Just make sure you don't have any dependencies on the current state in there.
Simply type:
. ~/.bash_profile
However, if you want to source it to run automatically when terminal starts instead of running it every time you open terminal, you might add . ~/.bash_profile to ~/.bashrc file.
Note:
When you open a terminal, the terminal starts bash in (non-login) interactive mode, which means it will source ~/.bashrc.
~/.bash_profile is only sourced by bash when started in interactive login mode. That is typically only when you login at the console (Ctrl+Alt+F1..F6), or connecting via ssh.
If you don't mind losing the history of your current shell terminal, you could also do
bash -l
That would fork your shell and open up another child process of bash. The -l parameter tells Bash to run as a login shell. This is required, because .bash_profile will not run as a non-login shell. For more information about this, read here.
If you want to completely replace the current shell, you can also do:
exec bash -l
The above will not fork your current shell, but replace it completely, so when you type exit it will completely terminate, rather than dropping you to the previous shell.
You can also use this command to reload the ~/.bash_profile for that user. Make sure to use the dash.
su - username
I like the fact that after you have just edited the file, all you need to do is type:
. !$
This sources the file you had just edited in history. See What is bang dollar in bash.
You just need to type . ~/.bash_profile.
Refer to What does 'source' do?.
Save the .bash_profile file
Go to the user's home directory by typing cd
Reload the profile with . .bash_profile
Add alias bashs="source ~/.bash_profile" into your Bash file.
So you can call bashs the next time.
If the .bash_profile file does not exist, you can try to run the following command:
. ~/.bashrc
or
source ~/.bashrc
instead of .bash_profile.
You can find more information about bashrc.
Use
alias reload!=". ~/.bash_profile"
Or if want to add logs via functions:
function reload! () {
echo "Reloading bash profile...!"
source ~/.bash_profile
echo "Reloaded!!!"
}
While using source ~/.bash_profile or the previous answers works, one thing to mention is that this only reloads your Bash profile in the current tab or session you are viewing. If you wish to reload your bash profile on every tab/shell, you need to enter this command manually in each of them.
If you use iTerm, you can use CMD⌘ + Shift + I to enter a command into all current tabs. For terminal it may be useful to reference this issue;
I use Debian and I can simply type exec bash to achieve this. I can't say if it will work on all other distributions.
I am running macOS v10.12 (Sierra) and was working on this for a while (trying all recommended solutions). I became confounded, so I eventually tried restarting my computer! It worked.
My conclusion is that sometimes a hard reset is necessary.
Simply re-sourcing the file won't "reload" in the sense that something is first unloaded, then loaded again. If that is what you want you can do:
hash -r && _SHOW_MESSAGES=1 exec -a -bash bash

Resources