Terminal Takeaway πŸ₯‘

chafa animated GIF example:

chafa https://media.giphy.com/media/f63ra8KYIvWGA/giphy.gif


Similar to the next one, this is a GIF of a GIF so expect smoother results.

Cooked up some chafa sprite animation instructions:

# Sprites source: https://www.gameart2d.com/free-dino-sprites.html

wget https://www.gameart2d.com/uploads/3/0/9/1/30917885/freedinosprite.zip
unzip freedinosprite.zip
cd ./png
nano run.sh
# Paste the following:

while true; do
	chafa --clear -size 50 "Walk ($((i++))).png"
	if [ $i = 11 ]; then i=1; fi
	sleep 0.05

# Save
chmod +x ./run.sh
# Hold down Ctrl+C to stop

Peek 2020-12-22 00-35


Tip of the week: Notice my bad practice above --^

Train yourself to use chmod u+x instead of chmod +x

chmod +x grants executable rights system wide, chmod u+x just grants rights to the file’s owner which is usually all you want.

Try it yourself:

# Create files named A, B and C in the current directory
touch ./A ./B ./C

# Observe the initial file rights
ls -la ./A ./B ./C

# Give everyone executable access to A (same as chmod a+x)
chmod +x ./A

# Give just the owner executable access to B
chmod u+x ./B

# Give just the owner and group executable access to C
chmod ug+x ./C

# Observe the new rights
ls -la ./A ./B ./C

# Cleanup
rm ./A ./B ./C

Security Bonus:

Don’t give executable rights to files at all and just run them directly. Examples:
bash ./MY_FILE
sh ./MY_FILE


Add these to your bashrc and thank me later

#Shell Options
shopt -s autocd # change to named directory
shopt -s cdspell # autocorrects cd misspellings
shopt -s cmdhist # save multi-line commands in history as single line
shopt -s dotglob
shopt -s histappend # do not overwrite history
shopt -s expand_aliases # expand aliases
shopt -s checkwinsize # checks term size when bash regains control
bind "set completion-ignore-case on"

# Custom Alias

# easy resource
alias resource="source ~/.bashrc"

# Easy Open
alias open="xdg-open"

# IP colors
alias ip='ip -br -c'

alias tb='nc termbin.com 9999'
alias termbin=tb


ip has colors and a tabular mode… whhhhattttttt

.bashrc lsusers()

Credit to terminalforlife, arguably THE most underrated terminal focused show on YouTube.

Lots of .bashrc goodies here:

BashConfig/.bash_functions at master Β· terminalforlife/BashConfig Β· GitHub

Highlighting a really nice one, this’ll list all the users on the system (from /etc/passwd) in a human readable table.

nano ~/.bashrc
# Paste the following somewhere within:
# lsusers() Repo: https://github.com/terminalforlife/BashConfig/blob/master/source/.bash_functions
# lsusers() License: https://github.com/terminalforlife/BashConfig/blob/master/LICENSE
lsusers(){ #: List users on the system, according to '/etc/passwd'.
	printf "%-20s %-7s %-7s %-25s %s\n" "USERNAME" "UID" "GID" "HOME" "SHELL"

	local X
	while IFS=':' read -a X; do
		if [ "$1" == "--nosys" ]; then
			# It's possible some users might show up if they mistakenly
			# were given a HOME, but '--nosys' should otherwise work.
			if [[ ${X[5]/\/home\/syslog} == /home/* ]]; then
				printf "%-20s %-7d %-7d %-25s %s\n"\
					"${X[0]}" "${X[2]}" "${X[3]}"\
					"${X[5]}" "${X[6]}"
			printf "%-20s %-7d %-7d %-25s %s\n" "${X[0]}"\
				"${X[2]}" "${X[3]}" "${X[5]}" "${X[6]}"
	done < /etc/passwd


1 Like

Exitting VIM

A 2017 study including over 1,000,000 developers found jQuery devs were the most likely to get stuck in VIM:

Know your way out!

  • Pressing Escape won’t allow you to β€œescape” VIM but it will get you back to Normal mode.
  • From Normal mode you can enter Command mode by pressing :
  • Now you can enter a command to exit VIM, then press enter (to exit).


  • :q #Quit
  • :q! #Rage quit (quit and discard changes)
  • :wq #Save and quit
  • :x #Also Save and quit
  • :qa #Quit all open files
  • :qa! #Rage quit all open files

Exit directly from Normal mode:

  • Esc + Shift ZZ #Save and quit
  • Esc + Shift ZQ #Rage quit

Remote recovery: (if all else fails)

  • SSH into the machine and run: pkill vim

:w !sudo tee %

I always need to save when I forget to sudo.


Sweet! Thanks. I use that one a lot. :slightly_smiling_face:

If you want to know how many packages are installed on your Debian based system without using something like neofetch or screenfetch:

dpkg -l | wc -l


One thing I really miss from Debian in Fedora is apt search tells you which packages you already have installed.

dnf list installed


It’s hard to describe exactly why I like seeing which packages are installed when I go package hunting. In part it’s because i’m always jumping through VMs and I can lose track of what’s on there. :stuck_out_tongue:

There could be a wrapper that pulls dnf list installed, matches it to dnf search and appends [Installed] to matching package lines.

There is also dnf info in Fedora. It works similar like apt policy. So at least you can see if is installed or not.

1 Like

If you want to know who you are because you forgot:


And because it is Terminal Tuesday you should look up:


1 Like

Call me immature, but when terminal output has tasteful, non-kitschy colors, I enjoy my CLI experience like 10x better. I think any and all commands (perhaps to be made into .bashrc aliases) which colorize the output are big wins, to share around.

For example, I really like glances, instead of htop now (thanks, @Mr_McBride). Even though glances takes a lot more RAM, its use of color is much more tasteful, IMHO. I hope 2021 is a year of tasteful colorization of lots and lots of common CLI utilities in Linux.


+1 for glances

add nethogs to that.


How to use multi-dimensional associative arrays in BASH

As promised, a solution in < 10 lines. Using grep with PCRE RegEx.

Introducing BAAM - [B]ASH [A]ssociative [A]rrarys in [M]ulti-dimensions

BAAM (){ # BAAM - [B]ASH [A]ssociative [A]rrarys in [M]ulti-dimensions
	for PROP_NAME in "${@:3}"; do
	echo $(echo "$1" | grep -oPe "$REGEX_STR")

Example of use:

#!/usr/bin/env bash

# BAAM uses BAAML, a TAB deliminated multidimensional markup

# Option 1. Inline: Pass arbitrary text containing BAAML markup into a variable
{ MY_DATA=$(</dev/stdin); } <<\EOF
			address:Rocket Road
		founder:Elon Musk

# Option 2. Load: cat BAAML markup into a variable
# MY_DATA="`cat ./my_baaml.txt`"

MY_DATA=${MY_DATA//$'\n'/} # Remove newlines so grep can search it in one go

# Define search function
BAAM (){ # BAAM - [B]ASH [A]ssociative [A]rrarys in [M]ulti-dimensions
	for PROP_NAME in "${@:3}"; do
	echo $(echo "$1" | grep -oPe "$REGEX_STR")

# Call BAAM wtih MY_DATA and each array property to reach the desired value
echo $(BAAM "$MY_DATA" SpaceX links website)

#Output: https://www.spacex.com/

If you’d like to see the process of me creating BAAM and BAAML:

Best way to simulate multidimensional arrays "objects" in BASH? - #27 by Ulfnic

This is ground floor for the project and I intend to take it a lot further. Time allowing i’ll be adding lots of features, documentation and testing.


Great post seen on Element.

Deep dive into BASH pitfalls.


1 Like

What would you like for next Terminal Tuesday?

  • Self-hosted terminal chatroom in < 20 lines using BASH and NGINX.
  • Self-host your own GeoIP lookup without using a 3rd-party service.
  • Improvements and/or new features added to BAAM.
  • Tracking down what’s using up space the fun way and the not-so-fun way.
  • Hosting a public API that allows anyone to run arbitrary code in several languages with heavy sandboxing.
  • Giving Internet to your Android using ADB over USB.

0 voters

Votes should be ranked or multiple choice in future. :confused:

For the coin flip: When DL is published, the 1st letter of the first word used at/after the 5 minute mark will decide which one I do. A to M = chatroom, N to Z = GeoIP