12 Shell Scripts (Bash Scripts) for Productivity

Meet Gregory, a writer and the brains behind Face Dragons. He's the go-to guy for getting things done. Gregory's been living the digital nomad life in Asia for as long as anyone can remember, helping clients smash their goals. He writes on topics like software, personal knowledge management (PKM), and personal development. When he's not writing, you'll catch him at the local MMA gym, nose buried in a book, or just chilling with the family.

We love Free and Open Source software here at Face Dragons, and we love becoming more productivity and optimizing our workflows. So this is the article made in Heaven for us. In this post, you’ll find great shell script ideas you can use as inspiration or just take them and use them as they are. Check back for more shell scripts for productivity, as we will update this page regularly!

Or follow Face Dragons on Twitter so you’ll see the updates!

Shell scripting is a great way to automate frequent tasks or to add functionality to your system. These scripts are mostly written in bash but are mostly posix compliant (or can be with small tweaks.)

They have only been used on Linux systems with bash shell installed. If you’re using macOS or another shell, you may need to make some changes. There is no super complex coding here, so read the scripts, and you will be able to understand them.

Most of these scripts also make use of Suckless’s DMenu, so download that before trying them out!

Let’s jump straight in!

1. Custom-Made GTD App

FOSS task management

Never read Getting Things Done? Read my GTD Guide and level up your productivity instantly!

Years ago, I got inspired by David Allen’s never-used plans for his ultimate GTD app. The hand-drawn designs showed an application every GTDer has ever dreamed about – The perfect GTD App. Unfortunately, everyone has their own ideas of what that might be. And Allen’s design never came to fruition.

When I saw the design, I was using a todo.txt-based system utilizing plain text files and CLI applications that worked seamlessly with it in the Linux terminal.

Seeing David’s design made me realize that the perfect GTD app was possible for me – I just had to build it myself. After a little planning and a few nights of coding, I had a GTD app of my very own. Super fast, super minimal, completely integrated into my workflow, and with all the features I need.

Moreover, I built the whole thing with a single bash script. If you’re interested, you can find the write up about it here.

2. Capture Ideas Quickly

See the top line of the screenshot below for my minimalist capture tool.

One of the things I find helpful is an instant capture tool. I have one on my phone and one within my GTD app above, but I don’t want all my ideas going to my FOSS task management system. Topics for blogs are a good example.

I keep a list of blog ideas I occasionally draw from when I need something new to write about. These aren’t exactly tasks that I need to do. Instead, they’re a store of ideas, so I keep them separate. Like most things, however, if I don’t immediately write down my new idea, it disappears quicker than it came. I needed something instantaneous that wouldn’t get in the way.

So, I made this really simple script you could use for anything. It takes some input and then stores it in a file. Simple.


KW=$(echo "" | dmenu -p "Enter KW:")
VOL=$(echo "" | dmenu -p "Enter Volume:")
DIFF=$(echo "" | dmenu -p "Enter Difficulty:")
LOCATION=$(echo -e "FD\nLFW" | dmenu -l 3 -p "Site:")
echo "$LOCATION"
if [[ $LOCATION == "FD" ]]


3. A Script to Access Config Files

Again, the screenshot below shows my quick-to-open menu, and it only takes up the top line of the screen!

I think the idea for this came from DT at DistroTube.

It’s just a quick script to quickly give you access to your configuration files. Sure, you could just look through your .config directory, but as we all know, most of the important configs you actually want to edit aren’t there. Instead of getting frustrated, just add it to this list, and you’ll always be able to find it in a second or two. The script opens the config file in your favorite text editor, too, so it really does exactly what you need.


CHOICE=$(echo -e "dwm\ndmenu\ndwmblocks\nvim\nconky\nbashrc\nxinitrc" | dmenu)

if [[ $CHOICE == "dwm" ]]
	st -e "nvim ~/Software/dwm/config.h"

if [[ $CHOICE == "dmenu" ]]
	nvim ~/Software/dmenu/config.h

if [[ $CHOICE == "dwmblocks" ]]
	nvim ~/Software/dwmblocks/blocks.h

if [[ $CHOICE == "vim" ]]
	nvim ~/.config/nvim/vimrc

if [[ $CHOICE == "conky" ]]
	nvim ~/.conky/conky.conf

if [[ $CHOICE == "bashrc" ]]
	nvim ~/.bashrc

if [[ $CHOICE == "xinitrc" ]]
	nvim ~/.xinitrc 

if [[ $CHOICE == "ADD MORE HERE" ]]

4. Temporary Script

I’m sure I didn’t invent this idea, but I’ve never seen anyone else do it. I set a hotkey to run a script called temporary_script. Sometimes, you find that you need to take 30 screenshots of an x=300 y=500 rectangle in the middle of your screen or some other random task. All you have to do is copy the screenshot script into the temporary_script, and you can hit a hotkey to run it in as many times as you want.

Or maybe you have a few different versions of a script you want to test out and want them accessible with a hotkey. Paste them into this script, and you can instantly try them.

Anything you wish was already set to a hotkey can be with this idea.

5. Temporary Script Swapper

Of course, the temporary_script is nothing without a temporary script swapper!

This script lists all the scripts within your designated scripting directory and automatically pastes the one you choose into the temporary_script file. Using this script, you can change the content of your temporary_script instantly.


# Use dmenu to display a list of files in the ~/scripts folder and save the choice to a variable
file_choice=$(ls ~/scripts | dmenu -l 20)

# Overwrite the temp file with the contents of the user's chosen file
cat ~/scripts/$file_choice > ~/scripts/temporary_script

# Confirm the temp file was overwritten
notify-send "The temp file has been overwritten with the contents of $file_choice"

6. Run a Script Script

Yes, this is script inception, but it’s useful. When you have dozens of scripts in your scripting folder, it is sometimes annoying to find one you wrote ages ago that you just need to run real quick. This Dmenu script will list out all the scripts in your directory and run whichever one you select. Easy.


SCRIPT=$(ls ~/scripts/ | dmenu -l 20)


7. Reminders and Hotkeys

This is a script I run all the time. I have it bound to Alt F1.

The point of this script is to remind me of my hotkeys and what my various scripts do.

You know the scenario: you set a hotkey ages ago to play that awesome playlist you love or start your recording software or whatever, but you just can’t remember what it was. You could start guessing, but we all know that’s a bad idea. Alternatively, you could look through your config files, but that’s too time-consuming. So why not have a dedicated file with all your shortcuts, aliases, hotkeys, and explanations for scripts in one place? Make it accessible and instantly searchable – that’s what this script does.

After I hit Alt F1, Dmenu opens and shows me the hotkeys, etc, and if I type, it will show me exactly what I want to find.

Of course, to make it work, you need to create the plain text file “keys-bindings.” You can put anything in there you want; I put hotkeys reminders, less commonly used commands, and other random things I know I will forget.


cat ~/scripts/keys-bindings | dmenu -l 20

8. Web Clipper

Back when Evernote was cool, I did use it on a Windows machine; I even had it synced up to my iPhone 4! And I didn’t hate it.

One of the things I loved was the web clipper. I always found myself clipping pieces of web pages and saving them for later.

After I had stopped dual booting and decided to live permanently in Linux (circa 2012), I wanted to build a script that would do the same thing.

I wanted something that would:

  • Find the highlighted text in the web browser
  • Turn it into markdown with headings, etc
  • Save it into a file to be reviewed later

After revising the web clips, I created a second script that creates an atomic note (or Zettel) and integrates this new note into my FOSS second brain. You’ll need xclip for this script to work.


# Prompt the user for input using dmenu
user_input=$(echo "" | dmenu -p "Enter text:")

# Get the currently highlighted text

# Append the user input and highlighted text to the file "capture.md"
echo -e "$user_input\n\n$highlighted_text\n\n---\n\n" >> ~/DIRECTORY/capture.md

9. Workout Logs

This bash script will create a file for each day of the rest of the week (I have it set up to create files only for Monday-Friday, so if it’s Wednesday and I run it, it will create Wed-Fri.)

Within the files, the script adds the date as an H1 heading; it also adds a “Previous” and “Next” link in markdown to the day that comes before and after it.

This way, I can quickly navigate my workout logs to see how much I lifted last time with any markdown viewer.

I did experiment with using the script to add my workouts, too, but I found that I didn’t always want to do the workout it had set. Instead, I use Markor’s snippet feature, which lets me save workouts as a template and then import them immediately into the file this script created.


# Get the current date in DD-MM-YYYY format
current_date=$(date +"%Y-%m-%d")

# Get the day of the week (1-7, where 1 is Monday and 7 is Sunday)
day_of_week=$(date +"%u")

# Calculate the date of the next Friday
friday_date=$(date -d "next Friday" +"%Y-%m-%d")

# Loop through each day from the current day to the next Friday
for ((i = 0; i <= 5 - day_of_week; i++)); do
    # Calculate the date for the current day in the loop
    loop_date=$(date -d "$current_date + $i days" +"%Y-%m-%d")

    # Create a text file with the current date as the filename
	filename="$loop_date-$(date "+%A" -d "$loop_date").md"
    touch /LOCATION/"$filename"

    # Add markdown links for Prev and Next to the file
	prevdate=$(date -d "$loop_date -1 day" +"%Y-%m-%d")
	nextdate=$(date -d "$loop_date +1 day" +"%Y-%m-%d")
    if [ $(date "+%A" -d "$prevdate") = "Sunday" ]
            prevdate=$(date -d "$loop_date -3 day" +"%Y-%m-%d")
	if [ $(date "+%A" -d "$nextdate") = "Saturday" ]
			nextdate=$(date -d "$loop_date +3 day" +"%Y-%m-%d")
    echo "[Prev]("$prevdate"-$(date "+%A" -d "$prevdate"))" > /LOCATION/"$filename"
    echo "[Next]("$nextdate"-$(date "+%A" -d "$nextdate"))" >> /LOCATION/"$filename"
    echo "" >> /LOCATION/"$filename"
    echo "# $filename" >> /LOCATION/"$filename"
    echo "" >> /LOCATION/"$filename"

    # Display a message indicating the file creation
    echo "File '$filename' created with Prev and Next links."

10. Chapter and Verse

The Bible

Every Christian should use this nifty little script, which helps you find a Bible verse or section and loads it into your clipboard so you can paste it wherever you like.

I use it when I’m taking Bible notes or when I’m doing research into a specific area of my faith. Typing out four or five verses is a lot of work when this script can let me paste it out in a few seconds.

Again, I use Dmenu to let me make a selection of the Book, Chapter, and verses; then, the script calls a program called KJV, which contains the King James Version and finds the verses asked for. Finally, xclip is used to copy the verses into the clipboard.

An equivalent program to kjv is available for the vulgate, and I’m sure there are similar programs out there if you prefer a different translation.

cd ~/scripts/
BOOK=$(cat bbooks | dmenu -l 20)
CHAPTER=$(echo "" | dmenu -p "Chapter:")
VERSE=$(echo "" | dmenu -p "VERSE:")


kjv $QUERY | xclip -selection c

To create the “bbooks” file, use this command: (you may want to clean it up by removing the parentheses, I did.)

kjv -l >> bbooks

11. AQI Pollution Widget

I lived in China for many years, and so I always kept a close eye on the air pollution levels. When it was too high, we didn’t go out, instead, staying at home with the air purifier on.

I had an app on my phone for this, but I wanted something on my desktop, too. This little script was the solution. I set it up to be a taskbar widget that always displays the current AQI (Air quality index) where I am.

You’ll need your own API token, which you can find here; then, this one-line script will output the AQI at whichever location you select. (Search the site for locations near you.)

curl -si "https://api.waqi.info/search/?token=ENTERYOURTOKENHERE&keyword=ENTERLOCATIONHERE" | grep -o "aqi.:...." | grep -o "[^a-z:\"]*"

12. ScreenShots

I’m sure you already have a hotkey setup to take screen captures on your laptop or computer. But can you name them whatever you want on the fly? Can you set a timer, the location and other options like a selected area or custom resolution. That’s what this script will do.

It uses maim, os take a look at that too.


LOC=$(echo -e "/ADDLOCATION1/\n/ADDLOCATION2/" | dmenu -l 5)
PIC=$(echo -e "Selection\nFullscreen\nTimer" | dmenu -l 5)
PICNAME=$(echo "" | dmenu -p "Filename: ")

if [ -e ~/ADDLOCATION1OR2/$PICNAME.jpg ]
		PICNAME="${PICNAME}$(date +"%Y-%m-%d-%H-%M-%S")"

		if [[ $PIC == "Selection" ]]
				maim -s $LOC$PICNAME.jpg
		if [[ $PIC == "Fullscreen" ]]
				maim $LOC$PICNAME.jpg
		if [[ $PIC == "Timer" ]]
				maim -d 5 $LOC$PICNAME.jpg

notify-send " "