Why not just use an OEM installation for this? It's not as pretty, but it gets the job done. If you want to go down this route, see izx's excellent answer to this question: How do I pre-install Ubuntu for someone (OEM install)?
Basically, the system will (on first boot) prompt the user for a bunch of information to personalize their machine. This includes the language, location, username, hostname, password, and so on. Basically, everything that your computer will usually prompt you with for an installation.
This is exactly what OEM images are meant for, and they do a great job of it. Plus, you'll give your students a small taste of the "install Ubuntu" experience. Though, Ubuntu installs aren't exactly painful. You can probably do it in a single class, and give your students some homework to personalize and explore their VM. Plus, partitioning is painful fun!
Back to the problem at hand (and an answer to your actual question).....
Let's look at man usermod
to get an explanation for what's going on:
CAVEATS
You must make certain that the named user is not executing any
processes when this command is being executed if the user's numerical
user ID, the user's name, or the user's home directory is being
changed. usermod checks this on Linux, but only check if the user is
logged in according to utmp on other architectures.
Basically, this just means we can't change a user's UID, their username, home directory, or anything of the sort if the user is logged in.
So, we can do some fun stuff to set this up on the system's next boot. Instead of your script doing the work, we make your script make another script to do all the heavy lifting and manipulation. An example of this:
# Make the first-run script
touch /etc/init.d/firstrun-setup.sh
# Add in user modifier
echo "usermod -d /home/$username -m -g $username -l $username ben" >> /etc/init.d/firstrun-setup.sh
# Add in group rename
echo "groupmod -n $username ben" >> /etc/init.d/firstrun-setup.sh
# Add in password expiry
echo "passwd -e $username" >> /etc/init.d/firstrun-setup.sh
# Add in file self-destruct
echo "rm /etc/init.d/firstrun-setup.sh" >> /etc/init.d/firstrun-setup.sh
# Mark the file as executable
chmod a+x /etc/init.d/firstrun-setup.sh
# Reboot the computer
reboot
Basically, by doing this, you're "queueing" events to run on the system's next boot. This will run before the userland happens, so the system will execute these commands as root. Therefore, the ben
user won't be logged in, and the system won't complain.
You may still need to add additional commands to this thing to allow more personalization (like setting the actual name, etc). However, this is optional and only needs to be done if you want it to take place during the setup script.
Though, it may be a good idea to just create a new user for the students entirely, and then keep your existing sacrificial account in place. This way, if something happens, you can go in and repair/administrate their machine if at all necessary. Of course, if you're giving your students admin access to their VM, this is sort of a moot point as they might very well delete the "instructor" user because they're students.
Best Answer
Changing the hostname
Change the hostname in the following two files:
/etc/hostname
/etc/hosts
(You'll need to use
sudo
to edit these files. Eg.sudo nano /etc/hostname
)Changing the username
First, set a password for root:
Then reboot the machine. When you see the login screen, switch to a virtual terminal using CtrlAltF4. Login with the username
root
and the password you set previously.It's now safe to change the username using the following three steps:
Rename the user:
Change the name of the user directory and all daughter directories to match the new username and update the filepaths:
Update the user database: