Password Reset

A little bit ago, I was confronted with a problem whose solution I think is worth sharing. My mother-in-law forgot what password she had put on her new (used) MacBook. Normally this isn’t an issue because you can always pop-in the installer disc and reset the password. Unfortunately, there was nary an installer disc to be found.

Fortunately, there is a trick for just such an occasion.

First of all, make sure you know your short username. This is the name you see on your home folder in the finder.

Once that is retrieved, boot into single user mode. This is accomplished by holding the command key and “s” while booting. Single user mode puts the computer into a command line interface as the “root” user, or administrator that can make any changes – no questions asked.

But first, we have to make the filesystem writeable, since it is mounted in a read-only state initially. use the following command:

mount -uw /
Now that the filesystem is writeable, meaning that you can make changes to it, it is time to reset the password. Password retrieval is not feasible as it is encrypted, but you can overwrite it using a built in utility called passwdpasswd will create the new password and store it in the correct place with the proper encryption. To use it, simply type in the command followed by the short user name mentioned earlier.

passwd username
This will prompt you for a password which you will then need to type in twice for verification. Once you have done that, you can safely restart and use your new password! To restart, type the command:

shutdown -r now
Well, I hope this helps someone else out (and that it is only used for good purposes!).

Never Type This As Root

I was working on a shell script this morning to make my life easier on some trivial task. The last few lines looked a little like this.

somedir=/mnt/tmp
mv $somedir/*.txt ~
rm -rf $somdir/*

Obviously I meant to remove all the files in the directory, however a typo in the variable name led to the deletion of /. I caught it before it got to the home folder, but bin and dev were gone resulting in a broken system that needed to be reinstalled.

Never delete * as root unless you are sure you know what you are doing….

UTF-8 Converter


The other day at work, I needed to batch convert about one or two hundred files formatted in MACROMAN format to UTF-8. Well, it turns out there is a command line utility to do just this called iconv. I was very pleased when I found that because it was going to save me a lot of time. Then I ran it and got confused. It turns out that iconv does convert text format, but it doesn’t write it back out to a file, it just spits the results back into the terminal window. Mildly frustrated, I decided to take matters into my own hands and write a script that would take the output and put it back into a file with the same name. These are the results:

#!/bin/bash

for f in $1/* ; do
o=`basename $f`
if file $f | grep Unicode ; then
cp $f $2
else
iconv -f MACROMAN -t UTF-8 $f >$2/$o
fi
done

I went further and added options,  a debug mode, verbose mode, and the like, and even a man page! The syntax is:

# roman_to_utf8 [options] <input> <output>

The input and output can be either directories or individual files.

#!/bin/bash

usage() {
echo Usage: $0 "[-v | --verbose] [-d | --debug] [-e | --encoding <encoding>] <input> <output>"
exit 1
}

VERBOSE=false
ENCODING=MACROMAN
DEBUG=false

while true; do
case $1 in
-v | --verbose) VERBOSE=true;;
-d | --debug) DEBUG=true;;
-*) echo "Bad option $1"; usage;;
*) break;;
esac
shift
done

SOURCE="$1"
DESTINATION="$2"

if [ $DEBUG = true ]; then
echo VERBOSE = $VERBOSE
echo SOURCE = $SOURCE
echo DESTINATION = "$DESTINATION"
echo ENCODING = "$ENCODING"
exit
fi

if [ "x$SOURCE" = x -o "x$DESTINATION" = x ]; then
usage;
fi

convert() {
INPUT="$1"
OUTPUT="$2"
FILENAME=`basename "$INPUT"`
if file "$INPUT" | grep Unicode ; then
cp "$INPUT" "$OUTPUT"
$VERBOSE && echo "Successfully copied $FILENAME"
else
iconv -s -f $ENCODING -t UTF-8 "$INPUT" >"$OUTPUT/$FILENAME"
$VERBOSE && echo "Successfully converted $FILENAME"
fi
}

if [ -d "$SOURCE" ]; then
for INPUT in "$SOURCE"/* ; do
convert "$INPUT" "$DESTINATION"
done
else
convert "$SOURCE" "$DESTINATION"
fi

exit

Please excuse the poor tabbing due to wordpress. In any case, it worked and saved me a ton of time. All you need to do is copy this script into a file and make it executable. Enjoy!

© 2007-2015 Michael Caldwell