HOWTO: Eject All Quicksilver Trigger

Before you begin, make sure you have downloaded, installed, and launched Quicksilver. I am going to assume you know the basics of Quicksilver, in that you understand what its purpose is and how to bring it up.

In order to use this script to create an “eject all” keyboard shortcut we need to do several things:

  1. Turn on Quicksilver’s advanced features.
  2. Install the Terminal Plug-in.
  3. Download the script and move it to an appropriate location.
  4. Make the script executable.
  5. Edit the script to fit your needs.
  6. Setup up a Quicksilver trigger and keyboard shortcut.

Step 1. Turn on Quicksilver’s advanced features.

Activate Quicksilver and bring up its Preferences window. Select the Application group and check the box for Enable advanced features. You will be prompted to relaunch Quicksilver and you should do so. Once Quicksilver has relaunched proceed to the next step.

Step 2. Install the Terminal Plug-in.

Once again activate Quicksilver and bring up its Preferences window, but this time select the Plug-ins group. Now scroll down and find the Terminal Module, check the box associated with it to install it. Quicksilver will flash a little badge up announcing Terminal Module Installed when it has been installed. Now in the next step we will download the script and get it ready for the trigger.

Step 3. Download the script and move it to an appropriate location.

Download eject-all.txt. I will assume it was downloaded to the Desktop as that is the default, if you have changed your downloads location then you will need to adjust the following commands accordingly.

Activate Finder and from the Go menu select Utilities. Press T, Terminal.app should be highlighted, open it and then proceed by typing the following commands.

ls ~/Desktop | grep eject-all

This tell Terminal.app to list the contents of your Desktop directory and check for the eject-all file. You should see,

eject-all.txt

this means you successfully downloaded the script to your Desktop. That part was easy right ;-)

mv ~/Desktop/eject-all.txt ~/.eject-all
ls -a ~ | grep eject-all

The first line tells Terminal.app to move the script from your desktop to your home folder and rename it with a period so that it is hidden (we don’t need to see it normally). The second line show the contents of your home directory with the option -a which shows all (including hidden) and checks to see if the script is there. You should see,

.eject-all

Step 4. Make the script executable.

Now we will make it executable by issuing the command,

chmod +x ~/.eject-all

We can check that it was made executable by issuing the command,

ls -al ~ | grep eject-all

if it was made executable you will see something like,

-rwxr-xr-x    1 nnutter  nnutter   524B Jun 25 13:22 .eject-all

where the x’s in -rwxr-xr-x mean that is executable.

Step 5. Edit the script to fit your purpose.

Finally, you should customize the script a tiny bit to suit your computer, just type,

open .eject-all

You will see,


#!/bin/bash
for i in $( disktool -l | grep "Mountpoint = '/" | sed s/^.*Mountpoint = '// | sed s/',.*// | sed 's/ //g' )
    do
        case "${i}" in
# Add any volumes you might want to skip as alternate case, for example the root volume:
            /)
                ;;
            /Users/nnutter)
                ;;
# This case will take care of all the others, the drives you do want to eject:
            *)
                umount "`echo $i | sed 's// /g'`" && echo "$i unmounted"
                diskutil eject "`echo $i | sed 's// /g'`" && echo "$i unmounted"
                ;;
        esac
    done

At the very least you need to remove the two lines,

            /Users/nnutter)
                ;;

What these cases do is prevent the script from acting on certain volumes which you may not want to eject. Now technically these volumes are probably not ejectable anyway, but why not throw in an extra precaution. In the above case /Users/nnutter is my FileVault volume which I obviously don’t want to eject. The / volume is your main hard drive which you also don’t want to eject. To add volumes just use the format,

            /path/to/volume)
                ;;

Just add these two lines over and over for each volume, most people should be fine with just removing my FileVault example. You might also try duplicating the script, making one for network volumes and one for removable disks, etc. Anyways for most people your script should look like this,


#!/bin/bash
for i in $( disktool -l | grep "Mountpoint = '/" | sed s/^.*Mountpoint = '// | sed s/',.*// | sed 's/ //g' )
    do
        case "${i}" in
# Add any volumes you might want to skip as alternate case, for example the root volume:
            /)
                ;;
# This case will take care of all the others, the drives you do want to eject:
            *)
                umount "`echo $i | sed 's// /g'`" && echo "$i unmounted"
                diskutil eject "`echo $i | sed 's// /g'`" && echo "$i unmounted"
                ;;
        esac
    done

Save it and close your text editor, we can now setup the trigger so we can eject all extra volumes at the touch of a key.

Step 6. Setup up a Quicksilver trigger and keyboard shortcut.

Activate Quicksilver and bring up its Preferences window. This time select the Triggers group. Click the + in the bottom left to add a new trigger.

A sheet will slide down, use tab to move between fields just like normal. In the first field press period to enter text mode then type,

~/.eject-all

Then press tab and type,

run

Wait a half-second and additional options will show up, you want to select Run Command in Shell. Then press return and click on Save. Now all you have to do is assign a keyboard shortcut. Double-click in the trigger column on the word None this will open a drawer which is waiting for your keyboard shortcut. You might try something like Command + Shift + E. Optionally you might also check the box Hold for and put 1 or 2 in the text field, this will make it so you have to hold down the key combo in order to execute the trigger.

You are all done, put in a CD or mount a disk image and give it a try!

Shell Script Eject All For Quicksilver Trigger

At Merlin’s request

Rough draft, first attempt, whatever, it doesn’t work quite yet for me but I’ll post it and see if anybody else can help.

Just create a trigger to run the shell script (once it works correctly, it’s close though) and you can eject all with a hot key, no extra apps needed.

Update: I think I got it working, just save this, make it executable with chmod +x and then create a trigger in Quicksilver to run the shell script. (You will need the appropriate Quicksilver plugins. I’ll make a tutorial when I get home probably.)

eject-all.txt

Bugs:

  1. Doesn’t work if volume has spaces.
  2. Doesn’t properly eject disk images, maybe others.
  3. Uses disktool which is deprecated. If I had to I could just use mount but this works.

#!/bin/bash
for i in $( disktool -l | grep "Mountpoint = '/" | sed s/^.*Mountpoint = '// | sed s/',.*// | sed 's/ //g' )
    do
        case "${i}" in
# Add any volumes you might want to skip as alternate case, for example the root volume:
            /)
                ;;
            /Users/nnutter)
                ;;
# This case will take care of all the others, the drives you do want to eject:
            *)
                diskutil eject  "`echo $i | sed 's// /g'`"
                ;;
        esac
    done

Better Terminal Prompt

Set terminal prompt color and style, green user, red root (set elsewhere), machine, and working directory. Place in your .profile or .bash_profile:

if [ "$TERM" = "xterm-color" ]; then
        C1="[33[0;32m]"
        C2="[33[1;0m]"
        export PS1="${C1}u${C2}@h: W $ "
fi

Generate gnuplot Scripts For Data Sets

plot.sh is a script I wrote as a hack to “dynamically” generate gnuplot scripts for each of the regions I need to plot. There is probably a better way to do this but I am not a gnuplot guru.

My program stored the results of each batch of particles in a numbered folder as well as aggregating the results in the main directory. The script allows you to select whether you are plotting the z-distribution or the v-distribution.

The syntax is:

./plot.sh z .

Plots the z-distribution from the zstate file in the main directory.

./plot.sh +8 .

Plots the v-distribution of the eighth bin in z, the file vstate+8 in the main directory.

./plot.sh +8 0

Plots the v-distribution of the eighth bin in z, the file vstate+8 in the 0 directory, the directory storing the results for the first batch of particles.

Xgrid Submission Script

Background

For my senior project as an undergrad at Illinois State University I wrote a program that could execute on Apple’s Xgrid. I am well aware of GridStuffer but I needed to be able to do most of what GridStuffer did from the command line. I heard about but never tried pyXgrid, instead I chose to write my own little custom scripts. They are available here in the event that someone else might find them useful.

Script

myxgrid.sh allows you to submit, pause, start, check the status of, and get the results of xgrid jobs. It also cleans the jobs off the Xgrid controller and in my case combines the results through the use of another program I wrote.

#!/bin/bash

export XGRID_CONTROLLER_HOSTNAME=
export XGRID_CONTROLLER_PASSWORD=
export EXEC="./distribution"
export NN_WORK=build
# Remember each packet is many particles
N_PACKETS=$2

cd ${NN_WORK}

case "$1" in
    "clean" )
        for id in `cat jobs.list`
            do
                if [ "$id" != 0000 ]
                    then
                        echo Deleting: $id
                        xgrid -job delete -id $id | grep jobStatus
                fi
            done
        rm -f jobs.list
        rm -rf output
    ;;

    "combine" )
        ./combine
    ;;

    "suspend" )
        for id in `cat jobs.list`
            do
                if [ "$id" != 0000 ]
                    then
                        echo Status: $id
                        xgrid -job suspend -id $id
                fi
            done
    ;;

    "results" )
        if [ ! -d output ]
        then
            mkdir output        
        fi
        cd output
        n=0
        for id in `cat ../jobs.list`
            do
                if [ "$id" != 0000 ]
                    then
                        if [ ! -d $n ]
                        then
                            mkdir $n        
                        fi
                        echo Getting results for $id, storing in folder $n
                        xgrid -job results -so $n.out -out $n/ -id $id
                        n=`expr $n + 1`
                fi
            done
    ;;

    "resume" )
        for id in `cat jobs.list`
            do
                if [ "$id" != 0000 ]
                    then
                        echo Status: $id
                        xgrid -job resume -id $id
                fi
            done
    ;;

    "status" )
        if [ "$#" -eq 1 ]; then
            for id in `cat jobs.list`
                do
                    if [ "$id" != 0000 ]
                        then
                            echo Status: $id
                            xgrid -job attributes -id $id | grep jobStatus
                    fi
                done
        fi
        if [ "$#" -eq 2 ]; then
            if [ "$2" == "s" ]; then
                rm -f jobs.tmp
                echo This will take a minute...
                echo Generating Summary Status
                for id in `cat jobs.list`
                    do
                        if [ "$id" != 0000 ]
                            then
                                xgrid -job attributes -id $id | grep jobStatus >> jobs.tmp
                        fi
                    done
                echo Complete:
                cat jobs.tmp | grep "Finished" | wc -l
                echo Incomplete:
                cat jobs.tmp | grep "Pending" | wc -l
                echo Running:
                cat jobs.tmp | grep "Running" | wc -l
                rm -f jobs.tmp
            else
                echo Status: $2
                xgrid -job attributes -id $2 | grep jobStatus
            fi
        fi
    ;;

    "submit" )
# Loop through to send packets
        rm -f jobs.list
        n=0
        while [ "$n" -lt "$N_PACKETS" ]
        do
            xgrid -job submit "${EXEC} $e" | sed 's/{.*= //' | sed 's/;.*//' >> jobs.list
            n=`expr $n + 1`
        done
        echo 0000 >> jobs.list
    ;;
esac
exit 0