If you are more of a minimalist, perhaps terminals are your thing. To allow you to use your terminal to its full potential, let's learn a bit about bash scripting.
The tutorial has been divided into 3 parts:
- aliases
- functions
- customization
Setting up
If you have macOS/Linux and use bash/zsh
, you're good to go.
Before proceeding, make sure to have a .bashrc
file present in your home directory. If not, you can create it by typing:
cd ~ && touch .bashrc
Aliases
These are quite simple. Just like abbreviations.
What if you want to go up a directory? cd ..
What if you want to commit your changes? git commit -m "this is long"
All these commands can be vastly shortened by using aliases. Let's look at a couple of examples.
Git aliases
What do we usually do after making some changes in a git repository?
git add .
git commit -m "long method"
How about reducing the above two steps to:
gc "short method"
It's quite simple, really. Add this line at the end of your .bashrc
file:
alias gc='git add . && git commit -m'
Note: Make sure to not put any spaces (' ') between the =
and the following/preceeding characters.
Now, open up a new terminal window, and try out your new tool.
You can probably figure out what everything means, here:
-
alias
is a keyword to define a new alias name -
&&
is used to execute multiple commands in succession
Now, you can have something like:
alias gp='git push'
alias gu='git pull'
alias gs='git status'
Well, you get the idea.
General aliases
How about remembering your most visited directories with simple names? Probably a folder where you store all your apps?
alias apps='cd ~/path/to/apps/folder'
Or perhaps managing your Python venv?
alias pyenv='python3 -m venv env'
alias startenv='source env/bin/activate'
alias pyget='pip3 install'
Want to go up a directory?
alias up='cd ..'
Always ls to show all the hidden files/directories as well?
alias ls='ls -ACF'
Go ahead and experiment!
Functions
Remember the up alias? What if you want to go up 5 directories? Well,
up
up
up
up
up
can get really tiring. That's where functions come in.
Let's start off with an easy function. I can't possibly count the number of times I've followed my cd
command with an ls
command. Time to automate it.
function cd() {
builtin cd "$@"
ls
}
It might look confusing at first, but not for long. The $
variable contains all the arguments provided to a function. Hence, $1
is the first argument, $2
is the second, and so forth. $@
converts to all the arguments that were passed to the function. Also, $#
returns the number of arguments provided. Well then, the pseudocode for the above:
function cd() {
cd into the argument provided
ls
}
And the builtin
? Well, that is just so that the function call doesn't produce an infinite recursion. Something like:
function abc() {
abc()
}
Try doing some cd
now!
up
Stepping up the game now, let's get back to the up
function. For now, add this to the end of your .bashrc
file:
function up() {
if [ $# -eq 0 ]; then
count=1
else
count="$1"
fi
i=0
while [ $i -lt $count ]; do
builtin cd '..'
i=$((i+1))
done
ls
}
Fire up a new terminal session, navigate to some directory, and try doing up 3
now. Interesting.
If you cannot make much sense of the code above, here's the pseudocode for you again:
function up() {
if number of arguments is 0
set count to 1
else
set count to the first argument
loop from 0 to count
go up 1 directory
ls
}
clone
How about cloning a git repository and navigating into it with a single command? Probably:
function gcl() {
git clone "$1"
repo_name=`echo "$1" | perl -nle 'm/([^\/]+(?=\.git))/; print $1'`
cd $repo_name
}
Try gcl https://github.com/akshansh2000/dotFiles.git
now!
Note: Make sure that a function/alias name doesn't override any other built-in commands, or you might end up having problems which are difficult to debug :P
git everything
Executing a git add
, git commit
, and git push
consecutively?
function gacp() {
git add .
git commit -m "$1"
git push
}
Again, sky is the limit. You might end up creating some really useful functions!
Customization (bash)
This is particularly for bash
users. zsh
has some really amazing themes, which you can check out here.
Terminals are sometimes known to be ugly. They don't have to stay that way, though. If you have never customized your terminal, it probably looks like this:
user@pc:~$
If you prefer minimalism, add this to your .bashrc
export PS1="> "
Your terminal prompt should be changed to:
>
Too minimalistic? No problem.
export PS1="\u in \w\n> "
which results in…
user in ~/Desktop
>
Let's add some colors to it.
txtcyn='\[\e[0;96m\]'
txtred='\[\e[31m\]'
txtyel='\[\e[0;33m\]'
txtwhi='\[\e[37m\]'
txtblu='\[\e[34m\]'
export PS1="\n${txtblu}\u ${txtwhi}in ${txtyel}\w ${txtwhi}at ${txtred}\$(date +'%T')\n${txtcyn}> ${txtwhi}"
A bit better, perhaps?
Let's go one step further. How about displaying the current branch if you're in a git repository? And adding some bent pipe symbols at the starting?
txtcyn='\[\e[0;96m\]'
txtred='\[\e[31m\]'
txtyel='\[\e[0;33m\]'
txtwhi='\[\e[37m\]'
txtblu='\[\e[34m\]'
bold=$(tput bold)
normal=$(tput sgr0)
function gitBranch() {
git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/'
}
export PS1="\n${txtyel}┌─⭘ ${bold}\u ${normal}${txtwhi}in ${txtcyn}\w ${txtwhi}at ${txtblu}\$(date +'%T') ${txtred}\$(gitBranch)\n${txtwhi}└─⭘ "
It'd look something like:
Well, there you have it. The basics of bash scripting.
All of my config files are available at https://github.com/akshansh2000/dotFiles, should you need them.
Happy reading!
Top comments (23)
Very nice! I'm not much of a shell-scripter and have always found it quite annoying to write them because I do it so rarely. I wrote one to bootstrap a new machine and that was fun (sarcasm). I do, however, love old Unix utilities like
awk
andsed
and would love to use them more for scripting and they're more portable and have less drift than writing Python or Ruby scripts.The functions are nice! I never quite found a good way to move up multiple directories and do it quite often, but I do it far less now as I rely more on
fzf
globbing. I think functions have far more utility than aliases as I only keep a handful around and heavily rely on my history -- shameless plug: my post about efficiency in the terminal/shellDo you have a link to your dotfiles or a repo with the functions that you use? Would love to check 'em out!
Hahaha, indeed, using the shell can sometimes be annoying. Moving up directories continuously is an example :P
I took a look at your post, and it's a great read!
reverse-i-search
is something I discovered quite late, and wished to have known about it sooner haha.Sure, I have my dotFiles hosted on GitHub. Though I'd suggest that you look at the
.zshrc
instead of.bashrc
, since I haven't updated the latter in quite a long time.Thanks for reading!
Yeap! It's such a rare occurrence for me nowadays, because I literally just keep all the projects that I operate in open with tmux with their sessions auto-saved. They're restored on restarts. Tmux was something that took me a super long time to adopt (start of this year).
Yeah, I feel like
reverse-i-search
is not mentioned enough. It's spectacular withfzf
integration: github.com/junegunn/fzf.Neat neat! I like that function you've got for git branch, current working directory, and more. You've even got some perl in there. LOL! Wow! Out of curiosity, how did you go about learning all that you know about shell-scripting?
Your
.zshrc
is so much cleaner LOL. You've even got functions to generate what appears to be checksums. You're probably the first person that I've seen with Dart-lang repos. I always like to ask C++ programmers about Rust -- have you tried it? Thoughts?Ahh, I've never used
tmux
, but heard a lot of praise! I've been usingi3wm
for quite a while, and so I just open multiple terminal windows and pretend it'stmux
haha. Anyway, I would surely give it a try, as the session-restoring sounds great (and time-saving)!Looking at
fzf
, do you also usevim/emacs
? I've never gotten around to using them, as I think that it'd take a lot of time to migrate from VSCode to a total keyboard experience, and so I keep postponing trying to learn the shortcuts :PHaha thanks, I use perl majorly for applying regex into bash strings (like extracting the directory name, CPU Temp, etc.)
I learned all that majorly from other awesome people's articles online, and sometimes through books (e.g. O'Reilly's Learning the bash Shell).
Ahh yes, the checksums function is quite useful. It generates the checksum, checks it against the one you provided as an argument, and returns if the two match. So, for md5 checking, I can simply do
So yes, I use it a lot :P
I majorly use Dart for mobile development i.e. Flutter. And Rust has been on my list for quite a while now, but never really got around to learning it. From what I've heard, people just call it a better C++ (if that's possible :P). I think I might start soon. Are you planning on learning it, too?
Yeah, I guess tmux is certainly more for a terminal-based workflow. I can't live without it. Switching windows is all keyboard shortcuts. I figure that i3wm is, too? I'm on macOS, and spent the last two hours looking at Yabai, a super popular tiling window manager for macOS
Yeap! You nailed it. I'm a total Vim-nut, but it's partially because I don't do any sort of dev in ecosystems that have amazing IDEs, like Java, iOS, etc. I try to keep a mouse-less workflow which comes in handy when having only a laptop (before the pandemic began). With regard to fzf, just navigating a filesystem is so much nicer. I use the globbing a lot!
My reverse-i-search becomes this w/ fzf (instead of the standard one-liner):
Yeah, your checksum functions are friggen neat! I've saved them :)
Haha -- so I've never really done too much systems programming and reading C++ is pretty straight-forward to me (at least in relation to Leetcode problems). Well, the problem with C++ is the footguns with memory. Right? I think it was only last year or the year before that Google reported two zero-days in Chrome. A large organization with as many resources as they have, has made a valiant effort, but it is still a problem. And it seems like the bulk of CVEs are memory-related. I currently do a little bit of Go which is useful but I really don't like its lack of elegance, though simple, and maintainable. I like modern language facilities and constructs and tooling, vibrant community, but without the memory footguns of C++, which Rust seems to provide (which is also being used on my team at my current company). I plan on learning it, because I'd like to have a performant systems language in my toolbox
Yep,
i3wm
is also all-keyboard workflow. Honestly, I didn't even know how much time I spent alt+tabbing and moving between windows using my mouse until I started usingi3wm
. I guess I'd have a similar experience once I switch from VSCode to vim :PI've heard about Yabai. Probably somewhere in unixporn (SFW), people have some amazing rices there.
Ahh yess, not using a mouse certainly helps with a laptop. Out of curiosity, which laptop do you use? I particularly love MacBook's touchpads (sometimes preferable over a mouse for me).
Wow, your
reverse-i-search
looks beautiful. Comparing to the one-liner I get hahaha, I'd perhaps try outfzf
soon.I literally just Googled "zero-days" right now :P
Yes, the main problems lie in memory management and garbage collection of C++ (which I believe Rust improves upon?)
The lack of generics in Go really annoyed me, although (finally) they're coming in the next version, so it might be a really interesting time to improve our GoLang skills.
Again, out of curiosity, how long have you been working with C++?
VSCode is so hard to switch from. I watch a lot of tech YouTubers and I'm like, "Wow! WTF! It's like a full-blown IDE!" I used to use SublimeText with its vim plugin before doing a complete switch after being comfortable with the keys and this was before there were so many super video tutorials from YouTubers, like The Primeagen's troll video before he created a six-part series on some basic and intermediate Vim: youtube.com/watch?v=1UXHsCT18wE. I hear that the vim plugin for VSC is pretty good, though!
LOL! I think you've just sold me on a tiling window manager. I'll probably install Yabai tomorrow if it's a light work day. I was not aware of that sub-Reddit either! Just joined. LOL.
I only have Macs -- my personal machine is a 2019 MacBook Air, but I started a new job in April and was provided a 15" MacBook Pro (late 2019). Yeah, the touchpad is nice, but still requires me to move off my keyboard. I even surf the web with Vim keybinding using the Vimium plugin in both Chrome and Firefox. I also have the keyboard shortcuts turned on in Gmail (which are also Vim keybinding). Vim-nut, I tell ya!
Here's a quick five minute video on the capabilities of
fzf
: youtube.com/watch?v=1a5NiMhqAR0. It is one of the most starred projects on GitHub for a reason and the Vim integration is phenomenal.This was the Hacker News article discussion and article that was heavily upvoted a year ago - Serious Chrome zero-day. You'll see people ranting about the C++ right at the outset. Yeah, Rust has a very very strict compiler and introduces the "ownership" model along with semantics around it, dubbed "borrow-checking". The quality of the software, at least in open-source, in that community is pretty phenomenal. A few tools that I use are Rust-based now -- like my terminal emulator, Alacritty (perceptibly faster than iTerm2) and cross-platform (macOS and multiple Linux distros),
ripgrep
for searches (faster thanag
and most certainly,grep
).Yeah, I saw a demo of generics in Go in the Golang sub-Reddit. I'm totally fine with or without it, because I don't envision writing more Go than I need to. It would be a welcome addition and reduce the SLOC in a big organization. However, I would much prefer to learn and work in Rust, as I find the language much more expressive (modern language features) even though there's a steep steep learning curve. My current company uses Go, but finds it difficult to get observability and runtime introspection without going whole hog into Google land with K8s and containers to layer over it.
Haha, funny that you ask. I've probably written no more than two programs in C++ (a small game and calculator). I've done some Leetcode problems in C++ and have read some C++ source code in open-source projects, but my entire career has been in the web-stack which I'm getting bored of, so I want to drop down lower fueling my intrigue with Rust :)
VSCode is literally an IDE in the package size of a big text editor :P
Moreover, its extension support is one of the major reasons people (including me) can't let go of VSCode.
Ahh, this series is nice. Thanks for sharing! This is a great way of moving to vim. The only thing I did before trying vim was
vimtutor
, which is nice, but still a little overwhelming for first time use. It'll grow on me slowly, I guess :)Hahaha, so did you install Yabai? And yes, Macs are great. I just found out about the Vimium plugin and wow, you clearly do love vim :P
I use Gesturefy or CrxMouse to speed up my browsing, but that's about it. Gonna definitely try Vimium after learning vim haha.
Ahh, that definitely makes Rust something to try soon! Also, I saw Rust to be among the most loved languages on StackOverflow, so it definitely is a good sign for its future :)
I've been using
alacritty
for over 3 months now, and yes, it's really a no-nonsense and lightweight terminal. Moreover, I also use dmenu-rs which is a Rust-based dmenu, and functions just like the extremely amazing spotlight search of macOS.I tried Competitive Coding with Go once, just for fun really (majorly to see performance differences compared to C++). The speed was amazing, but the code writing part was definitely a headache xD
That was majorly due to generics. Now, since their introduction, maybe I'd try it once again. I'm just looking for substitutes for Python (for CP). Basically, I mostly use C++ during CP, but when the question relies heavily on hashmaps and lists, I prefer Python (mostly due to its ease-of-implementation and O(1) key searching). However, Python sometimes exceeds the time limit due to being really, really slow. So, if GoLang can solve that for me, I'd happily use it.
Ohh, I really thought that you were into systems programming with C++ haha. That's nice. I'm just diving into kernel development now, so C/C++ are gonna be with me for a long time now :)
The "Two steps from VSCode to Vim" video, I'm literally laughing hahahah. Took me quite a while to understand the satire :P
This was a great video; thanks for sharing :D
Enjoy! I've left a lot of questions and comments on those videos. Haha. He's pretty entertaining. I mean, Vi key-bindings are everywhere! Navigating man-pages and tons other Unix utils... I can't be the only one. Vimium really doesn't take much to learn aside from the movement keys hjkl,
gg
(top of page),<shift>-g
(bottom of page), thenf
and it marks anything that's a link with a letter or a sequence of keys to press to visit the link or open the link in new tab/window. This trips me up each time I'm on someone else's machine. Gesturefy is neat! I didn't even know about this. I do love Firefox containers and tree-style tab plugins, though!Oh! I was not familiar with dmenu, but that is pretty neat! I may give it a whirl -- so many things to try. LOL.
Didn't end up installing Yabai -- was chatting w/ a coworker using it and he's like, yeah -- you gotta configure the keys first and I'm like, "okay, guess I'll wait!" I end up installing Rust instead and reading the book 🤷♂️ #priorities
Yah! Rust has been atop or near the top of that list for the last two or three years. It's got a lot of traction in the San Francisco Bay Area tech scene.
I always admire folks that do competitive programming. I follow quite a few on YouTube that you may be familiar with Erichto, William Lin, and Rachit Jain. Does Go's standard library have the data structures that you need for most problems? And did you find problems where you could use goroutines? C++ is pretty much the only language that I see used in CP, but of course, back in the day, there was Pascal. How often do you reach for heaps?
I've never really used any of the other Python VMs, but I can't even imagine someone using Python for CP. It's the language I typically end up using for interviews, but it's not like my solution is being compared one implemented in another language -- just need to be able to bring down the algo complexities (not always easy for a non-competitive programmer)
Haha -- people at work ask me why, too. Just curiosity and the possibility of working on some hardware that I had no interest in years ago. I think reading about Discord's use of Elixir and Go, then switching from Go to Rust here, really sparked my interest. I also had a coworker at a previous company that was a huge Rust open source contributor before it was popular -- he wrote a bunch of device drivers and software for cameras and lights around his house and I found that really cool. It wasn't something I could particularly do.
So I ended up installing the Vimium extension, and, wow. I love it. You were right; it didn't take much time to get used to, but saves a whole lot of effort while browsing. Thanks for this!
Firefox's containers are indeed great. I never really used the tree style tabs, though, as I think I'd need a bigger screen (I pretty much always feel that my screen isn't big enough haha) and so I think I might try that later.
Hahaha, yes,
Yabai
,i3wm
,dwm
, and perhaps almost every tiling WM takes a lot of time setting up + getting used to. They do save a lot later, though. So, a worthy investment, I'd say.You've sold me for Rust, really. Gotta start learning soon :P
I haven't heard about Erichto, but yes, William Lin and Rachit Jain are amazing. Go's standard library contains lists (obviously), trees, heaps, stacks and queues (easily implemented using slices), and some useful functions. It isn't as extensive as the C++ STL, but it still does a really good job.
About the goroutines, I never came around to using them, as I didn't even know that much programming when I used Go (I was in my freshman year :P)
Haha yes, Python for CP is usually frowned upon. Honestly, I figured that in competitions where the submission time matters (i.e. the time one took to solve the problem, and not the submission runtime), Python is really good!
When I became used to Python, I realized that I could sometimes solve a problem using Python in half the time it took to solve the same in C++. So, what I usually do is use Python for easy problems (so that I don't fall into TLE problems), and switch to C++ for the harder ones. I found this way to be really efficient! Moreover, when dealing with really large numbers, Python works like a charm.
Woah, Discord switching from Go to Rust is a really interesting step! Let's see how it fares in the future :D
Your
cd
function could be greatly simplified:cd
with no arguments already goes to the home folder."$@"
passes all arguments passed to the function exactly as they were passed. If there were none passed, it passes nothing.Ahh, this looks great. It was a simple solution, really (should've been obvious to me). Perhaps, I spent a little too time thinking :P
Made the changes. Thanks!
Nice post!
A few small improvements ;)
Thanks for the suggestions!
Yes, I believe putting the aliases and functions in a separate file would immensely clean up the rc files, so I'd be careful to do that from now.
As for the gcc, this never occurred to me as I never really used gcc apart from compiling cpp files with g++. Perhaps, I should add a little note in my post telling others to make sure that the aliases/functions do not try to override any other command :)
Ahh, I'll definitely read up about it; thanks for pointing this out :D
Using
gcc
for a function name is not a wise idea. Especially when you cope with C language. ;)Thanks for the insight!
I realised this quite late 😅
I'll perhaps add a note in my post telling users to make sure not to name functions/aliases such that they override other commands :)
Nice writeup 🔥
Although a small suggestion
If you meant
git add
all the changes, than you should update it togit add -A
git add .
will only stage changes in current directory, might get confusing if you run this in sub-directories.Ahh yes, quite rightly pointed out. I'll update it in the post as well.
Thanks for reading!
Don't use
git add .
, usegit add --all
insteadTry
basename
.I often use ctrl+r for history fuzzy search. alt+f to go forward a word, alt+b to go backward a word, etc. I recommend looking into readline's default bindings.
I'd surely do so. Thanks :)
Git commit multiple files:
git commit -am "Commit message"