## Bash shell scripting

This post is a good introduction to bash scripting/programming.

## My own programming style convention for most languages

I write code mainly in R, and from times to times, in C, C++, SAS, bash, python, and perl. There are style guides out there that help make your code more consistent and readable to yourself and others. Here is a style guide for C++, and here is Google’s style guide for R and here is Hadley Wickam’s guide for R. For R, I agree more with Google’s style guide than Hadley Wickam’s because I absolutely hate typing the underscore (personal preference) and because Google’s style guide seems more related to that of the C++’s guide. Style guides differ by languages because the languages are different (restrictions on names, etc.).

My brain goes crazy if I have to remember and apply multiple styles, so I want to use a convention that I can use consistently for all languages. This boils down to refraining from using special characters such as “-“, “.”, and “_” in names as these characters can have special meaning in different languages. Here it goes:

• constants: the letter k or n followed by a description. For example, kConstant or nSim.
• variable names: description words where the first word is lower case and every subsequent words are lower case but with an upper case first letter. For example, varBeta1 for variance of beta1.
• function names: a verb followed by description words, with each word capitalized except. For example, savePlot and computeGRhoGamma. This is the same as the variable names. I originally was going to follow the Google R style guide instead of the C++ style guide, but opted for the latter because the reasoning made sense: the distinction is obvious based on syntax when a function is called (has parentheses and possibly arguments).
• function arguments: depending on the type of argument, use the variable names or function names style for each. To help distinguish an argument that takes in a function, the argument should begin with f if it takes in a function. For example, drop=TRUE and fSummarize=summarizeDefault.

When breaking these conventions lead to a better understanding of the code (easier on the brain), I will not hesitate to break them. For example, using i, j, k as iterator variables, using na.rm as functional argument in R, or rKM for a function that draw random numbers from a Kaplan-Meier survival curve.

Now, if only I can just magically transform all of my own code into this convention. I’m going to really hate going back to old code that doesn’t follow my own style, especially when they refer to code in packages that I will update according to my new convention.

## Bash script auto-complete filename by file type/extension

Suppose I wrote a bash script with usage script.sh filename.type. That is, the script takes in filenames as arguments. Bash’s tab completion works with all files. However, I’ve seen commands that will complete the filename even faster because it will select the file with the “right” extension. For example, pdflatex firstpart[Tab] would automatically select firtpart.whatever.is.next.tex. I’d like this feature for the scripts I write as well. Thanks to this post and this, I found out it is implemented through the complete function in bash. For installed programs like pdflatex, the complete commands are added to /etc/bash_completion through the installer script (I think). For me, I can add them to my ~/.bashrc:

 <pre class="src src-sh"><span style="color: #ff4500;">##</span><span style="color: #ff4500;">complete -G "*.Rnw" pgfSweave</span>


complete -f -X ‘!.@(Rnw)’ pgfSweave Sweave Sweave.sh complete -f -X ‘!.@(eps|ps)’ eps2pdf.sh

## DirB, Directory Bookmarks for Bash

I found out about DirB through this Linux Journal article. Pretty useful and user-friendly. Don’t know if I’ll remember to use it since I use Dired in Emacs for bookmarking directories. I just need to remember these commands:

<pre class="src src-sh">s &#8212; save a directory bookmark.


g — go to a bookmark or named directory. p — push bookmark/directory onto dir stack. r — remove a saved bookmark. d — display a bookmarked directory path. sl — print the list of directory bookmarks.

To install, save this to ~/.bashDirB and place source ~/.bashDirB in your ~/.bashrc file. I commented out the PS1 definition in the .bashDirV file since I don’t like it.

## Monitor disk usage and send email when disk is nearly full

This site and this site describe some scripts to monitor disk usage of a computer based on the df command and email the ADMIN when disk usage reaches a certain percentage. The scripts can be ran periodically based on cron.

These scripts did not work on my local NAS because I have one filesystem called /dev/mapper/acer-root that takes up two lines in the output of df; hence, the scripts run into an error when trying to grab the 5th column of the output. Also, in recent versions of Ubuntu, /bin/sh is symbolically linked to dash; to get the scripts to work, remove the function keyword or change to /bin/bash on the shebang (#!) line in order for the scripts to run.

I adapted a script found on this site for my own use:

 <pre class="src src-sh"><span style="color: #ff4500;">#</span><span style="color: #ff4500;">!/bin/</span><span style="color: #00ffff;">bash</span>


## adapted from ## http://www.unix.com/unix-dummies-questions-answers/100941-email-warning-script-disk-usage.html #### check disk space on filesystems listed filesystems=(/ /boot /h2tb) for fs in ${filesystems[@]}; do disk_space=df -h | grep -E$fs$| awk '{print$(NF-1)}' max_space=“80” disk_space=${disk_space:-$((max_space-1))} ##[[ “${disk_space%’%’}” -ge “$max_space” ]] && { clear ; echo -e “nWARNING…DISK SPACE ON “$fs” IS AT$disk_spacen”; } [[ “${disk_space%’%’}” -ge “$max_space” ]] && { echo “” | mutt -s “WARNING…DISK SPACE ON “$fs” IS AT$disk_space” MY.EMAIL.ADDRESS ; } done unset filesystems fs disk_space max_space ####

Note that I use mutt to send emails; mail would be simpler and more portable, but it isn’t set up on my server.

I added the following to cron via crontab -e to get the script to run hourly:

 <pre class="src src-sh">0 * * * * /path/to/diskAlert.sh