Shell Scripting
Dealing with ._ files in Mac OS X
by Matt Danger on Jan.26, 2010, under Mac OS X, Shell Scripting, terminal
The current code base I’m working from is located on a network share and controlled by Subversion. I’ve been dealing with the Apple Double format problem a lot lately and scripted a simple clean up solution.
For those unfamiliar with the Apple Double problem, it is an old bug that exists from the early days of Mac OS X. Here’s the explanation from the Apple Knowledge Base:
Before Mac OS X, the Mac OS used ‘forked’ files, which have two components: a data fork and a resource fork. The Mac OS Standard (HFS) and Mac OS Extended (HFS Plus) disk formats support forked files. When you move these types of files to other disk formats, the resource fork can be lost.
With Mac OS X, there is a mechanism called “Apple Double” that allows the system to work with disk formats that do not have a forked file feature, such as remote NFS, SMB, WebDAV directories, or local UFS volumes. Apple Double does this by converting the file into two separate files. The first new file keeps the original name and contains the data fork of the original file. The second new file has the name of the original file prefixed by a “._ ” and contains the resource fork of the original file. If you see both files, the ._ file can be safely ignored. Sometimes when deleting a file, the ._ component will not be deleted. If this occurs you can safely delete the ._ file.
Essentially, when you’re working on files located on a network share you end up with duplicates of the file with a “._” prefix. The files are empty and are quite the annoyance. They are removed when the network share is unmounted. However, I leave my share mounted for long periods of time and the files make a mess of my Subversion status reports.
You can run the following command to clean the files up.
find . -name '._*' -exec rm '{}' ';'
You could also make this into a launchctl or cron task. Happy hacking!
Facebook-Status-2.0 announced!
by Matt Danger on Feb.10, 2009, under Perl, Shell Scripting, Uncategorized, Unix, terminal
I have updated my original Facebook status script to work with Facebook 2.0.
Why is this interesting? Until recently the Facebook Developer Platform didn’t allow the changing of user status messages. This does and can be implemented in other utilities, which I may do in the future. Enjoy!
Bash Examples
by Matt Danger on Nov.23, 2008, under Shell Scripting, Unix
A while ago a friend was taking an entry level Unix programming class and asked me to help him study. I came up with some sample problems for him. Here are my solutions:
The first is a program that will allow a user to input as many numbers as the user wants (999 as the choice that ends the user input). The program will then output the highest number, the lowest number, the sum of all the numbers, and the average number.
#!/bin/bash COUNT=0 echo -n "Enter a number (999 to quit): " while read NUM; do # Set initials if [ $COUNT -eq 0 ]; then HIGHEST=$NUM LOWEST=$NUM SUM=$NUM fi # If 999 is entered, break out if [ $NUM -eq 999 ]; then break else # See if inputted number is the highest number if [ $NUM -gt $HIGHEST ]; then HIGHEST=$NUM fi # See if inputted number is the lowest number if [ $NUM -lt $LOWEST ]; then LOWEST=$NUM; fi # Calculate sum SUM=$(($SUM+$NUM)) echo -n "Enter another number (999 to quit): " fi COUNT=$(($COUNT+1)) done AVERAGE=$(($SUM/$COUNT)) echo "Highest number: $HIGHEST" echo "Lowest number: $LOWEST" echo "Sum of the numbers: $SUM" echo "Average of the numbers: $AVERAGE"
The second program is a number guessing game. The computer picks a number from 0-60 then allows the user to guess at the number until the user gets it right. The program gives the user a hint on whether they should guess a higher or lower number.
#!/bin/bash RAN=$((RANDOM%60)) COUNTER=1 echo -n "I've guessed a number between 0-60, what is it? " while read GUESS; do if [ $GUESS -eq $RAN ]; then break; else echo if [ $GUESS -lt $RAN ]; then echo -n "Nope, try a higher number: " else echo -n "Nope, try a lower number: " fi fi COUNTER=$((COUNTER+1)) done echo echo "Yep, good job! It took you $COUNTER tries to guess correctly."
The third program allows a user to type in a number, then the program will either count up to the number provided by the user or count down from that number. In addition, a menu lets the user choose which counter they wish to use. In both cases that counter will either count down to 0, or start counting from 0.
#!/bin/bash echo -n "Enter a number: "; read NUM echo -n "Enter U to count up to $NUM and D to count down to 0: "; read CHOICE case $CHOICE in 'u'|'U') COUNTER=0 while [ $COUNTER -le $NUM ]; do echo $COUNTER COUNTER=$(($COUNTER+1)) done ;; 'd'|'D') while [ $NUM -ge 0 ]; do echo $NUM; NUM=$(($NUM-1)) done ;; *) echo "Error: You entered an invalid argument." esac
The last program asks the user if they want to add, subtract, multiply or divide two user inputted numbers. Then the program outputs the sum of number 1 and number 2, the difference of number 1 and number 2, the product of number 1 and number 2, and the quotient of number 1 and number 2
This program will run until the user wants to quit. Also, if the user puts in a 0 as the second number, we let the user know that if they choose divide that a division by zero error will occur.
#!/bin/bash while true; do echo "Please enter two numbers (type 'q' to quit): " echo -n "Number 1: " read NUM1 if [ $NUM1 == "q" ]; then exit; fi echo -n "Number 2: " read NUM2 echo -n "Enter (a) to add, (s) to subtract, (m) to multiply, or (d) to divide these numbers: " read OPERATION case $OPERATION in a) echo "The sum of $NUM1 and $NUM2 is: $(($NUM1+$NUM2))" ;; s) echo "The difference of $NUM1 and $NUM2 is: $(($NUM1-$NUM2))";; m) echo "The product of $NUM1 and $NUM2 is: $(($NUM1*$NUM2))" ;; d) if [ $NUM2 -eq 0 ]; then echo "You can't divide by 0, a division by zero error will occur." else echo "The quotient of $NUM1 and $NUM2 is: $(($NUM1/$NUM2))" fi ;; esac done