I often need to quickly create a Python virtual environment to try out ideas. Normally, I create a temporary directory, create a virtual environment, then install the required packages. While these steps do not take long to finish, it helps to streamline the steps.
Continue readingCategory Archives: bash
Detect OS and Distro in Bash
In my daily work, I often need to know which operating system (OS) or Linux distribution (distro) I am in to customize my bash script. Here is how I detect the OS and distro.
Continue readingSynchronize Directories in Bash Shell
The Problem
I often work in a Linux environment with multiple windows open in a tmux session. One of the pattern I see often is the need to navigate to the same directory for multiple windows. For example, in window 1, I navigated to a directory deep within my project:
$ cd ~/long/path/to/my/directory
Then, on window 2, I want to navigate to the same directory. This often involves either copy the command from window 1 and paste into window 2, or retype the same command again. There must be a better way.
Let the Mac Speak for Me
The Problem
I often lose my voice temporarily due to allergy. During that time, my main mode of communication is a notepad, or the electronic equivalent: Zen Brush. I was looking for a solution that can convert what I type into spoken words.
The Solution
Since I am using Mac both at home and at work, and Mac has the say command which is useful for this purpose; I decided to roll my own solution. It turned out that the solution is a very simple bash script, which I named speak4me.sh, which I saved in my ~/bin directory:
#!/bin/bash
while read line
do
say -v Alex $line
done
To make the script executable, I issued the following command:
$ chmod +x ~/bin/speak4me.sh
Using speak4me.sh
To use speak4me.sh, from the terminal, issue the following command:
$ speak4me.sh
After that, start typing your message. As soon as you hit the return key, the script will “say” what you type. You can keep on typing and hitting return. To end the script, just type Ctrl+C.
Discussion
The script is very simple, pragmatic and free from bells and whistles, but it works the way I like it. The -v Alex
part of the say command specifies a voice from Alex. OS X comes with a few voices which you can experiment with yourself. To list the voices your system has, issue the following command:
$ say -v ?
Agnes en_US # Isn't it nice to have a computer that will talk to you?
Albert en_US # I have a frog in my throat. No, I mean a real frog!
Alex en_US # Most people recognize me by my voice.
Bad News en_US # The light you see at the end of the tunnel is the headlamp of a fast approaching train.
Bahh en_US # Do not pull the wool over my eyes.
Bells en_US # Time flies when you are having fun.
Boing en_US # Spring has sprung, fall has fell, winter's here and it's colder than usual.
Bruce en_US # I sure like being inside this fancy computer
Bubbles en_US # Pull the plug! I'm drowning!
Cellos en_US # Doo da doo da dum dee dee doodly doo dum dum dum doo da doo da doo da doo da doo da doo da doo
Deranged en_US # I need to go on a really long vacation.
Fred en_US # I sure like being inside this fancy computer
Good News en_US # Congratulations you just won the sweepstakes and you don't have to pay income tax again.
Hysterical en_US # Please stop tickling me!
Junior en_US # My favorite food is pizza.
Kathy en_US # Isn't it nice to have a computer that will talk to you?
Pipe Organ en_US # We must rejoice in this morbid voice.
Princess en_US # When I grow up I'm going to be a scientist.
Ralph en_US # The sum of the squares of the legs of a right triangle is equal to the square of the hypotenuse.
Trinoids en_US # We cannot communicate with these carbon units.
Vicki en_US # Isn't it nice to have a computer that will talk to you?
Victoria en_US # Isn't it nice to have a computer that will talk to you?
Whisper en_US # Pssssst, hey you, Yeah you, Who do ya think I'm talking to, the mouse?
Zarvox en_US # That looks like a peaceful planet.
Easy Way to Create Colorful Bash Prompt
The Problem
I often want to fiddle with the bash prompt, but don’t want to deal with bash prompt escape sequences. I wish for a utility which simplify setting a bash prompt. I finally wrote that utility myself: mkprompt
Install
Copy mkprompt to a directory in the path.
Using mkprompt
The best way to show mkprompt usage is via a couple of examples.
PS1=$(mkprompt "red workdir" space dollar)
PS1=$(mkprompt "cyan Workdir" space "green dollar")
mkprompt # display help
For more information, see my shell_tools page.
What’s Next?
The following are improvements which I plan for mkprompt, depends on my free time:
- Implement the rest of the prompt escape sequences
- Improve the help output
- Implement installation script
The Script
I current host my script as part of my shell_tools collection on GitHub.
Automatically List a Directory’s Contents After Changing Dir
The Problem
After the cd command, the next command is almost always ls so we want to combine the two to automatically issuing the ls command right after the cd command.
The Solution
In bash, add the following line in either ~/.bash_profile or ~/.bashrc:
function cd() { builtin cd "${@:-$HOME}" && ls -l; }
If you are using csh or tcsh, add the following line to .cshrc:
alias cd 'cd \!*; ls -l'
Now, whenever we type a cd command, not only we are changing the work directory, but also list the files at the new location. I would like to thank Matt Jenkins for helping me out with the csh part.
Bash – Log to Screen and File Simultaneously
The Problem
In my bash script, I would like to print both the the standard output (typically the screen) and a file.
The Solution
Below is a simple script which demonstrate the solution.
#!/bin/sh # whatis: Demo script that prints to both screen and a file { echo Logging demo echo Output will go both the screen and logging.log # Other lines which might produce output here } | tee logging.log
Discussion
Normally, the output from a bash script goes to the standard output, typically the screen. To redirect the output to both the standard output and a file, we employ the tee program. By surrounding the block of code with curly braces, we redirect the whole block, not just individual lines.
Restore Your SSH Session Working Directory
The Problem
I want to login to a remote Linux machine via SSH and to be in the same directory I was before my last log out.
The Solution
Since my login shell is bash, I present this solution in bash, but you can adapt it for your favorite shells. This tip relies on the two special files ~/.bash_profile and ~/.bash_logout. When a user logs out of a Linux system, the login shell (bash in this case) executes the ~/.bash_logout file, which is where we save our working directory:
# Contents of .bash_logout rm -f $LASTDIRFILE echo cd $PWD > $LASTDIRFILE
Likewise, we a user logs in, bash execute .bash_profile, so we put the instruction to restore the working directory there:
# Contents of .bash_profile # ... # Restore last directory export LASTDIRFILE=~/.lastdir test -f $LASTDIRFILE && source $LASTDIRFILE
Conclusion
The ~/.bash_logout is a wonderful file for saving your session’s details and its counterpart, ~/.bash_profile, is good for restoring them.
Adding Confirmation to bash
The Problem
Bash does not have a “confirm” command to solicit the user’s confirmation of an action. I realize that some commands, such as rm which can ask for the user’s confirmation via the -i flag, but many do not. In addition, when writing bash scripts, I often run into situations which requires the confirmation for a series of commands, not just a single one.
The Solution
I created a confirm command, really a bash function which we can include in our script. The interface for this function is simple: think of it as a stripped-down version of the echo command. Below is the contents of confirm.sh, where I defined the confirm function.
The Code
# ====================================================================== # # Function: confirm # Asks the user to confirm an action, If the user does not answer yes, # then the script will immediately exit. # # Parameters: # $@ - The confirmation message # # Examples: # > # Example 1 # > # The preferred way to use confirm # > confirm Delete file1? && echo rm file1 # > # > # Example 2 # > # Use the $? variable to examine confirm's return value # > confirm Delete file2? # > if [ $? -eq 0 ] # > then # > echo Another file deleted # > fi # > # > # Example 3 # > # Tell bash to exit right away if any command returns a non-zero code # > set -o errexit # > confirm Do you want to run the rest of the script? # > echo Here is the rest of the script # # ====================================================================== function confirm() { echo -n "$@ " read -e answer for response in y Y yes YES Yes Sure sure SURE OK ok Ok do if [ "_$answer" == "_$response" ] then return 0 fi done # Any answer other than the list above is considerred a "no" answer return 1 }Discussion
To use the function, just save the contents of the file above and name it
confirm.sh. Before using the confirm command
in your script, include the confirm.sh:source confirm.shThe examples above should provide enough information to get started. For comments,
suggestions, bugs report, please post a comment to this blog post.
Sweeten Bash History by Adding Grep
The Problem
While I know about the Ctrl-R key combination in bash to perform an incremental reverse search the history; I often need to grep the history to find what I want. For example, to find out what directory I changed into, I issue the following command:
$ history | grep cd
That’s a lot of typing for a lazy guy like me. Imagine that. I rather spend my time writing this blog that repeating that command.
The Solution
To solve this problem, I created a simple function and placed it in my ~/.bash_profile file:
function h() { if [ -z "$1" ] then history else history | grep "$@" fi }
Explanation
- Line 2-5: If the user call the command h without any parameter, the function calls the history command
- Line 6-7: Otherwise, issue the history command and use grep to search.
Going back to my original example, the command now becomes:
$ h cd
Clearly, this is the way life should be: short and sweet. See you in another post.