DEV Community


Shell scripts are awesome

dechamp profile image DeChamp Updated on ・3 min read

(big thanks for Ben Sinclair's comment to help correct some things.)

I love using command line, it something about it's simplicity and power.

I just wanted to give a quick idea out there, to help speed up your day. I also hope you'll add any of your fun and helpful tools!

So here are my favs.

Aliases are super useful and I have a bunch. If you want them, message me. If i get enough response I'll make a post about it. But this is more focussed on functions and module combination to do some neat stuff.

First off, this post started because just now i was like "why am i retyping this every time!" and I wrote a quick function in 10 seconds, and realized I should share this!

So at work we do git forks, and then we branch per story.

I personally call the origin/master "upstream" and my fork of it by name name.

Each time I start a new story I have to run the following commands.

git fetch upstream
git checkout -b STORY_NUMBER_WITH_BRIED_DESC upstream/master
git pull upstream master // repetitive but for some reason fetch doesn't always update for me

So I type that literally every time I start a new story. It's a lot to type especially when you have more than 1 services that will be involved.

So this little function in my ~/.zshrc file (you may be using .bash_profile) make it easier!

newStory() {
    git fetch upstream && git checkout -b $1 upstream/master && git pull upstream master;

to use it, just make sure to source you new changes source ~/.zshrc and now I just type

newStory B-23168_automated_testing

There are many other one off shell script functions I use. I have a hard time remembering how to spell words. So I have a spl command which behind the scenes will run the aspell module. Which you can install via brew.

spl () {
    aspell -a <<< "$1"

Now I run my new command and it'll give me back what it thinks I mean. The first 1 or 2 words are almost always the one you meant.

spl polymorfus

> & polymorfus 3 0: polymorphous, polymers, polymer's

Maybe you wanna create your own function that call a custom script to do more than you know how to do in bash. Maybe PHP is your best language and you suck as bash other than the basics?

No problem!

Add your php shell script. Simple as using #!/path/to/php and then your php script. You can get your paths by using which php

~/.settings/snippets/urldecode (no extension)


echo urldecode($argv[1]);

now add your snippets folder export to the end of the ~/.zshrc file. This will make any script in this folder available to the command line! (thanks Ben for the better solution)

export PATH=$HOME/.settings/snippets:$PATH

and boom💥 you have a new script of your own making!

urldecode this%20is%20my%20string%21%20

> this is my string! %

So as you can see, you can do a lot with bash. It's awesome! I've dumped a few more below that you might wanna use. If you see it using another function name, you will probably need to brew install or npm install it.

# take every file and move it to the current folder
# with in parent folder you want, run flattenSubfolders
flattenSubfolders () {
    find . -type f -exec mv -n -- {} . \;

# used after you use flattenSubfolders to remove empty subfolders
# with in parent folder you want, run removeEmptySubdirs
removeEmptySubdirs () {
    find . -depth -mindepth 1 -type d -empty -exec rmdir {} \;

# will open chrome and turn your in to a nice web view, requires 
# rmd ./
rmd () {
    grip -b $1 &
    sleep 10
    kill $TASK_PID

# video helpers 
# genWebMp4 ./movie.ext ./newmovie.mp4
genWebMp4 () {
    ffmpeg -i $1 -vcodec h264 -acodec aac -strict -2 $2

# genWebm ./movie.ext ./newmovie.webm
genWebm () {
    ffmpeg -i $1 -c:v libvpx-vp9 -b:v 2M -pass 1 -c:a libopus -f webm /dev/null && \
        ffmpeg -i $1 -c:v libvpx-vp9 -b:v 2M -pass 2 -c:a libopus $2

# wavToMp3 ./file
wavToMp3() {
    ffmpeg -i $1.wav -codec:a libmp3lame -qscale:a 2 $1.mp3

# with in folder of all mp3s, run mp3ToOgg
mp3ToOgg() {
    for file in *.mp3
        do ffmpeg -i "${file}" "${file/%mp3/ogg}"

# genVideoThumb ./video.ext ./thumbnail.ext
# you can use jpg and png for thumbnail ext
genVideoThumb () {
    ffmpeg -ss 00:00:01  -i $1 -vframes 1 -q:v 2 $2

# spl word
spl () {
    aspell -a <<< "$1"

# gitCleanBranches
gitCleanBranches() {
    git branch --merged | egrep -v "(^\*|master|develop)" | xargs git branch -d

Hope you liked it. See an issue? Let me know.

Please add yours in the comments!



Editor guide
moopet profile image
Ben Sinclair

I agree with you: shell scripts are awesome.

I'm calling them that though because you refer to "bash scripts" you're using in zsh. They type of script is defined by the shell that's running it (which is either the shell sourcing it with . or the shell its shebang tells it to execute).
I think that you're getting confused around the purpose of the shebang, because you talk about writing a PHP script with #!/usr/bin/php, which is great, it's fine, and as long as you make it executable (with `chmod +x ./urldecode') there's no reason to wrap it in a shell function. Instead of putting it into some "snippets" directory, put it in somewhere on your path... or better yet, add

export PATH=$HOME/settings/snippets:$PATH

to your shell config.
Then all your PHP snippets that are marked executable and have a valid shebang will work automatically.

This has the added benefit that you can use it in another shell script and know that as long as you include the full path it'll work. If you write an alias or a shell function, and then try to use it in another script, you'll see unexpected things happen depending on circumstances. For instance if you made a cron job that expected urldecode to be your shell function, there's a good chance it won't be available.

I'd also really recommend making your function or alias names consistent: removeEmptySubdirs, flattenSubfolders, genvideothumb, and wavToMp3 all have different capitalisation and abbreviations. I know it'll autocomplete for you, but it's extra cognitive load, and from personal experience... my brain gets full.

dechamp profile image
DeChamp Author

See this is what I love, you taught me so much! I knew that I only had a over all idea of what I was doing with "Shell" scripts. So thank you for clarifying all of that. I'm going to update my post with this great information!

Also I KNEW someone would all me on the casing ha ha. I was tempted to update it in the post but I got lazy.

ruslangonzalez profile image
Ruslán González

Nice comment!

richarddewit profile image
Richard de Wit

If you like using Bash functions, then you will like Sly, a CLI tool a la Make but utilizing plain Bash functions. It uses a Slyfile in which you define custom functions doing anything you put in them, that can be run by calling sly functionname

dechamp profile image
DeChamp Author

nice! Thank you for the suggestion!

attkinsonjakob profile image
Jakob Attkinson

I love your gitCleanBranches. I'm a very newbie when it comes to scripts, therefore I kinda miss the basic knowledge like how to create a script, save and run it with ease. Until I read your post, I didn't even know I didn't know this (Windows user).

I use the aforementioned commend at least once a week, but I run it manually. I'd love to start now by doing it the right way.

Thanks for sharing.

dechamp profile image
DeChamp Author

You're very welcomed. I am happy to hear it taught you something and is useful! When you get more in to it, feel free to stop back by and show us your new cool skills!

cescquintero profile image
Francisco Quintero 🇨🇴

In general, automating repetitive stuff is awesome and a way to free ourselves from the burden of them.

It's even more awesome when we create a script to simplify that repetitive thing.

I've done it a couple of times and your examples are inspiring. 👍🏾

dechamp profile image
DeChamp Author

Thank you Francisco, glad you liked it.