- How to set variables
- How to write for loops
- How to write if statements
- How to execute strings
- How to write functions
- How to use sed
- How to use xargs
- How to use cut to split strings
- How to calculate how long the script took to run
Learn how to write fish shell scripts by example.
How to set variables
Here’s a simple example of assigning a value to a variable.
set MY_VAR "some value"
Here’s an example of appending values to a variable. By default fish variables are lists.
set MY_VAR $MY_VAR "another value"
This is how you can create lists.
set MY_LIST "value1" "value2" "value3"
Here’s an example of storing value returned from the execution of a command to a variable.
set OUR_VAR (math 1+2) set OUR_VAR (date +%s) set OUR_VAR (math $OUR_VAR / 60)
Since all fish variables are lists, you can access individual elements using
[n] operator, where
n=1 for the first element (not 0 index). Here’s an
example. And negative numbers access elements from the end.
set LIST one two three echo $LIST # one echo $LIST # two echo $LIST # three echo $LIST[-1] # This is the same element as above
You can also use ranges from the variable / list, continuing the example above.
set LIST one two three echo $LIST[1..2] # one two echo $LIST[2..3] # two three echo $LIST[-1..2] # three two
How to write for loops
Since variables contain lists by default, it is very easy to iterate thru them. Here’s an example.
set FOLDERS bin set FOLDERS $FOLDERS .atom set FOLDERS $FOLDERS github for FOLDER in $FOLDERS echo "item: $FOLDER" end
How to write if statements
The key to writing if statements is using the
test command to evaluate some
expression to a boolean. This can be string comparisons or even testing the
existence of files and folders. Here are some examples.
String comparison in variable.
if test $hostname = "mymachine" echo "hostname is mymachine" end
Checking for file existence.
if test -e "somefile" echo "somefile exists" end
How to execute strings
The safest way to execute strings that are generated in the script is to use the following pattern.
echo "ls \ -la" | sh
This not only makes it easier to debug, but also avoids strange errors when
doing multi-line breaks using
How to write functions
A fish function is just a list of commands that may optionally take arguments. These arguments are just passed in as a list (since all variables in fish are lists).
Here’s an example.
function say_hi echo "Hi $argv" end say_hi say_hi everbody! say_hi you and you and you
How to use sed
This is useful for removing fragments of files that are not needed, especially
xargs is used to pipe the result of
Here’s an example that removes
./ from the start of each file that’s found.
echo "./.Android" | sed 's/.\///g'
Here’s a more complex example of using
set folder .Android* find ~ -maxdepth 1 -name $folder | sed 's/.\///g' | \ xargs -I % echo "cleaned up name: %"
How to use xargs
This is useful for piping the output of some commands as arguments for more commands.
Here’s a simple example:
ls | xargs echo "folders: ".
- Which produces this:
folders: idea-http-proxy-settings images tmp.
- Note how the arguments are concatenated in the output.
Here’s a slightly different example using
-I % which allows arguments to be
placed anywhere (not just at the end).
ls | xargs -I % echo "folder: %"
Which produces this output:
folder: idea-http-proxy-settings folder: images folder: tmp
Note how the arguments are each in a separate line.
How to use cut to split strings
Let’s say you have a string
"token1:token2" and you want to split the string
and only keep the first part of it. This can be done using the following cut
echo "token1:token2" | cut -d ':' -f 1
-d ':'- this splits the string by the
-f 1- this keeps the first field in the tokenized string
Here’s a real example of finding all the HTML files in
~/github/developerlife.com with the string
"fonts.googleapis" in it and then
opening them up in
cd ~/github/developerlife.com echo \ "find . -name '*html' | \ xargs grep fonts.googleapis | \ cut -d ':' -f 1 | \ xargs subl" \ | sh
How to calculate how long the script took to run
set START_TS (date +%s) # This is where your code would go. sleep 5 set END_TS (date +%s) set RUNTIME (math $END_TS - $START_TS) set RUNTIME (math $RUNTIME / 60) echo "⏲ Total runtime: $RUNTIME min ⏲"