Hacker News new | ask | show | jobs
by ulizzle 934 days ago
What's a good useful difference between .bashrc and .bashprofile? I usually just ignore everything but the rc files.
2 comments

A shell can be interactive or non-interactive (eg. shell-scripts).

An interactive shell can be a login-shell or a non-login-shell. A login-shell is what you get when you login at one of the virtual terminals of a linux machine. A non-login-shell is a shell started after you logged in (eg. clicking your console-icon in a graphical desktop environment).

An interactive bash will read and execute `bash_profile` (Actually, it will try to read `profile` first, for historic reasons) when it is a login shell, and `bashrc` when it is not.

However, the difference is moot on most systems, since this is what you will probably find in most `~/.bash_profile` files these days:

   [[ -f ~/.bashrc ]] && . ~/.bashrc
aka. all interactive shells, no matter if they are or aren't a login shell will just read `.bashrc`

For completeness sake: A shell run via `sshd` is technically not an interactive shell, as it is started by the ssh-daemon. However, bash behaves like an interactive non-login shell in this case and reads `bashrc`.

Also for completeness sake: All the files mentioned can be system-wide under `/etc/FILENAME` and user specific (`~/.FILENAME`). Bash first reads the files in `/etc`.

The behavior is documented in the manpage `man bash`, under the section `INVOCATION`.

> An interactive shell can be a login-shell or a non-login-shell.

A shell can be login and non-interactive.

This happens e.g when starting a session from a X session manager. Subsequently a terminal such as Xterm starts non-login interactive sessions, inherits stuff like env vars like PATH from the login shell, and is only concerned with setting up the additional interactive stuff.

Similarly doing ssh <host> <command> starts a non-interactive login shell.

> However, bash behaves like an interactive non-login shell in this case and reads `bashrc`.

IIRC nope: distros such as Debian often have bashrc source bash profile (or the other way around, I can't recall) which has me irate to no end+. They even have some TTY dependent stuff in profile which spits out some error in some cases when no TTY is allocated because heh not interactive.

+ I took great length to have my rc and profile properly separated because it's that much faster not to source the unneeded stuff (at the cost of having to logout to apply login stuff) https://github.com/lloeki/dotfiles

> Similarly doing ssh <host> <command> starts a non-interactive login shell.

Interesting, is there a source for this? Genuinely interested, because the manpage leaves this part a bit vague:

    A login shell is one whose first character of argument zero is a -, or
    one started with the --login option.
    (...)
    Bash attempts to determine when it is being run with its standard input
    connected to a network connection, as when  executed  by the historical
    remote shell daemon, usually rshd, or the secure shell daemon sshd.
    If bash determines it is being run non-interactively in this fashion, it
    reads and executes commands  from  ~/.bashrc, if  that file exists
    and is readable.
Sadly, the manpage for sshd also doesn't mention how exactly the users shell is invoked. It does say however:

    After  this,  the client either requests an interactive shell or
    execution of a non-interactive command
...which I took to understand that the shell dows in fact run as an interactive shell.

> IIRC nope: distros such as Debian often have bashrc source bash profile

Well, these are distro dependent things. Since I am not on Debian, I am just refering to the manpage.

You can try this out:

  ssh user@host export
  vs
  ssh user@host --> export
  or
  ssh user@host bash --> export

But it's not sshds job to specify how either shell type is requested.
> A shell run via `sshd` is technically not an interactive shell, as it is started by the ssh-daemon.

Hmmm....I'm a bit confused by that one. Why is the program that started the shell an important consideration as to whether it should be considered interactive or not? Shouldn't it just be how the shell is most likely to be used?

Are shells started by `xterm` (and similar) "technically" interactive? What about shells started by `screen`/`tmux`? What makes them different to, or the same as, `sshd`?

"Interactive" in this sense has less to do with how the shell is used, and more with how it is invoked and connected to it's environment.

From the manpage:

     An interactive shell is one started without non-option arguments
     (unless -s is specified) and without  the  -c option,  whose  standard
     input and error are both connected to terminals (as determined by
     isatty(3)), or one started with the -i option.
Technically, the shell isn't connected to a terminal when started by sshd but to the ssh connection. So yeah, from the point of view of the user, it is absolutely interactive, but not from the point of view of bashs internal logic.
Huh. My intuition would have been that stdin/stderr provided by sshd to the shell would have been been marked as `isatty(3)`. TIL.
The interesting thing is, `isatty()` seems to report 1 even over an ssh connection...so yeah, purely from that point of view, the shell should be "interactive". Why this case is then marked as special in the bash manpage, I cannot say :D
This diagram should clear things up in a confusing manner.

https://i.pinimg.com/736x/13/be/5b/13be5b89e662930a2b2dc1573...

I would expect nothing less from Bash. Presumably this is the simplified version...