# How to create a function in a Bash shell script

> Learn how to create and call a function in a Bash shell script to avoid repeating commands, plus how to loop over an array of folders to run it on each.

Author: [Flavio Copes](https://flaviocopes.com/about/) | Published: 2022-05-05 | Topics: [CLI](https://flaviocopes.com/tags/cli/) | Canonical: https://flaviocopes.com/shell-script-function/

I was writing a [shell script](https://flaviocopes.com/bash-scripting/) to automate things in my workflow to publish books.

I was doing things manually and generally I'm so lazy I could repeat things over and over again before automating but today I had to do a very repetitive task and I wanted to do things right so I just decided to write a script to help me and future me.

So I wrote a shell script that was going into different folders and had to call 3 times [`npx`](https://flaviocopes.com/npx/) do do something, like this:

```bash
#!/bin/sh

cd c-handbook

npx honkit pdf ./ ../books/$(basename $PWD).pdf
npx honkit epub ./ ../books/$(basename $PWD).epub
npx honkit mobi ./ ../books/$(basename $PWD).mobi

cd ..

# and repeat this endlessly

cd css-handbook 

npx honkit pdf ./ ../books/$(basename $PWD).pdf
npx honkit epub ./ ../books/$(basename $PWD).epub
npx honkit mobi ./ ../books/$(basename $PWD).mobi

cd ..
```

The part that `npx` is doing is all the same. 

So I wrapped all the `npx` calls into a function and I called that function instead, like this:

```bash
#!/bin/sh

generate_book () {
  npx honkit pdf ./ ../books/$(basename $PWD).pdf
  npx honkit epub ./ ../books/$(basename $PWD).epub
  npx honkit mobi ./ ../books/$(basename $PWD).mobi
}

cd c-handbook
generate_book
cd ..

cd css-handbook 
generate_book
cd ..

# ...and so on
```

Then while I was there I also decided to create an array for all the book folders:

```sh
books=( "c-handbook" "css-handbook" "deno-handbook" "es5-to-next" "express-handbook" "html-handbook" "javascript-beginner-handbook" "linux-commands-handbook" "nextjs-handbook" "node-handbook" "python-handbook" "react-beginner-handbook" "svelte-handbook" "vue-handbook"  )
```

and to iterate over this array using a loop:

```sh
for i in "${books[@]}"
do
   : 
   echo $i
   cd $i
   generate_book
   cd ..
done
```

Final version:

```sh
#!/bin/sh

books=( "c-handbook" "css-handbook" "deno-handbook" "es5-to-next" "express-handbook" "html-handbook" "javascript-beginner-handbook" "linux-commands-handbook" "nextjs-handbook" "node-handbook" "python-handbook" "react-beginner-handbook" "svelte-handbook" "vue-handbook"  )

generate_book () {
  npx honkit pdf ./ ../books/$(basename $PWD).pdf
  npx honkit epub ./ ../books/$(basename $PWD).epub
  npx honkit mobi ./ ../books/$(basename $PWD).mobi
}

for i in "${books[@]}"
do
   : 
   echo $i
   cd $i
   generate_book
   cd ..
done
```
