Tank Wars in G3D
Reading Email with PHP and IMAP/POP3
A Simple Terrain Model
Compiling and Installing Freespace 2 on Ubuntu Linux
Installing Proprietary nVidia Drivers on Ubuntu Linux
Garmin Edge 205 GPS Cycle Training Tool

Useful Ubuntu Linux Commands

Linux commands can be far from intuitive, with files related to a single application seemingly scattered throughout various locations, such as usr, bin, etc, var. This can make it difficult to recall how to invoke certain essential but not every-day commands. This page lists these commands in a single place.
compton, 6 September 07
Updated 23 December 11

Set Page Up and Down keys to Search bash History


Create a file in your home directory called .inputrc containing the following lines:
"\e[5~": history-search-backward "\e[6~": history-search-forward

Now type the first few letters of a command, press Page Up and bash will show you the last command you entered that began with those letters. Press again for the previous match, and so on.

Increase the Sudo Timeout


After you run a terminal command as root by prepending it with sudo, you can execute further commands with sudo without reentering your password as long as each successive command is no more than 5 minutes apart, by default. You can change this default by adding a line like that below to your sudoers file:
Defaults:myusername timestamp_timeout=-1

By setting the timeout to -1 as above means that there is no timeout, and you only need enter your root password the first time you run sudo in any terminal session. Alternatively, use a positive integer to specify how many minutes you want the timeout to be. Don't forget that the right way to edit your sudoers file is by using visudo.

Recursively Applying chmod To Files Only


There are often occasions when you need to ensure all files in the current folder and all subfolders have specific access attributes, but chmod's -R flag would also apply the same attributes to directories. This is usually a problem because directories need the executable bit set if they are to be accessible. The solution is to use find in combination with chmod:
find .. -type f -print0 | xargs -0 chmod 755

Use -type d if you want to apply chmod only to directories rather than only to files.

Handy Bash Keyboard Shortcuts


Ctrl + LClears the Screen, similar to the clear command
Ctrl + ZPuts whatever you are running into a suspended background process. fg restores it.
Ctrl + WDelete the word before the cursor
Ctrl + UClears the line before the cursor position. If you are at the end of the line, clears the entire line.
Ctrl + KClear the line after the cursor
Ctrl + T Swap the last two characters before the cursor
Esc + TSwap the last two words before the cursor

Clean Deadwood out of SVN Repo


It's not uncommon for extraneous files to find their way into a subversion repository over time. Backups, test scripts, IDE setting files and folders; all these and more can be found washed up in your once pristine repos. The more people you have in your team, the more likely this is to happen, and the more varied the deadwood flies will be. Often there will be multiple files with a similar filename scattered throughout, such as the subfolders called _notes that dreamweaver creates inside every folder.

We can splam all these in one go with a little CLI Fu. This bash command will remove all _notes folders from subversion, and then delete them from disk:
find . \( -name _notes! -name "*.svn*" \) | while read line; do svn delete "$line"; rm -rf "$line"; done

Obviously, you'll need to do a commit afterwards, and you'll probably want to do an update immediately beforehand.

Create a TAR archive with a Folder Tree starting at the Current Working Directory


Use the anchored option as below:
tar -cz --anchored -f archive.tar.gz folder1/subfolder1/* folder1/subfolder2/* folder2/* index.html style.css

Find files in a directory that are mentioned within files in another directory


ls srcdir | while read filename;do find targetdir -type f -name "*.php" -exec grep -o "$filename" {} \; ; done | uniq -c

This command lists all the files inside the directory called srcdir, and then searches all files in targetdir, including those inside subdirectories, looking for any that contain the filenames from srcdir. It outputs just the names of files from srcdir that are mentioned within other files, along with a count of how many times each was found.

This is useful when trying to determine if any files in a directory are no longer in use, ie no longer linked to from (or included by) other files.

Get File From an arbitrary SVN Repo


svn cat svn://myserver.dev/trunk/filefromtrunk.php > otherverson.php

Get SVN History Since a Specific Revision


svn log -r 31:HEAD

This will retrieve all commit messages, dates and users for all commits from revision 31 inclusive. You can substitute another revision number in place of HEAD if you want to limit to a range of revisions.

List All Files Modified Since a Specific SVN Revision


Basically use the same SVN command as above, but with the verbose switch and then feed into grep, sort and uniq to get a list of what files were modfiied, added or deleted:
svn log -r 31:HEAD -v | grep -E ' (M|A|D) /' | sort -k2 | uniq

Find SVN Revisions Committed by a Specific User


Do this by passing the SVN log through grep:
svn log svn://server/repo | grep -i insert_username_here

This will just show details such as the date, time and revision number from the commit message. You could use the -A2 switch on grep to view the first line of the commit message for each change, but this will take up screen space of course, and can easily eat up all your scrollback if this is not a new project and has a lot of history in the log. Alternatively you can just view the comment for a specific commit by replacing the XXX below with the revision number:
svn log -rXXX http://bacon.server.dev/svn/central

SVN also has the -lNN option which will limit the response to NN lines, but of course this is before it's further filtered by grep.

Find a server's external IP address via DNS from CLI


wget -q -O - checkip.dyndns.org|sed -e 's/.*Current IP Address: //' -e 's/<.*$//'

Read a file and perform a command for each line


The following trivial example simply copies a file from inputfile to outputfile, but naturally you can replace the echo command with any other of your choosing.

cat inputfile | while read line;do echo $line >> outputfile; done

Useful Additions to .bash_profile



# set xterm title and shell prompt export PS1="\[\e]2;\u@\H \w\a\e[31;1m\]\u@\H \w\[\e[0m\] " # ignore duplicates and any commands you enter where the first character is a space HISTCONTROL=erasedups:ignorespace # ignore these commands in history file HISTIGNORE=l[sla]:cd:pwd:exit:clear # preserve history across multiple terminals shopt -s histappend PROMPT_COMMAND="history -a;$PROMPT_COMMAND"

Set Disk Checking to Once per Month


Ubuntu defaults to running a disk check every 30 boots, or once a month (I think). The following command will set it to just check once per month, regardless of how many times you reboot:

sudo tune2fs -c 0 -i 1m /dev/sda1

Search within Selected Files Recursing Through Folders


grep has the -r option to do a recursive search through folders under the specified path. However it won't work in conjunction with wildcards such as *.java. To do searches such as this, you need to use it in combination with find and xargs like so:

find ~/startfolder -type f -name '*.java' -print0 | xargs -0 grep 'searchpattern'

Create a tar.gz Compressed Archive


tar -cvzpf archive.tar.gz sourcedir1 sourcedir2

The -c option means create a new archive, -v is for verbose, -z indicates it should be a gzipped archive, -p means preserve permissions on files, and -f means use the specified archive file.

List contents of a tar.gz Compressed Archive


tar -tzf archive.tar.gz

Unzip a ZIP archive


unzip -d /path/to/destination /path/to/zip

List All directories containing certain files


find . -type f -name '*.py' |sed 's#\(.*\)/.*#\1#' |sort -u

This will list all directories under the current directory which contain python files.

Flush bash history


The bash shell keeps a record of commands that have been used in the file ~/.bash_history. However the commands used in the current session are not written to this file until you log out of the current session. If you wish to flush the history to this file before logging out, use the following:
history -a

'a' here stands for append - so this is the regular behaviour. If you want, you can use 'w' instead, which will replace the current bash history file with the session history.

List the most recently modified file


ls -lt | grep ^[^dt] | head -1

Switch to a Virtual Terminal from the command line


sudo chvt 1

Display a Unix timestamp in a readable form


date -d @1193144433

Reset WINE (equivalent to a reboot in Windows)


wineboot

Restart the pulseaudio deamon


pulseaudio -k; pulseaudio -D

Restart Apache2 on Ubuntu


sudo /etc/init.d/apache2 restart

View Apache2 error log


gedit /var/log/apache2/error.log


This location is also where apache keeps its access.log file.

Force Disk Check on Next Reboot


sudo touch /forcefsck

Reload Apache2 Config Settings


sudo /etc/init.d/apache2 force-reload

Install Apache2 Module (eg ModRewrite)


sudo a2enmod module_name

eg sudo a2enmod rewrite

Then force Apache to reload config settings as above.

Regenerate the fonts cache:


sudo fc-cache -fv


The default location of system fonts is /usr/share/fonts/. Different font types are grouped into subfolders off here.

Create a symbolic link


ln -s /path/to/target /path/to/linkname
You can omit the final linkname argument if you want to create a link in the current directory with the same name as the target directory.

Change the target of an existing symbolic link


ln -sf /path/to/target /path/to/linkname
The 'f' option (or --force) actually overwrites any existing file with the same name & location as the newly created link. If not given, it should just hide any such files until the link is destroyed.

The effect is that if the link already exists, this command will change it so it links to the specified target location. If it doesn't already exist, it will be created as normal.

Copy a file over a network via SSH


ssh -l {login_name} 192.168.0.XXX cat /path/to/target > /path/to/outputfile

Shortcuts for Eclipse IDE


Lower Case: CTRL+SHIFT+Y
Upper Case: CTRL+SHIFT+X

Jump to Matching Bracket: CTRL+SHIFT+P

Copy current line(s) and place them above/below: CTRL+ALT+UP/DOWN
Move current line(s): ALT+UP/DOWN

Comment/uncomment current line(s): CTRL+/

Switch to next/prev tab: CTRL+PgUp/PgDn

Close current file: CTRL+W

Find open file: CTRL+E

Delete to end of line: CTRL+SHIFT+DELETE
Delete previous word: CTRL+BACKSPACE

Import Gzipped MySQL Database on the command line



gunzip < /path/to/database.sql.gz | mysql -u root -p -D databasename

The final -D databasename option for the mysql client selects the named database, and is only necessary when the gzipped SQL file doesn't begin with a USE databasename command.

Unix for loop syntax



The following returns every line in all files called build.mk in all subdirectories of the current working directory which contain the text 'bird', along with the name of each file:

for filename in `ls *.mk`; do grep -H bird $filename; done


Typical output might be:

./src/mozilla/extensions/build.mk:# Ben Turner mozilla@bongbirdnest.com

The name and path of each file appears, a colon then the actual line containing the string 'bird'.

Mount an ISO Image in Unix



sudo mount -o loop /path/to/iso /path/to/mount/point

Replace Underscores with Spaces in File and Directory Names



ls | while read filename ; do echo "$filename" | grep "_" >/dev/null 2>&1 ; if [ $? -eq 0 ] ; then newfilename=`echo "$filename" | tr "_" " "`; mv "$filename" "$newfilename" ; echo "renamed \"$filename\" to \"$newfilename\"" ; fi ; done

List installed packages



How you do this will depend on the package manager used by your distribution. For RPM based distros, such as Red Hat, Fedora Core, Suse Linux, Cent OS, use:

rpm -qa | grep -i 'package-name'

The i switch on grep is pretty unnecessary really, as all libraries seem to use only lower case.

For .deb systems such as Debian and Ubuntu, use:

dpkg --list | grep -i 'package-name'