4
\$\begingroup\$

I am just wondering what, if any, more elegant ways might exist to write a script to accomplish the task that the script below accomplishes. The script works, so I don't need it to be debugged, but I want to learn more. Other commands to be used, other ways of structuring it, etc. I have taken it through shellcheck.

Yesterday I decided to try my hand at a shell script that would create and open a file to take notes for each of my classes in the folder designated for notes from that class. It was pretty satisfying to do; I started with basically no knowledge and over the course of an hour or two I went from a script that would prompt me to enter the class and the desired file title (read Class read Title if [[ $Class = "X]] then touch /path/"$Title".docx etc) to something that would just create the file in the right place based on the time/date the command is invoked, since the title is always today's date anyhow.

Again, it works. I just know that there must be more ways to skin this cat and I was wondering what those might be. The version below has been revised once after input from some good samaritans.

Also, FWIW, this is running on OS X Sierra.

#!/bin/bash

read date hour day month <<< $(date +"%-d %-H %a %B")
if [[ $hour -lt 11 && $day = "Tue" ]] || [[ $hour -lt 11 && $day = "Thu" ]]; then
    dir="/path/to/first"
elif [[ $hour -gt 12 && $hour -lt 15 && $day = "Tue" ]] || [[ $hour -gt 12 && $hour -lt 15 && $day = "Thu" ]]; then
    dir="path/to/second"
elif [[ $hour -ge 16 && $hour -le 17 && $day = "Wed" ]]; then
    dir="/path/to/third/"
else
    echo "I am of no use to you right now"
    exit 1
fi
file="$dir/$month $date".docx
touch "$file"
open "$file"
killall Terminal
\$\endgroup\$
2
\$\begingroup\$

killall Terminal is very harsh! Maybe you aren't a serious Terminal user now, but someday, you might be doing something important in another Terminal window. And, due to the way macOS works, multiple windows all run under a single Terminal process, so you would be killing all of your Terminal windows. At most, do

osascript -e 'tell application "Terminal" to close the front window'

… which sends a message to just one window using AppleScript. But I would consider even that to be too violent for my taste.


I find those cases too cumbersome to read as conditions. I would write out all of the combinations, using pattern matching, and in particular, extended pattern matching enabled by shopt -s extglob.

#!/bin/bash

shopt -s extglob

read date hour day month <<< $(date +"%-d %-H %a %B")

case $day.$hour in
    @(Tue|Thu).@(8|9|10|11))
        dir="/path/to/first"
        ;;
    @(Tue|Thu).@(13|14))
        dir="/path/to/second"
        ;;
    Wed.16)
        dir="/path/to/third"
        ;;
    *)
        echo "I am of no use to you right now"
        exit 1
esac
…
\$\endgroup\$
  • \$\begingroup\$ Thanks for your input. I included the somewhat drastic killall command basically because I decided that I shouldn't be using the terminal while in class so I might as well include something to save me from myself. I should probably at least replace it with an AppleScript tell to quit command so I'll have a chance to stop it:-). Thanks for your suggestions (and the links are much appreciated!); I'll take some time to learn more about pattern matching. \$\endgroup\$ – dlk0606 Mar 30 '17 at 14:04
1
\$\begingroup\$

You could simplify some of the conditions, for example instead of:

if [[ $hour -lt 11 && $day = "Tue" ]] || [[ $hour -lt 11 && $day = "Thu" ]]; then

You could write:

if [[ $hour -lt 11 ]] && [[ $day = "Tue" || $day = "Thu" ]]; then

With pattern matching you could go one step further:

if [[ $hour -lt 11 ]] && [[ $day =~ Tue|Thu ]]; then

You could apply the same technique to the second condition too.

The last condition is impossible, probably a bug you overlooked, because $hour cannot be greater than 16 and less than 17 at the same time:

elif [[ $hour -gt 16 && $hour -lt 17 && $day = "Wed" ]]; then
\$\endgroup\$
  • \$\begingroup\$ Thanks. Ironically, if you look at the conditions for the third string (and I tell you that I am on US Eastern Time) it shouldn't surprise you to hear that I literally just debugged that. Should have been -ge 16 && -le 17. I was just trying to figure out how to compress the conditions. Very helpful \$\endgroup\$ – dlk0606 Mar 29 '17 at 20:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.