Lets say I have a perl script that setups a bash_aliases as follow
source file: bash_aliases.sh
alias w="cd /var/www"
install.pl
#!/usr/bin/perl
my $aliase_src= "${installation_dir}/bash_aliases.sh";
my $aliase_target="$ENV{'HOME'}/.bash_aliases";
if (! copy($aliase_src,$aliase_target))
{
print "Failed to copy file $aliase_src to Destination:$aliase_target. Reason:$! .";
die;
}
[command required to load .bash_aliases file]
I should be able to go as follow:
./install.pl
w
I dont want to :
./install.pl
source ~/.bash_aliases
w
I am unable to find command to load these aliases such that once the file is moved to home directory these aliases should be available to current script (install.pl) as well as all other script without running another command from command line e.g source ~/.bash_aliases OR . .bash_aliases
Edit
auto_load_aliases.sh using PROMPT_COMMAND (trying to following l0b0, answer)
#!/bin/bash
echo 'alias test="echo tested"' > $HOME/.bash_aliases
export PROMPT_COMMAND="$HOME/.bash_aliases";
this also did not work :
./auto_load_aliases.sh
test
What I expected what that auto_load_aliases.sh script sets the PROMPT_COMMAND , once it's set I have test aliase available.But that did not work.
~/.bash_aliases is not loaded by Bash by default, it is just a common convenience to avoid putting too much stuff in ~/.bashrc. If you want the aliases to be available in new Bash shells you have to source ~/.bash_aliases somewhere in ~/.bashrc. Some popular distributions (I believe Ubuntu is one) does this by default.
If you want to automatically source ~/.bash_aliases after changing it, you could try adding this in ~/.bashrc to source it after each command:
PROMPT_COMMAND='source ~/.bash_aliases'
If your alias file is very complex, you could make this faster by using inotifywait and only reloading the file when it changes.
Another way of loading aliases after changing them would be to replace the current shell with another one:
exec "$SHELL"
Bottom line, something has to change to automatically load new aliases. There is no built-in runtime configuration option in Bash to do this (and even then you'd have to enable that option).
Related
Bash will source automatic profiles such as .bashrc. --rcfile option can be used to override the automatic script. But I need to source additional personalized file (that's the automatic script plus another file) when launching the bash shell without touching ANY files in $HOME or /etc directory since $HOME directory belongs to application run user. The personalized file must not be located in $HOME directory.
Is this possible?
I tried:
/bin/bash <<EOF
. /a-directory-outside-of-home/vanilla
EOF
but it returned to the current shell.
Okay, so you want to run the user's normal .bashrc, followed by your own script, and you want to trigger this behavior in the way that bash is called, correct?
The call:
/bin/bash --rcfile myscript
First line of myscript:
source $HOME/.bashrc
bash --rcfile <(cat rcfile1; cat rcfile2)
works just fine and requires no modifications anywhere.
Add your stuff as *.sh files in /etc/profile.d -- read /etc/profile and
http://www.gnu.org/software/bash/manual/bashref.html#Bash-Startup-Files
I wouldn't modify the .bashrc file. Instead, I would modify the .bash_profile
file which is located at $HOME.
It is the place from where .bashrc is included.
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/bashrc
fi
A good option for you is to add a .personalized_settings file and include it
just below the above lines like this.
# Adding personalized settings
if [ -f ~/.personalized_settings ]; then
. ~/personalized_settings
fi
This requires that .personalized_settings file is located at $HOME.
I have tested the above in Fedora12.
Edit :
You might need to look for .profile instead of .bash_profile in Ubuntu (and hopefully other Debian based systems). (courtesy #Benjamin W.)
This (link)[https://www.gnu.org/software/bash/manual/bash.html#Bash-Startup-Files] will give you more information on it.
What if you mess around with any of the profile files?
You have a back-up copy of all these files in /etc/skel which you could
use to restore.
How do I write a simple Python script that is globally executable via a simple command (such as cd or pwd)?
I know the file has to be executable and in my $PATH. I know I can omit the python prefix when calling the file by specifying the interpreter. But then I still have to call the script using the ./script syntax.
I basically want to create a bunch of Python CLI programs stored ~/bin and have them behaving the same way as Bash scripts like cd and pwd.
You just need to add ~/bin to your PATH. For example, you could add something like this to your ~/.bashrc file:
export PATH="$HOME/bin:$PATH"
To see the changes in the current shell, you can then do . ~/.bashrc. The path should automatically be added in all new shells that you open. You can check by doing echo "$PATH" - you should see that it starts with /home_directory/bin:....
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.
After start the cygwin shell, it just locate in a wrong home dir:
xfire#codingme.com ~
$ pwd
/cygdrive/c/Users/xfire
But it used to be /home/xfire
xfire#codingme.com /etc
$ cat passwd | grep xfire
xfire:unused:22773:10513:U-CORP\xfire,S-1-5-21-527237240-725345543-682003330-12773:/home/xfire:/bin/bash
And the .bashrc in the /home/xfire was not executed, even I copy it to the /cygdrive/c/Users/xfire, it also doesn't work!
On cygwin, I add this to my ~/.bash_profile:
. ~/.bashrc
Some program add an "HOME" environment in windows registry and set the value to "C:\Users\xfire", that's why cygwin take that directory as the home. cygwin.com/faq-nochunks.html
On my version of cygwin I found that only ~/.profile was being execueted so added
if [ -e "${HOME}/.bash_profile" ]; then
source "${HOME}/.bash_profile"
fi
to the .profile file. My .bash_profile file contains another test for .bashrc and executes that from inside there. I also added the following two lines to my .bashrc file.
export BASH_ENV="${HOME}/.profile"
export ENV="${HOME}/.profile"
The first of these ensures that .profile gets executed in non-interactive terminals and the second ensures it gets executed in POSIX terminals. I found a very useful explanation of what get run and when in the Bash Reference Manual.
In your case it wouldn't help as you have an issue with the value of your HOME environment variable but this page comes up quite high on the list when searching for this issue.
You can also also set BASH_ENV variable, e.g., BASH_ENV='C:\DOCUME~1\dwyttenb\.bashrc'
~/.bash_profile is executed before the initial command prompt is returned to the user. After that, every time a new shell is opened, ~/.bashrc is executed.
Adding . ~/.bashrc at end of ~/.bash_profile has resolved the problem.
Now you can check existing aliases using alias command.
Find more details on github.
in "Bash Guide for Beginners", it's said:
Bash is the GNU shell, compatible with the Bourne shell and incorporating many useful features from other shells. When the shell is started, it reads its configuration files. The most important are:
/etc/profile
~/.bash_profile
~/.bashrc
however, in my ubuntu 11.10,
- there's no "~/.bash_profile": file explorer does not show it, and "ls -l ~/.bash_profile" says "No Such file or directory"
- there are "/etc/profile" and "~/.bashrc", but they don't show up in file explorer, only "ls -l /etc/profile" and "ls -l /.bashrc" shows the result.
is there something missing during my installation?
No, it's fine if those files aren't there, they'll just be ignored. To get a complete list of what's loaded and in what order, run man bash and check the section on INVOCATION (use "/" and type in INVOCATION to search)
Edit: saving #athos a man bash call ;)
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. After reading that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes com‐
mands from the first one that exists and is readable. The --noprofile option may be used when the shell is started to inhibit this behavior.
When a login shell exits, bash reads and executes commands from the file ~/.bash_logout, if it exists.
When an interactive shell that is not a login shell is started, bash reads and executes commands from /etc/bash.bashrc and ~/.bashrc, if these files exist. This
may be inhibited by using the --norc option. The --rcfile file option will force bash to read and execute commands from file instead of /etc/bash.bashrc and
~/.bashrc.
Here I discuss, how to set JAVA_HOME variable and the PATH variable to your Java installation.
First using the terminal open the .bashrc which is at your home.
gedit ~/.bashrc
Now add the following to the end of the file.
JAVA_HOME=/usr/lib/jvm/java
export JAVA_HOME
PATH=$PATH:$JAVA_HOME/bin
export PATH
NOTE: If /usr/lib/jvm/java does not match the actual JAVA_HOME path in your environment, then set the actual JAVA_HOME, where you have installed Java in your machine.
Now run,
source ~/.bashrc
Then, try running the following commands and check whether your getting the appropriate responses:
echo $JAVA_HOME
/usr/lib/jvm/java
echo $PATH
:/usr/lib/jvm/java/bin
If it not work try after restarting
It also reads /etc/bashrc, which is probably present on your system.
I'm pretty sure that you also have ~/.profile (that one it reads as well) or ~/.bashrc.
If those files are missing, feel free to create them and fill with whatever you need.