Strange behavior of .bashrc - linux

I changed .bashrc file on my web server a little bit, to color links on ls -la and so on. But when I log in using ssh: ssh user#server and type ls -al nothing is coloring, seems like my .bashrc file has not been applied on login. When if I just type bash and then again ls -la - all works fine. In short, all my rules in .bashrc only apllied when I type bash just after authorization, a little boring.

When you log in via ssh, you invoke a login shell. When you type bash in an existing shell, you invoke an interactive shell.
.bash_profile is read when a login shell is invoked, and .bashrc is read when an interactive shell is invoked.
Try adding this to your .bash_profile:
if [ -f ~/.bashrc ]; then
source ~/.bashrc
fi
See bash(1) for more details.

~/.bashrc is only read if the shell is interactive and not a login shell:
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.
Furthermore:
Bash attempts to determine when it is being run with [...] sshd. If bash determines it is being run in this fashion, it reads and executes commands from ~/.bashrc and ~/.bashrc, if
these files exist and are readable. It will not do this if invoked as sh.
So:
your remote shell must be bash, not sh,
it must not be a login shell, and
it must be an interactive shell.

Related

How to Change my default shell on server?

I was assigned an account for log in to a remote server, and I want to change my default shell.
I tried chsh command but it says: chsh: "/public/home/{my_id}/bin/zsh" is not listed in /etc/shells.
If you don't have permission to install zsh system wide, a quick fix is to append exec ~/bin/zsh -l to ~/.bash_profile (if bash is the current shell), or an equivalent rc file for the current login shell.
zsh -l starts zsh as a login shell.
exec COMMAND replaces the current process with COMMAND, so you'll only have to type exit (or press ctrl+d) once.
~/.bash_profile is executed when bash starts as a login shell, you can still run command bash normally.
Depending what is in ~/.bash_profile (or equivalent), you may wish to avoid executing its other contents, by putting exec ~/bin/zsh -l at the start of the file (not the end), and copy/port anything important over to the zsh equivalent, $ZDOTDIR/.zprofile.
I might also do export SHELL="$HOME/bin/zsh", although I'm unsure of the full effects of setting SHELL differently to that specified for your user in /etc/passwd, to a shell not in /etc/shells, and to a shell binary in your home path.
First check all the shells available on your linux system
cat /etc/shells
Use chsh command line utility for changing a login shell with the -s or –shell option like this.
# chsh --shell /bin/sh tecmint

In Linux, when does the "bash" command source a ~/.bash_profile or ~/.profile file?

I am currently using ssh to access a linux computer. I use the command:
ssh -t user#hostaddress 'cd ~/Desktop && bash'
When I get there, I see that neither ~/.bash_profile nor ~/.profile are sourced. What are the rules surrounding when these are sourced in? The reason I call bash is because I am able to get terminal colors when I do bash (blue folders, etc) that I otherwise cannot get just by using ssh user#hostaddress.
You're not running bash as a login shell -- using bash -l should source .bash_profile. Otherwise you can use .bashrc.

My alias name is referring to old alias not a new one [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What's the difference between .bashrc, .bash_profile, and .environment?
It seems that if I use
alias ls='ls -F'
inside of .bashrc on Mac OS X, then the newly created shell will not have that alias. I need to type bash again and that alias will be in effect.
And if I log into Linux on the hosting company, the .bashrc file has a comment line that says:
For non-login shell
and the .bash_profile file has a comment that says
for login shell
So where should aliases be written in? How come we separate the login shell and non-login shell?
Some webpage say use .bash_aliases, but it doesn't work on Mac OS X, it seems.
The reason you separate the login and non-login shell is because the .bashrc file is reloaded every time you start a new copy of Bash. The .profile file is loaded only when you either log in or use the appropriate flag to tell Bash to act as a login shell.
Personally,
I put my PATH setup into a .profile file (because I sometimes use other shells);
I put my Bash aliases and functions into my .bashrc file;
I put this
#!/bin/bash
#
# CRM .bash_profile Time-stamp: "2008-12-07 19:42"
#
# echo "Loading ${HOME}/.bash_profile"
source ~/.profile # get my PATH setup
source ~/.bashrc # get my Bash aliases
in my .bash_profile file.
Oh, and the reason you need to type bash again to get the new alias is that Bash loads your .bashrc file when it starts but it doesn't reload it unless you tell it to. You can reload the .bashrc file (and not need a second shell) by typing
source ~/.bashrc
which loads the .bashrc file as if you had typed the commands directly to Bash.
Check out http://mywiki.wooledge.org/DotFiles for an excellent resource on the topic aside from man bash.
Summary:
You only log in once, and that's when ~/.bash_profile or ~/.profile is read and executed. Since everything you run from your login shell inherits the login shell's environment, you should put all your environment variables in there. Like LESS, PATH, MANPATH, LC_*, ... For an example, see: My .profile
Once you log in, you can run several more shells. Imagine logging in, running X, and in X starting a few terminals with bash shells. That means your login shell started X, which inherited your login shell's environment variables, which started your terminals, which started your non-login bash shells. Your environment variables were passed along in the whole chain, so your non-login shells don't need to load them anymore. Non-login shells only execute ~/.bashrc, not /.profile or ~/.bash_profile, for this exact reason, so in there define everything that only applies to bash. That's functions, aliases, bash-only variables like HISTSIZE (this is not an environment variable, don't export it!), shell options with set and shopt, etc. For an example, see: My .bashrc
Now, as part of UNIX peculiarity, a login-shell does NOT execute ~/.bashrc but only ~/.profile or ~/.bash_profile, so you should source that one manually from the latter. You'll see me do that in my ~/.profile too: source ~/.bashrc.
From the bash manpage:
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 commands 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 ~/.bashrc, if that file exists. 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
~/.bashrc.
Thus, if you want to get the same behavior for both login shells and interactive non-login shells, you should put all of your commands in either .bashrc or .bash_profile, and then have the other file source the first one.
.bash_profile is loaded for a "login shell". I am not sure what that would be on OS X, but on Linux that is either X11 or a virtual terminal.
.bashrc is loaded every time you run Bash. That is where you should put stuff you want loaded whenever you open a new Terminal.app window.
I personally put everything in .bashrc so that I don't have to restart the application for changes to take effect.

#!/bin/bash --login vs #!/bin/bash

I read some following script when looking for script to run Appium with Jenkins
#!/bin/bash --login
killall -9 "iPhone Simulator" &> /dev/null
killall -9 node &> /dev/null
killall -9 instruments &> /dev/null
...
I don't understand why the first line of the script needs to pass a --login option here. I have read the man page but still have some confusions.
What I get from the man page is that passing --login to make the script be called as login shell instead of interactive shell. interactive shell is the shell that users can interact with the shell, like input something with keyboard. But what is login shell? I checked the man page that it said login shell would load ~/.bash_profile, but if open the terminal through Mac OSX's Terminal.app, it also loads the ~/.bash_profile and I am able to interactive with the shell,right? So, the shell I open is both login shell and interactive shell?
The main difference is that a login shell executes your profile when it starts. From the man page:
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 commands 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.

Commands available in bash -i can't access in bash -l

I don't know how to describe it. It just happens when i use vim and set shell=bash -l. Then i found that a command called mm which can execute in terminal can't execute in vim .
And i also found that when i write this command in run.sh and execute this script. It still report command not found. I think there must be something wrong with my $HOME/.bash* files and $HOME/.profile. And i am sure that .profile are almost the same with .bashrc.
From $ man bash:
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 commands from the first one that exists and is readable.
and
When an interactive shell that is not a login shell is started, bash
reads and executes commands from ~/.bashrc, if that file exists.
So:
shell | files loaded
--------+-----------------
bash -l | /etc/profile
| ~/.bash_profile
| ~/.bash_login
| ~/.profile
--------+-----------------
bash -i | ~/.bashrc

Resources