Overview
Teaching: 0 min Exercises: 40 minQuestions
Objectives
Let’s get you up to speed with dotfiles.
~
), we will learn how to version control and publish this folder in the next class.Set up a method to install your dotfiles quickly (and without manual effort) on a new machine. This can be as simple as a shell script that calls ln -s
for each file, or you could use a specialized utility. An example of a simple shell script would be:
#!/usr/bin/env sh
# Where is your dotfile folder and which dotfiles you want to install?
dir=~/dotfiles # dot files directory
olddir=~/dotfiles_old # backup dot files directory
files="bash_aliases bash_profile tmux.conf vimrc" # Example list of files you use to configure your tools, and you chose to be put in your dotfiles folder WITHOUT the . in front so they are no longer hidden
# Create a backup:
echo "Creating $olddir for backup of existing dotfiles in ~"
mkdir -p $olddir
echo "...done"
# change to the dotfiles directory
echo "Changing to the $dir directory"
cd $dir
echo "...done"
# Move existing files to backup folder and create symbolic links
for file in $files; do
echo "moving any existing dot files from ~ to $olddir"
mv ~/.$file ~/dotfiles_old/
echo "Creating symlink to $file in home directory."
ln -s $dir/$file ~/.$file
done
tmux
tutorial and then learn how to do some basic customizations following these steps..tmux.conf
dotfile should also be placed in your dotfiles folder.If you are using bash, you can place your aliases in .bashrc
file, or create a separate .bash_aliases
dotfile and source
the file in your .bashrc
workflow. With zsh
, your aliases are placed in .zshrc
.
Create an alias dc
that resolves to cd
for when you type it wrongly.
Run history | awk '{$1="";print substr($0,2)}' | sort | uniq -c | sort -n | tail -n 10
to get your top 10 most used commands and consider writing shorter aliases for them. Note: this works for Bash; if you’re using ZSH, use history 1 instead of just history. You don’t have to write one for all 10, but consider the most useful ones for you.
Read man ls
and write an ls
command that lists files in the following manner
A sample output would look like this
-rw-r--r-- 1 user group 1.1M Jan 14 09:53 baz
drwxr-xr-x 5 user group 160 Jan 14 09:53 .
-rw-r--r-- 1 user group 514 Jan 14 06:42 bar
-rw-r--r-- 1 user group 106M Jan 13 12:12 foo
drwx------+ 47 user group 1.5K Jan 12 18:08 ..
Write bash functions marco
and polo
that do the following. Whenever you execute marco
the current working directory should be saved in some manner, then when you execute polo
, no matter what directory you are in, polo
should cd
you back to the directory where you executed marco. For ease of debugging you can write the code in a file marco.sh
and (re)load the definitions to your shell by executing source marco.sh
(Hint: 2 functions in 2 separate files named marco.sh
and polo.sh
, one saves the destination, one changes directories to that destination).
Say you have a command that fails rarely. In order to debug it you need to capture its output but it can be time consuming to get a failure run. Write a bash script that runs the following script until it fails and captures its standard output and error streams to files and prints everything at the end. Bonus points if you can also report how many runs it took for the script to fail.
#!/usr/bin/env bash
n=$(( RANDOM % 100 ))
if [[ n -eq 42 ]]; then
echo "Something went wrong"
>&2 echo "The error was using magic numbers"
exit 1
fi
echo "Everything went according to plan"
Use man
or tldr
to learn about pgrep
and pkill
. We may be used to using jobs
, htop
, or ps aux | grep
commands to view processes or get job pids and then kill them. But there’s a better way to do it. Start a sleep 10000
job in a terminal, background it with Ctrl-Z
and continue its execution with bg
. Now use pgrep
to find its pid and pkill
to kill it without ever typing the pid itself. (Hint: use the -af
flags, don’t overcomplicate things, no need to pipe or connect the 2 commands, simply show the command usage)
Say you don’t want to start a process until another completes, how you would go about it? In this exercise our limiting process will always be sleep 60 &
. One way to achieve this is to use the wait
command. Try launching the sleep command and having an ls
wait until the background process finishes (No need for &&
or if
statements here, check the shell scripting section of the notes on how to use both wait
and ls
on one line).
However, The wait
strategy will fail if we start in a different bash session, since wait
only works for child processes. One feature we did not discuss in the notes is that the kill
command’s exit status will be zero on success and nonzero otherwise. kill -0
does not send a signal but will give a nonzero exit status if the process does not exist. Write a bash function called pidwait
that takes a pid as an input argument and waits until the given process completes. You should simply use sleep
as your limiting process to avoid wasting CPU unnecessarily (Hint: while our sleep 60 is ongoing, do nothing, once it finishes, do ls
).
Key Points