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

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.

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

How to ssh login a system with exit profile

When I add the script snippet "exit 0" in profile, I can not ssh to this linux system any more.
How to fix it.
The actual answer is that you can ssh to that machine, however when doing an ssh it reads your profile where it reads directly exit 0 so it cleanly terminates your ssh session.
If you do something like :
ssh user#machine
Then ssh will try to invoke a login-shell. Assuming your default shell is bash, then you find the following in 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.
So since you have an exit statement in one of those files, your ssh session will terminate immediately.
how to solve it: remove the exit statement.

Can make shell run interactively along with --command option

I'm using GNU bash that is installed as git bash. On startup I need to change directory, so I'm doing it like this:
"C:\Program Files\Git\bin\sh.exe" --rcfile "./cd.sh"
Where cd.sh just contains cd /d/ command. Everything works fine here. Now I'm trying to get rid of cd.sh file and pass command to the shell as a parameter yet I want it to remain interactive, so I'm doing like this:
"C:\Program Files\Git\bin\sh.exe" -ic "cd /d"
It executes the command (tested with echo command) but then exits. Why doesn't it stay interactive?
From man bash:
An interactive shell is one started without non-option arguments and without the -c option ...
From man dash:
If no args are present and if the standard input of the shell is connected to a terminal (or if the -i flag is set), and the -c option is not present, the shell is considered an interactive shell.

What does this command do? "exec bash -l"

What does this command do?
exec bash -l
I found this command as part of a reminder text file were I wrote some instructions regarding how to create a ssh key and clone a git repo, but I wrote it a long time ago and I can't remember what it does.
exec executes a specified command, replacing the current process rather than starting a new subprocess.
If you type
bash -l
at a shell prompt, it will invoke a new shell process (the -l makes it a login shell). If you exit that shell process, you'll be back to your original shell process.
Typing
exec bash -l
means that the new shell process replaces your current shell process. It's probably slightly less resource intensive.
The reason for doing it is probably so that the new shell sets up its environment (by reading your .bashrc, .bash_profile, etc.).
See the bash documentation for more information:
Bash Startup Files for how a login shell differs from a non-login shell
Bourne Shell Builtins for documentation on the exec command.
(You should be able to read the manual on your own system by typing info bash.)
This will replace your current shell with a new bash shell run as a login shell.

Strange behavior of .bashrc

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.

Resources