shells, bashrc and fish
This post a about some sh/bash/fish configuration and, how to use fish together with bash.
§ the deal with sh
- the original
sh
is Bourne-Shell bash
stands for Bourne-Shell-Again-Shell, a de-facto replacement tosh
.
actually it’s linked to bash (or other shells like dash
). Note that when
bash
and dash
etc. are invoked with the sh
name, the become more POSIX
compliant1.
$ ls -l $(which sh)
lrwxrwxrwx 1 root root /usr/bin/sh -> bash
The there are ports of the original Bourne-Shell (sh) e.g. v7sh
§ the deal with bashrc
– it’s a fuckign mess.
- login shell:
/etc/profile
->~/.bash_profile
->~/.bash_login
->~/.profile
- interactive non-login shell :
/etc/bash.bashrc
2 ->~/.bashrc
- logout:
/bash.bash_logout
2 ->~/.bash_logout
- non-interactive shell: inherit whatever the calling process has and nothing more.
what is system default doing i.e. /etc/bash.bashrc
:
- check window size per
$DISPLAY
- sets control sequence correctly for the prompt, depending on terminal type (screen, tmux, xterm, foot, …)
- source completion commands
Note that when using bash as login shell, the ~/.bashrc
is not sourced. For it
to work, include the following line in ~/.bash_profile
or ~/.profile
[[ -f ~/.bashrc ]] && . ~/.bashrc
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. The
--noprofile option may be used when the shell is started to inhibit this
behavior.
When an interactive login shell exits, or a non-interactive login shell
executes the exit builtin command, 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 in‐stead of ~/.bashrc.
refs:
§ fish shell (fuck)
I read on HN that you should set fish as terminal shell instead of login shell (i.e. through chsh). Pretty interesting idea. I’ll try that.
source the source
There are a few issues with fish shell.
- it can’t explcitly source
.bashrc
. Meaning if you are using fish as login shell, it can not use what’s already there. Luckily my plan here is NOT TO use fish as login shell. But I still need a sanity check to make sure .bashrc is already sourced before fish is invoked.
in.bashrc
inexport BASHRC_SOURCED="yes"
config.fish
if not set -q BASHRC_SOURCED echo "[WARNING!] .bashrc is not sourced, do not use fish as login shell!" end
- bash aliases are not inherited to fish, therefore you need to source it
explicitly… (fuck)
in~/.bash_aliases
inalias abc=xyz # your aliases
~/.bashrc
in[[ -f ~/.bash_aliases ]] && . ~/.bash_aliases
config.fish
(perhaps check for file exists, but I won’t bother learning how fish scripting work)source ~/.bash_aliases
wipe their builtin functions
have you ever wondered why your grep
, ls
and kill
works differently than
you expected? Or why your colors are wrong? Or why your aliases doesn’t work?
That’s because fish
is trying hard to give you wrappers to the very basic
stuffs.
ls
becomes a bloated cyptic script.man
becomes a bloated cryptic script.kill
receives(__fish_expand_pid_args $argv)
which is another layer of cryptic indirection.diff
andgrep
receive--color=auto
- … check
fish_config
-> functions for yourself.
Therefore you may want to wipe these builtins. In config.fish
# functions --erase grep
# functions --erase kill
# functions --erase ls
# functions --erase ll
# functions --erase la
Trivias: in case you don’t know, on linux, the commands like cd
must be
implemented into the shell, not as an external program or script. Every process
has a working dir, tracked in task_struct.fs
and is changed via the
chdir
syscall.
In otherwords, a process can only change its own workding directory, therefore
you can’t implement cd
as a program.
§ epilogue
TAKE: While shells are supposed to implement their UNIX builtin functions (like. cd
,
pushd
, popd
, jobs
… they are not supposed to change how programs work
by default. When I call ls
I expect to run the program. When I call kill
I
expect to run the program. I do not want your perks and a expecially do not want
your smart-ass coloring.
TAKE: fish sucks, why use it then? – because UNIX eco system sucks more. I’m not hyperthymestic, I can’t remember how those programs are parameterized – and they are not defined in a conventional manner! I fucking need the completion and tooltips, period.
-
https://wiki.archlinux.org/title/Command-line_shell#POSIX_compliant ↩︎
-
this depends on the compilation flag.
-DSYS_BASHRC
or-DSYS_BASH_LOGOUT
. This is per-distro. ↩︎ ↩︎