Tuesday, November 29, 2011

Using --exclude-from in rsync

I've been toying with some rsync scripts tonight and after reading the rsync man page I still needed a little trial and error to determine the exact behaviour of the --exclude-from flag.

The --exclude-from flag specifies a file that contains exclude patterns (one per line). The rsync man page is VERY detailed on the subject of filters and how they can be used.

Looking at a simplified version of my scenario, consider the following directory structure:
   Source
   |---.DS_Store
   |---Alpha
   |  |---.DS_Store
   |  |---Document 1.txt
   |  |---Document 2.txt
   |  `---Temporary Items
   |     |---.DS_Store
   |     |---TI1.tmp
   |     `---TI2.tmp
   |---Beta
   |  |---.DS_Store
   |  |---Document 3.txt
   |  |---Document 4.txt
   |  `---Temporary Items
   |     |---.DS_Store
   |     |---TI2.tmp
   |     `---TI4.tmp
   `---Temporary Items
      |---.DS_Store
      `---TI5.tmp
I want backup the Source directory shown above and exclude the following from my backup:
  1. All of the ".DS_Store" files.
  2. All of the "Temporary Items" directories.
  3. All files contained in the "Temporary Items" directories.
My final backup will look like this:
   Destination
   |---Alpha
   |  |---Document 1.txt
   |  `---Document 2.txt
   `---Beta
      |---Document 3.txt
      `---Document 4.txt

Making this happen is very simple. The exclusions file (skip.txt) only needs to contain the following two lines:
Temporary Items
.DS_Store
The rsync command to perform the backup is as follows:
rsync -az  --exclude-from=./skip.txt ./Source/ ./Destination/
The output of this command is the "Destination" directory shown above.

There were two things that caused me greif getting my script to work:
  1. To exclude a file (or directory) with spaces in the name, the names DO NOT need to be quoted or escaped.
  2. To exclude all files underneath a directory you need only exclude the directory itself.
Now that this is committed to my long term memory I can move on.

Monday, November 21, 2011

Fixing unmappable character during Java compilation on Ubuntu

In the lab we have a standard header at the top of our source files, a copyright statement and licence. This header contains an ISO 8859-1 encoded copyright character (©).

Normally the header blurs into the background, the exception to this rule is the first time a do a build on a new Ubuntu system and I see the following error:

[javac] /src/com/yourcorp/HelloWorld.java:8: unmappable character for encoding ASCII
[jacac] /* ?? Copyright Yourcorp 2011

The Java compiler is expecting ASCII characters rather than ISO 8859-1. To resolve this error I do the following:
  1. Edit /var/lib/locales/supported.d/local and add:
    en_AU ISO-8859-1
    en_US ISO-8859-1
    
    
  2. Open a terminal and run:
    $ sudo dpkg-reconfigure locales
    
    
  3. Edit /etc/environment and add:
    LANG="EN_US"
    
    
  4. Reboot.
With Ubuntu being so stable these days it's a long time between re-installs so I have posted this here for next time when I forget.

Sunday, June 26, 2011

Run scripts when gnome-screensaver starts or stops in Ubuntu

For a project I have been playing with I need to be able to run a script when gnome-screensaver starts or stops on Ubuntu (10.04).

The gnome-screensaver FAQ provides detail on the dbus signal fired when gnome-screensaver activates and deactivates. The FAQ even has sample perl code to respond to the signal. Unfortunately the sample code polls dbus-monitor which is too inefficient for script I plan to run in the background on my laptop.

Python offers a great dbus library which allows signal receivers to be registered with dbus resulting in an efficient event listener.

On to the script.

Step 1: Setup the required files and directories
  1. Make a directory for your work:
    sudo mkdir -p /opt/ssTrigger
  2. Change yourself the owner of the new directory:
    sudo chown `whoami`:`whoami` /opt/ssTrigger
  3. Create stubs for the scripts to be used
    touch /opt/ssTrigger/ssTrigger /opt/ssTrigger/ssStart /opt/ssTrigger/ssStop
  4. Make the stub scripts executable:
    chmod 755 /opt/ssTrigger/*

Step 2: Edit the ssTrigger script
  1. Open the ssTriger file created earlier:
    gedit /opt/ssTrigger/ssTrigger
  2. Add the following to ssTrigger:
    #!/usr/bin/env python
    from gobject import MainLoop
    from dbus import SessionBus
    from dbus.mainloop.glib import DBusGMainLoop
    from subprocess import Popen
    
    class SSTrigger:
        def __init__(self):
            DBusGMainLoop(set_as_default=True)
            self.mem='ActiveChanged'
            self.dest='org.gnome.ScreenSaver'
            self.bus=SessionBus()
            self.loop=MainLoop()
            self.bus.add_signal_receiver(self.catch,self.mem,self.dest)
        def catch(self,ssOn):
            if ssOn == 1: #Screensaver turned on
                Popen(["/opt/ssTrigger/ssStart"])
            else: #Screensaver turned off
                Popen(["/opt/ssTrigger/ssStop"])
    
    SSTrigger().loop.run()
    
  3. Save and close the file.

Step 3: Set ssTrigger to start when you login:
  1. Open the Startup Applications menu:
    System -> Preferences -> Startup Applications

  2. Click "Add" to create a new startup application.

  3. Enter the following details:
    Name: Screensaver Trigger Script
    Command: /opt/ssTrigger/ssTrigger

  4. Click "Add" to save your new application.

  5. Restart your computer.

Finishing up:
Once you have restarted you can run:
ps aux | grep ssTrigger
Check the output to make sure the ssTrigger script has started at login.

Edit the ssStart and ssStop scripts to run commands as gnome-screensaver starts and stops respectively.

Friday, June 24, 2011

Downgrade to Firefox 3.6 on Ubuntu 11.04 Natty

We have a requirement in the office to downgrade to Firefox 3.6 on some test machines running Ubuntu Natty (11.04). To do this you can pin the firefox and firefox-branding packages to older packages from the Ubuntu Maverick (10.10) release.

Step 1: Edit your software sources to add Maverick
  1. Open your sources.list file:
    sudo gedit /etc/apt/sources.list

  2. Add the folowing three lines:
    # Maverick, used for firefox and firefox-branding 
    deb http://ftp.iinet.net.au/pub/ubuntu/ maverick main 
    deb http://ftp.iinet.net.au/pub/ubuntu/ maverick-updates main

  3. Save and close the file

Step 2: Pin the packages firefox and firefox-branding
  1. Create the pin file for firefox:
    sudo gedit /etc/apt/preferences.d/firefox

  2. Add the following:
    Package: firefox
    Pin: release n=natty
    Pin-Priority: -10
    
    Package: firefox
    Pin: release n=maverick
    Pin-Priority: 900

  3. Save and close the file.

  4. Create the pin file for firefox-branding:
    sudo gedit /etc/apt/preferences.d/firefox-branding

  5. Add the following:
    Package: firefox-branding
    Pin: release n=natty
    Pin-Priority: -10
    
    Package: firefox-branding
    Pin: release n=maverick
    Pin-Priority: 900

  6. Save and close the file.

Step 3: Check your apt policy to make sure it worked
  1. Update your apt cache:
    sudo apt-get update

  2. Show the apt policy for firefox:
    sudo apt-cache policy firefox

    Sample output:
    sudo apt-cache policy firefox
    firefox:
      Installed: 5.0+build1+nobinonly-0ubuntu0.11.04.2
      Candidate: 3.6.18+build2+nobinonly-0ubuntu0.10.10.1
      Package pin: 3.6.18+build2+nobinonly-0ubuntu0.10.10.1
      Version table:
     *** 5.0+build1+nobinonly-0ubuntu0.11.04.2 900
            500 http://ftp.iinet.net.au/pub/ubuntu/ natty-updates/main i386 Packages
            500 http://ftp.iinet.net.au/pub/ubuntu/ natty-security/main i386 Packages
            100 /var/lib/dpkg/status
         4.0+nobinonly-0ubuntu3 900
            500 http://ftp.iinet.net.au/pub/ubuntu/ natty/main i386 Packages
         3.6.18+build2+nobinonly-0ubuntu0.10.10.1 900
            500 http://ftp.iinet.net.au/pub/ubuntu/ maverick-updates/main i386 Packages
         3.6.10+build1+nobinonly-0ubuntu3 900
            500 http://ftp.iinet.net.au/pub/ubuntu/ maverick/main i386 Packages

    The line you are most interested in is "Candidate".
    This indicates the package that apt ranks as the installation candidate.

  3. Repeat this check for firefox-branding
    sudo apt-cache policy firefox-branding

Step 4: Install firefox 3.6
  1. Remove firefox 5.x:
    sudo apt-get remove firefox

  2. Install firefox 3.6:
    sudo apt-get install firefox

And you're done. Enjoy your outdated version of Firefox!


Update - July 24th 2011:

How to reverse the process:
  1. Remove these three (3) lines you added to /etc/apt/sources.list
    # Maverick, used for firefox and firefox-branding 
    deb http://ftp.iinet.net.au/pub/ubuntu/ maverick main 
    deb http://ftp.iinet.net.au/pub/ubuntu/ maverick-updates main
    
  2. Unpin the firefox and firefox-branding packages:
    sudo rm /etc/apt/preferences.d/firefox
    sudo rm /etc/apt/preferences.d/firefox-branding
    
  3. Update your apt cache
    sudo apt-get update
    
  4. Install the latest Firefox:
    sudo apt-get upgrade
    
  5. Close ALL your Firefox windows and re-open Firefox.

Update - December 6th 2011:

From the comments people have posted below I can see that this process works to downgrade Firefox on Ubuntu 11.10 as well as Ubuntu 10.04.

Downgrading packages to the Ubuntu 10.10 release will only work on Ubuntu 11.04 or better. Do not use this procedure on Ubuntu releases older than 11.04. If you try to do this you will be upgrading packages not downgrading.

Friday, April 29, 2011

Lock input without a screen saver in Linux

We came across this problem in the office today. How do we lock the input devices on a Linux machine (we were using Ubuntu 11.04) and keep a the current applications showing and updating? The solution we ended up with was to use xlock.

First you'll need to install xlock:
sudo apt-get install xlockmore
Then run xlock from a terminal with the following options:
xlock -mode blank -geometry 0x0 -timeout 2

The xlock command locks keyboard and mouse input, the flags do the following:
-mode blank displays a blank box in the top left corner of your monitor.
-geometry 0x0 makes the size of the blank box 0x0 pixels.
-timeout 2 sets the timeout (in seconds) for the password prompt if anyone hits a key.

Update 2011-05-02: A second (better) solution

First you'll need to install xtrlock:
sudo apt-get install xtrlock
Then run xtrlock from a terminal:
xtrlock

This will start xtrlock and lock the screen. To unlock the screen type your password and hit enter.