Fish Shell Series
- Good, So So, Bad about Fish Shell
- DRY(Do not Repeat Yourself) in fish
Credit or More Articles
- Nicolas Vanhorenâs Blog Nice introduction to fish shell programming
- Cover Image https://pixabay.com/photos/seashell-shell-shells-sea-ocean-2821388/
Fish is another shell
Iâm too lazy to change my shell. I used to use only bash shell back until 2009?.
I heard about tcsh
and ksh
at that time, but bash was kind of a new standard in
linux world.
Maybe zsh
rules the shell-world for now, there is another competitor called fish.
I didnât research about fish shell.
However, one thing I really like about fish shell is that fish shell has nice default settings out of box.
Sometimes, even if I installed new fish shell in a new box. I have no problem with using fish shell.
Iâm missing some bash history substitution like though:
bash> echo 123
bassh> ^123^456
echo 456
456
bash>
When I found those tricks in a book, I felt like I found some treasure in history. there were more (!$, !!) but I have forgotten many đ. Frankly, I donât miss those these days, but I can not deny it is nostalsic.
How About Script in fish?
I heard that fish is not good for making script. But this is not right expression. However, IMHO, bash or dash or zsh? is still better choice for more featrues and portability.
If you think about performance.. I think we need to go for another script languages, for example, perl, ruby, python.. or maybe javascript?!? Perl is the king for portability, but in 2022, python or ruby is available across the unix or linux world, isnât it?
Good
It has a clean syntax (arguably)
#!/usr/bin/env fish
# find "*.md (or *.markdown)", "*.lhs", "*.org" and print out first 7 lines of
# of each file.
set -l limit_numof_files 5
set -l numof_files_printed 0
set -l interested_extensions 'md' 'markdown' 'lhs' 'org'
set interested_extensions \
(for e in $interested_extensions
echo ".$e"
end)
set -l extensions_regex '('(string join "|" $interested_extensions)')$'
for fn in *
if test $numof_files_printed -ge $limit_numof_files
break;
end
if test -f $fn -a \
(string match -q -r $extensions_regex $fn)
test
set numof_files_printed (math "$numof_files_printed + 1")
echo -e "$numof_files_printed: filename: $fn\n"
head -n 7 $fn
echo -e "\n"
end
end
fish shell seems to use plain texts in its syntax, command and control flow. It looks similar to python or ruby. This doesnât mean it look best but I doesnât look tricky or geeky at least.
But remember..
You Can Write FORTRAN in any Language.
(This kind of trend will change over and over again, IMHO. And one thing I found that is One day.. someone says he likes the curly brackets in the javascript, which gives him more balanced look. I was suprised because this preference is exactly opposite to what most of people think python has cleaner look than perl back in 200x.)
great default auto-completion
I donât really have complains about fishâs auto-completion and I donât think most of unix user never heard about auto-completion. I wouldnât go deep inside. but you can make your own completions if you want.
powerful builtin functions
- math, string are used in the prior example code, I found that it is very well
documented via man page or website, and also convenient.
For basic calculation, I normally open a terminal and type like below:
fish> math "500+29*50+12*20+210+21*5"
and this is even written in my fish history! So, naturally I could recall it later. (not forever though)
- string supports even regular expression! I forgot about sed, awk commands and
sometimes use the perl to compare the texts against the regex. But now I could finish in fish shell.
remarkable variable scopes
This has pros and cons. It is just because it has different concept. This is where we should read the document very carefully.
However UNIVERSAL variable scope is unique and convenient some times. when you are using several fish sessions and want to share some variable.
- set -U or âuniversal option causes the specified shell variable to be given a universal scope. If this option is supplied, the variable will be shared between all the current userâs fish instances on the current computer, and will be preserved across restarts of the shell.
But it is easy to make mistake. for example, input set -U somevar
in
your ~/.config/fish/config.fish
. and somevar
will be duplicated over and over again.
well organized directory structure
If you have a look into ~/.config/fish/
directory. you will notice that
there is a functions
directory which consists of functions you can use during
the session. It will be automatically loaded when you start a new shell or invoke
that function for the first time. (sometimes you need to reload the file by source
)
Those function in
~/.config/fish/functions/
are avaiable in you all the sessions.
fisher
github repository: https://github.com/jorgebucaran/fisher There might be another kind of programme like fisher out there. Nevertheless fisher is a great third-party tool to make your fish socialized into the internet and install useful themes or tools from the github repositories. I believe that this is quite essesntial concept thesedays.
So So
index starting from 1 not 0
This is a kind of joke đ , but right now I think this is inconveient for programmer. Because when a programmer is loosing his/her focus and tends to make a mistake when indexing as 0 is very common in programming world.
This is why I donât think it as better choice, rather I think this is bold movement.
command substitution not as powerful as bash
There is a traditional way to copy but reserve the file attributes. (access time, creation time, ownership, etc) like below:
bash> touch a b c
bash> mkdir dest
bash> tar cf - a b c | (cd dest; tar xvf -)
bash> (cd dest; ls -l)
-rw-r--r-- 1 myoungjin users 0 Apr 16 21:41 a
-rw-r--r-- 1 myoungjin users 0 Apr 16 21:41 b
-rw-r--r-- 1 myoungjin users 0 Apr 16 21:41 c
bash> ls -l a b c
-rw-r--r-- 1 myoungjin users 0 Apr 16 21:41 a
-rw-r--r-- 1 myoungjin users 0 Apr 16 21:41 b
-rw-r--r-- 1 myoungjin users 0 Apr 16 21:41 c
As you can see above, sometimes grouped command in bash very useful. But, AFAIK, fish cannot do this or prevent this kind of behaviour.
update 20th Apr 2022
To correct my mention above, Iâll show more example. It is not impossible but still I think it is not as intuitive as bash way.
This is a equivalent solution:
fish> tar cf - a b c | fish -c "cd dest; tar xvf -"
Or this is a another approach:
fish> tar cf - a b c | begin cd dest; tar xvf -; cd -; end
The difference between two codes is that the former code used sub-shell1 as bash had, the latter one was still in the same level of your current fish session.
In either way, I could tell bash has more intuitive syntax for sub-shells.
Bad
Unusual variable scope
Actually, this is very powerful concept in fish, however it is not very common,
In other words, it is confusing. This confusion occurs highly when you are dealing
about local scope variable which is created by set -l varname
.
local scope is very limited scope which is not even propagate into the a local scoped function(declared in your script). So if you want to make a function, we need to aware about how we deliver some values from local scoped variables.
function has option -S which âŚ
allows the function to access the variables of calling functions. Normally, any variables inside the function that have the same name as variables from the calling function are âshadowedâ âŚ
so basically we cannot get any value from parent local scoped variables without -S option. But I agree that it is safer and strict.
function -V option is
-V or âinherit-variable NAME
snapshots the value of the variable NAME and defines a local variable with that same name and value when the function is defined. This is similar to a closure in other languages like Python but a bit different. Note the word âsnapshotâ in the first sentence. If you change the value of the variable after defining the function, even if you do so in the same scope (typically another function) the new value will not be used by the function you just created using this option. See the function notify example below for how this might be used.
Very well.. this maybe so you might need to study before making a function or script in fish. Otherwise you will get headache because generally shell script doesnât consult you kindly about your typo or misconcept.
Oh, This shell makes too lazy (Bad??)
Nevertheless, fish is a great shell which I love to use everyday. And I lost chance
to use zsh
. This is not about mannerism. đ Just because of fish shell is enough for me.
Thank you for reading!
Footnotes
Bash Sub Shells: https://www.linuxjournal.com/content/bash-sub-shellsâŠď¸