Pages

14 November 2012

Control a remote linux Transmission client.

This is more or less a follow-up to my previous post about connecting to a remote linux desktop session: http://sakiwinet.blogspot.com/2012/11/connect-to-remote-linux-systems-x.html

Here I will show how you can control a remote Transmission torrent client from the command line. Transmission is the standard Ubuntu torrent client. This will mean that instead of following my previous post to download the latest Linux Mint or Ubuntu torrent, you could add it via the command line from a remote ssh session.

In order for this to work you will need to ensure that Transmission has it's "web client" enabled as shown in this screenshot. For security reasons you would not want to open it to the world, so make sure that it is only open to the local machine that it is running on (i.e. 127.0.0.1)

You will also need to install the "transmission-cli" package, using whatever package manager your system uses, in Ubuntu you can do "sudo apt-get install transmission-cli", and make sure Transmission is running, if it isn't then you can start it from the command line as follows:
  1. clive@dogmatix > transmission-remote -l
  2. [12:08:22.988] transmission-remote: (http://localhost:9091/transmission/rpc/) Couldn't connect to server
  3. clive@dogmatix > export DISPLAY=:0
  4. clive@dogmatix > nohup transmission-gtk >/dev/null 2>&1 &
  5. [1] 22245
  6. clive@dogmatix > transmission-remote -l    
  7. ID     Done       Have   ETA           Up    Down  Ratio  Status       Name
  8.    1    100%     801 MB  Done         0.0     0.0   0.00  Stopped      linuxmint-13-cinnamon-dvd-64bit-rc.iso
  9. Sum:             801 MB               0.0     0.0
  10. clive@dogmatix >


To add a torrent to Transmission you would do the following (You need to know the url for the torrent file itself)
  1. clive@dogmatix > transmission-remote -a "http://torrents.linuxmint.com/torrents/linuxmint-14-cinnamon-dvd-64bit-rc.iso.torrent"
  2. localhost:9091/transmission/rpc/ responded: "success"
  3. clive@dogmatix > transmission-remote -l
  4. ID     Done       Have  ETA           Up    Down  Ratio  Status       Name
  5.    1    100%     801 MB  Done         0.0     0.0   0.00  Stopped      linuxmint-13-cinnamon-dvd-64bit-rc.iso
  6.    2      0%   19.05 MB  1 hrs        0.0   178.0   0.00  Downloading  linuxmint-14-cinnamon-dvd-64bit-rc.iso
  7. Sum:          820.05 MB               0.0   178.0

To stop a torrent do the following (Need to know the torrent number, obtained from "transmission-remote -l")
  1. clive@dogmatix > transmission-remote -t 2 -S
  2. localhost:9091/transmission/rpc/ responded: "success"

To remove a torrent (Including the downloaded file(s)):
  1. clive@dogmatix > transmission-remote -t 2 --remove-and-delete
  2. localhost:9091/transmission/rpc/ responded: "success"

The following shows all the options available to control the Transmission client:
clive@dogmatix > transmission-remote --help
transmission-remote 2.51 (13280)
A fast and easy BitTorrent client
http://www.transmissionbt.com/

Usage: transmission-remote [host] [options]
       transmission-remote [port] [options]
       transmission-remote [host:port] [options]
       transmission-remote [http(s?)://host:port/transmission/] [options]

See the man page for detailed explanations and many examples.

Options:
 -h   --help                               Display this help page and exit
 -a   --add                                Add torrent files by filename or URL
 -as  --alt-speed                          Use the alternate Limits
 -AS  --no-alt-speed                       Don't use the alternate Limits
 -asd --alt-speed-downlimit         max alternate download speed (in
                                           kB/s)
 -asu --alt-speed-uplimit           max alternate upload speed (in kB/s)
 -asc --alt-speed-scheduler                Use the scheduled on/off times
 -ASC --no-alt-speed-scheduler             Don't use the scheduled on/off times
      --alt-speed-time-begin  


       Where to store new torrents until
                                           they're complete
 -C   --no-incomplete-dir                  Don't store incomplete torrents in a
                                           different location
 -b   --debug                              Print debugging information
 -d   --downlimit                   Set the max download speed in kB/s
                                           for the current torrent(s) or
                                           globally
 -D   --no-downlimit                       Disable max download speed for the
                                           current torrent(s) or globally
 -e   --cache                        Set the maximum size of the session's
                                           memory cache (in MiB)
 -er  --encryption-required                Encrypt all peer connections
 -ep  --encryption-preferred               Prefer encrypted peer connections
 -et  --encryption-tolerated               Prefer unencrypted peer connections
      --exit                               Tell the transmission session to shut
                                           down
 -f   --files                              List the current torrent(s)' files
 -g   --get                         Mark files for download
 -G   --no-get                      Mark files for not downloading
 -i   --info                               Show the current torrent(s)' details
 -if  --info-files                         List the current torrent(s)' files
 -ip  --info-peers                         List the current torrent(s)' peers
 -ic  --info-pieces                        List the current torrent(s)' pieces
 -it  --info-trackers                      List the current torrent(s)'
                                           trackers
 -si  --session-info                       Show the session's details
 -st  --session-stats                      Show the session's statistics
 -l   --list                               List all torrents
      --move                         Move current torrent's data to a new
                                           folder
      --find                         Tell Transmission where to find a
                                           torrent's data
 -m   --portmap                            Enable portmapping via NAT-PMP or
                                           UPnP
 -M   --no-portmap                         Disable portmapping
 -n   --auth                      Set username and password
 -ne  --authenv                            Set authentication info from the
                                           TR_AUTH environment variable
                                           (user:pw)
 -N   --netrc                        Set authentication info from a .netrc
                                           file
      --ssl                                Use SSL when talking to daemon
 -o   --dht                                Enable distributed hash tables (DHT)
 -O   --no-dht                             Disable distributed hash tables
                                           (DHT)
 -p   --port                         Port for incoming peers (Default:
                                           51413)
 -pt  --port-test                          Port testing
 -P   --random-port                        Random port for incomping peers
 -ph  --priority-high               Try to download these file(s) first
 -pn  --priority-normal             Try to download these file(s)
                                           normally
 -pl  --priority-low                Try to download these file(s) last
 -Bh  --bandwidth-high                     Give this torrent first chance at
                                           available bandwidth
 -Bn  --bandwidth-normal                   Give this torrent bandwidth left over
                                           by high priority torrents
 -Bl  --bandwidth-low                      Give this torrent bandwidth left over
                                           by high and normal priority torrents
      --reannounce                         Reannounce the current torrent(s)
 -r   --remove                             Remove the current torrent(s)
 -pr  --peers                         Set the maximum number of peers for
                                           the current torrent(s) or globally
      --remove-and-delete                  Remove the current torrent(s) and
                                           delete local data
      --torrent-done-script          Specify a script to run when a
                                           torrent finishes
      --no-torrent-done-script             Don't run a script when torrents
                                           finish
 -sr  --seedratio              ratio       Let the current torrent(s) seed until
                                           a specific ratio
 -srd --seedratio-default                  Let the current torrent(s) use the
                                           global seedratio settings
 -SR  --no-seedratio                       Let the current torrent(s) seed
                                           regardless of ratio
 -gsr --global-seedratio       ratio       All torrents, unless overridden by a
                                           per-torrent setting, should seed
                                           until a specific ratio
 -GSR --no-global-seedratio                All torrents, unless overridden by a
                                           per-torrent setting, should seed
                                           regardless of ratio
 -td  --tracker-add               Add a tracker to a torrent
 -tr  --tracker-remove         Remove a tracker from a torrent
 -s   --start                              Start the current torrent(s)
 -S   --stop                               Stop the current torrent(s)
 -t   --torrent                   Set the current torrent(s)
      --start-paused                       Start added torrents paused
      --no-start-paused                    Start added torrents unpaused
      --trash-torrent                      Delete torrents after adding
      --no-trash-torrent                   Do not delete torrents after adding
 -hl  --honor-session                      Make the current torrent(s) honor the
                                           session limits
 -HL  --no-honor-session                   Make the current torrent(s) not honor
                                           the session limits
 -u   --uplimit                     Set the max upload speed in kB/s for
                                           the current torrent(s) or globally
 -U   --no-uplimit                         Disable max upload speed for the
                                           current torrent(s) or globally
      --utp                                Enable uTP for peer connections
      --no-utp                             Disable uTP for peer connections
 -v   --verify                             Verify the current torrent(s)
 -V   --version                            Show version number and exit
 -w   --download-dir                 When adding a new torrent, set its
                                           download folder. Otherwise, set the
                                           default download folder
 -x   --pex                                Enable peer exchange (PEX)
 -X   --no-pex                             Disable peer exchange (PEX)
 -y   --lpd                                Enable local peer discovery (LPD)
 -Y   --no-lpd                             Disable local peer discovery (LPD)
 -pi  --peer-info                          List the current torrent(s)' peers

Connect to a remote linux system's X Session (gnome/xfce/kde etc..)

I will be showing you how to connect to a remote linux desktop from a local PC running Windows. The reason why I am writing this is because, at the place where I work they only run Windows PC's, and I'm sure a lot of you are in the same situation. The basic theory is to open up a local listener on tcp port 5900, then ssh into the remote linux system and forward all traffic for tcp port 5900 to the local machine (tunneled through the ssh connection, so it is secure).

So you have your linux system at home, and from a remote location (e.g. work) you would like to see what is happening on your home system's screen, or run something at home that needs an X session in order for it to work. For example the latest Ubuntu has just come out and you really want to download the .iso using Transmission during the day so that when you get home you can try it out, without having to start the download then and still wait for it to finish downloading before you can try it out.


For this to work you will need the following in place:
  • Home router with port forwarding (need tcp port 22 (ssh) forwarding to your home pc).
  • Firewall rules on your home PC must allow incoming/outgoing tcp ports 22 and 5900.
  • x11vnc package installed on your home PC. (apt-get install x11vnc)
  • PuTTy installed on the local Windows PC.
  • TightVNC viewer on the local Windows PC.
  • The local PC needs to listen on tcp port 5900 so that the ssh connection can tunnel it's X session traffic through to you.
Because each router is different and there are many different firewall frontends on linux, I will not cover how to get the points mentioned above to work, there are many tutorials that cover these points, if you search the web. From here on I will assume that you can successfully connect to your remote linux using ssh.

To setup PuTTY so that it listens locally on tcp port 5900, you need to add a tunnel between the remote system and the local system, as shown in this screenshot:




Now connect to your remote linux system using PuTTy, and with a Command Prompt in Windows confirm that you are listening locally on port 5900, as shown in the screenshot below:


Now in the PuTTy session you must forward all tcp port 5900 traffic from the remote linux system to your local Windows PC as follows:
clive@dogmatix > x11vnc -noxdamage -xkb -geometry 1024x768 -safer -localhost -nopw -once -display :0
14/11/2012 09:52:11 -safer mode:
14/11/2012 09:52:11    vnc_connect=0
14/11/2012 09:52:11    accept_remote_cmds=0
14/11/2012 09:52:11    safe_remote_only=1
14/11/2012 09:52:11    launch_gui=0
14/11/2012 09:52:11 x11vnc version: 0.9.12 lastmod: 2010-09-09  pid: 12521
14/11/2012 09:52:11 Using X display :0
14/11/2012 09:52:11 ------------------ USEFUL INFORMATION ------------------
etc...
etc...
14/11/2012 09:52:11 X display is capable of DPMS.
--------------------------------------------------------
14/11/2012 09:52:11 Default visual ID: 0x21
etc...
etc...
14/11/2012 09:52:11 The X server says there are 10 mouse buttons.
14/11/2012 09:52:11 screen setup finished.
14/11/2012 09:52:11

The VNC desktop is:      localhost:0
PORT=5900

******************************************************************************
Have you tried the x11vnc '-ncache' VNC client-side pixel caching feature yet?

The scheme stores pixel data offscreen on the VNC viewer side for faster
retrieval.  It should work with any VNC viewer.  Try it by running:

    x11vnc -ncache 10 ...

One can also add -ncache_cr for smooth 'copyrect' window motion.
More info: http://www.karlrunge.com/x11vnc/faq.html#faq-client-caching

Note: I have removed a large amount of the output lines from x11vnc command to save space here.


The final step now is to use TightVNC viewer on the local Windows PC to connect to the local tcp port 5900, as shown in the screenshot below:

You should now have a window that shows your remote linux system's desktop where you can run Transmission to get the latest Ubuntu .iso torrent, or run any graphical program on the remote system.


Here are some links for more information and download links for PuTTy and TightVNC (which are freeware products):
https://help.ubuntu.com/community/VNC
http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html
http://www.tightvnc.com/download.php

Please feel free to leave a comment if this helps you, or if you would like to ask me a question.

13 November 2012

Split an image into two individual files (ImageMagick).

This is a follow up article on the image re-size article previously written, and describes how to split an image file into two halves vertically. 

I use this often when I have a scanned music CD cover, which when opened, has two pages and I want to get the two pages as individual image files, using the ImageMagick package in linux. 

Although the example shown below splits the image into two vertical halves, you can obviously split an image into three vertical portions, or split it horizontally into two halves for example.

N.B. The original file is not kept, so if you still want the original file then make a copy of it before running the mogrify command.
  1. clive@dogmatix > cd /tmp
  2. clive@dogmatix > cp /home/clive/Wimpy1983.jpg .
  3. clive@dogmatix > cp Wimpy1983.jpg Wimpy1983-orig.jpg
  4. clive@dogmatix > ll *jpg
  5. -rw-r--r-- 1 clive clive 560927 Nov 13 12:34 Wimpy1983.jpg
  6. -rw-r--r-- 1 clive clive 560927 Nov 13 12:35 Wimpy1983-orig.jpg
  7. clive@dogmatix > identify -format '%wx%h' Wimpy1983.jpg
  8. 1280x944
  9. clive@dogmatix > mogrify -crop 50%x100% +repage Wimpy1983.jpg
  10. clive@dogmatix > ll Wimpy1983-*jpg
  11. -rw-rw-r-- 1 clive clive 308303 Nov 13 12:36 Wimpy1983-0.jpg
  12. -rw-rw-r-- 1 clive clive 302236 Nov 13 12:36 Wimpy1983-1.jpg
  13. -rw-r--r-- 1 clive clive 560927 Nov 13 12:35 Wimpy1983-orig.jpg
  14. clive@dogmatix > identify -format '%wx%h   %f\n' Wimpy1983-[0-1].jpg
  15. 640x944   Wimpy1983-0.jpg
  16. 640x944   Wimpy1983-1.jpg
  17. clive@dogmatix >
The command used on line 9 can be explained as follows:
-crop 50%x%100% means make the first resulting image 50% the width of the original image by 100% the height of the original image.
-repage means that the working canvas of the original image is shifted past the first resulting image and is then saved to the second resulting image.

As you can see from lines 7 & 8 the original file's dimensions are 1280x944 pixels. Then after we run the mogrify command (line 9) we end up with two individual files called "Wimpy1983-0.jpg" and "Wimpy1983-1.jpg". The original file (Wimpy1984.jpg) has now been deleted.

Then when I run the identity command (line 14) on each of those two files they are now both 640 pixels wide and 944 pixels high.

Please leave me any comments if anything is unclear, I always try to keep my notes as simple as possible, so that even linux beginners can understand. I have always found that examples are the best way to learn anything, so I always try and show some examples (some of my every day examples).

09 November 2012

Re-size a bunch of image files (ImageMagick).

Have you ever needed to re-size a large number of image files? To open up each image in Gimp (or any other image editor) and re-size each one individually could take ages, and is really just a pain in the a**. Well there is an easier way thanks to the ImageMagick package in linux, see my previous post about determining an image dimensions (http://sakiwinet.blogspot.com/2012/11/display-image-dimensions-imagemagick.html). 

ImageMagick really is a fantastic package that can do so many things, I suggest you read up on all the things that it can do at http://www.imagemagick.org
Quoted from their site:
ImageMagick® is a software suite to create, edit, compose, or convert bitmap images. It can read and write images in a variety of formats (over 100) including DPX, EXR, GIF, JPEG, JPEG-2000, PDF, PhotoCD, PNG, Postscript, SVG, and TIFF. Use ImageMagick to resize, flip, mirror, rotate, distort, shear and transform images, adjust image colors, apply various special effects, or draw text, lines, polygons, ellipses and Bézier curves.
Mogrify is a part of ImageMagick, and can re-size any image type, full documentation can be found here.  Some good examples of command-line ImageMagick use can be found here, here or here


This is an example I use often to re-size all my cd covers in a folder to a specific width and height that I want:
  1. clive@dogmatix> mogrify -resize 500 *.jpg
NOTE: By default the resize option does a proportional re-size, so it is not necessary to specify the width and height. Here I specified 500px as the new width, so if I has an image with a width of 1000px and the height was 600px, then the image would now have a width of 500px and a height of 300px.

Here is another example:
  1. clive@dogmatix > identify -format '%wx%h' my_picture.jpg
  2. 1190x1700
  3. clive@dogmatix > mogrify -resize 800 my_picture.jpg
  4. clive@dogmatix > identify -format '%wx%h' my_picture.jpg
  5. 800x1143
 

Display image dimensions (ImageMagick).

Identify is part of ImageMagick, and displays various information about picture files. Full documentation can be found here. The various formatting escapes can be found here.
This is a good example on what can be displayed using the special escapes:

  1. clive@dogmatix > identify -format '%f [%wx%h] [%b bytes] [%[EXIF:Model]] [%[EXIF:DateTime]]\n' *JPG
  2. IMG_0121.JPG [640x480] [69165 bytes] [Canon PowerShot S3 IS] [2010:07:10 23:47:34]
  3. IMG_0122.JPG [640x480] [96095 bytes] [Canon PowerShot S3 IS] [2010:07:10 23:47:35]
  4. IMG_0123.JPG [640x480] [82048 bytes] [Canon PowerShot S3 IS] [2010:07:10 23:47:35]
  5. IMG_0124.JPG [640x480] [40431 bytes] [Canon PowerShot S3 IS] [2010:07:10 23:47:36]
This is an example I use often to get the image dimensions (Width x Height):
  1. clive@dogmatix > identify -format '%wx%h' IMG_0364.JPG
  2. 640x480
This is an example of a command I use often to move images into sub directories depending on their dimensions. The sub directories will be automatically created as needed, and the image files will be moved into their specific directories according to their dimensions
N.B. It is important to note that this will NOT handle files with spaces in their names too well (e.g. "This is my file.jpg"), if your file names have spaces in them, then you will need to rename them first before trying this.
  1. clive@dogmatix > pwd
  2. /data/wallpapers
  3. clive@dogmatix > ls
  4. Core_Redux.jpg   Phoenix1_0.jpg  Tangled_by_BJ1.jpg  Thornsofuncontrol1_0.jpg  Vertical_Insanity_v1.jpg  Weldedboxes1_0.jpg
    Grlled_2004.jpg  Science1_0.jpg  The_circle.jpg      Transport_v1.jpg          vienna.jpg
  5. clive@dogmatix > for imgfile in $(identify -format '%wx%h;%f;\n' *jpg); do DIR=$(echo "$imgfile" | awk -F';' '{print $1"_wallpapers"}'); FILE=$(echo "$imgfile" | awk -F';' '{print $2}'); mkdir $DIR; mv "$FILE" $DIR; done
  6. clive@dogmatix > tree
  7. .
  8. +-- 1024x768_wallpapers
  9. ¦   +-- The_circle.jpg
  10. ¦   +-- Transport_v1.jpg
  11. ¦   +-- Vertical_Insanity_v1.jpg
  12. +-- 1280x1024_wallpapers
  13. ¦   +-- Tangled_by_BJ1.jpg
  14. ¦   +-- Thornsofuncontrol1_0.jpg
  15. +-- 1680x1050_wallpapers
  16. ¦   +-- Core_Redux.jpg
  17. ¦   +-- Phoenix1_0.jpg
  18. ¦   +-- Science1_0.jpg
  19. ¦   +-- vienna.jpg
  20. ¦   +-- Weldedboxes1_0.jpg
  21. +-- 1920x1200_wallpapers
  22.     +-- Grlled_2004.jpg
  23.  
  24. 4 directories, 11 files
This is an explanation of what the command on line 5 will do:
  1. for imgfile in $(identify -format '%wx%h;%f;\n' *jpg); do
    This is the loop portion - it will get a list of all .jpg files in the current folder (formatted as
    <width>x<height>;<filename>;) e.g. 1024x768;myfile.jpg
  2. DIR=$(echo "$imgfile" | awk -F';' '{print $1"_wallpapers"}');
    This will create a variable called DIR to hold a special formatted name extracted for each file. From the example above this variable would be: 1024x768_wallpapers.
  3. FILE=$(echo "$imgfile" | awk -F';' '{print $2}');
    This will extract the actual file name from the first point above, so using that example the FILE variable would hold myfile.jpg
  4. mkdir $DIR;
    This will create the folder from point 2 above, i.e. 1024x768_wallpapers
  5. mv "$FILE" $DIR;
    This will now move the file myfile.jpg into the folder 1024x768_wallpapers.
  6. done
    This is the closing portion of the loop. 
If you need any further explanation, please post a comment and I will give you some more detail.
 

08 November 2012

Verify a CD/DVD after burning it from an iso image.

When you have written an .iso image to a cd/dvd you should verify that it was written and closed properly. This can be done with md5sum as shown below.
NOTE:  Although I have actually mounted the .iso image and md5summed that instead of an actual cd, the principal is the same, except you would use "/dev/cdrom" instead of "/dev/loop0".

  1. clive@dogmatix > pwd
  2. /home/clive/temp
  3. clive@dogmatix > mkdir testmount
  4. clive@dogmatix > ll -h My_cd_09.iso                          
  5. -r--r----- 1 clive clive 644M 2012-09-11 13:16 My_cd_09.iso
  6. clive@dogmatix > sudo mount -o loop My_cd_09.iso /home/clive/temp/testmount/
  7. clive@dogmatix > md5sum My_cd_09.iso
  8. cf8b114922fc3fcb0d356825e89b5c49  My_cd_09.iso
  9. clive@dogmatix > dd if=/dev/loop0 2>/dev/null | md5sum
  10. cf8b114922fc3fcb0d356825e89b5c49  -
  11. clive@dogmatix > isoinfo -d -i /dev/loop0   ### Unwanted lines removed below. ###
  12. CD-ROM is in ISO 9660 format
  13. System id: LINUX
  14. Volume id: My cd 09
  15. Application id: GENISOIMAGE ISO 9660/HFS FILESYSTEM CREATOR
  16. Logical block size is: 2048
  17. Volume size is: 329453
  18. Joliet with UCS level 3 found
  19. Rock Ridge signatures version 1 found
  20. clive@dogmatix > dd if=/dev/loop0 bs=2048 count=329453 conv=notrunc,noerror  | md5sum
  21. 329453+0 records in
  22. 329453+0 records out
  23. 674719744 bytes (675 MB) copied, 1.57553 s, 428 MB/s
  24. cf8b114922fc3fcb0d356825e89b5c49  -
  25. clive@dogmatix > dd if=/dev/loop0 bs=2048 count=329453 conv=notrunc,noerror 2>/dev/null | md5sum
  26. cf8b114922fc3fcb0d356825e89b5c49  -
  27. clive@dogmatix > echo "scale=2; (2048 * 329453) / 1024 / 1024" | bc
  28. 643.46
As you can see from the above, the md5sums for the iso file (Line 8) is the same as the md5sums for the cd created (Lines 10, 24 and 26).
You can also see that a straight "dd" command (Line 9) gets the same result as using "dd" with specifying the block size and the number of blocks (Lines 11 - 26).
Lines 25 and 26 are merely there to strip out the unwanted information that was shown in Lines 20 - 24 (It could be redirected to a file instead of /dev/null).
Lines 27 and 28 are just there to show the size of the data on the cd/dvd, obviously there is extra information contained on the cd/dvd that holds the table of contents, data type etc. that makes up the .34 Mb of data difference between the size of the .iso and the cd itself. (Lines 5 and 28)

Delete nested empty folders.

This is how to delete any empty folders that are below a certain point on a linux filesystem. It will not remove any folder that still has files or folders in them. To show how it works I will create a few sub folders under my home folder, and then create some files in a couple of them (to show those folders won't be deleted). Then I will remove only those folders that are empty.

The command used is "find -depth -type d -empty -exec rmdir {} \;". I will briefly explain what this does before actually showing you below.
  •     find is a standard linux/unix command (man find) to learn more.
  •     The -depth tells find to work from the deepest folder upwards i.e if you have the following folder structure "/home/clive/mydir1/mydir2/mydir3/mydir4" it will start at mydir4, then go up to mydir3, then up to mydir2 etc...
  •     The -type d tells find that you are looking only for folders.
  •     The -empty tells find that you are looking for empty folders.
  •     The -exec rmdir {} \; tells find to delete any empty folders it finds.

N.B. If you do not use the -depth option it will work the other way down (mydir1 -> mydir2 -> mydir3 -> mydir4), and will therefore only delete mydir4, because it will see that mydir1, mydir2 and mydir3 are not empty because they contain other folders/files, it will then only delete mydir 4 - as this is the only empty folder.


Now on to the actual example:
clive@dogmatix > cd ~
clive@dogmatix > pwd
/home/clive

clive@dogmatix > mkdir rmdir_example
clive@dogmatix > cd rmdir_example/
clive@dogmatix > mkdir -p subdir{01,02,03}/subdira
clive@dogmatix > mkdir -p subdir01/subdirb
clive@dogmatix > mkdir -p subdir{01,02,03}/subdira/another/stillmore/isempty
clive@dogmatix > mkdir -p subdir01/subdirb/another/empty/directory   
clive@dogmatix > mkdir -p subdir02/subdira/folder/hasfiles
clive@dogmatix > mkdir -p subdir03/empty/folder
clive@dogmatix > echo "This is a file" > subdir01/subdira/another/stillmore/myfile01.txt
clive@dogmatix > echo "This is a file" > subdir02/subdira/folder/hasfiles/myfile02.txt
clive@dogmatix > tree
.
+-- subdir01
¦   +-- subdira
¦   ¦   +-- another
¦   ¦       +-- stillmore
¦   ¦           +-- isempty
¦   ¦           +-- myfile01.txt
¦   +-- subdirb
¦       +-- another
¦           +-- empty
¦               +-- directory
+-- subdir02
¦   +-- subdira
¦       +-- another
¦       ¦   +-- stillmore
¦       ¦       +-- isempty
¦       +-- folder
¦           +-- hasfiles
¦               +-- myfile02.txt
+-- subdir03
    +-- empty
    ¦   +-- folder
    +-- subdira
        +-- another
            +-- stillmore
                +-- isempty
23 directories, 2 files


clive@dogmatix > find -depth -type d -empty -exec rmdir {} \;
clive@dogmatix > tree
.
+-- subdir01
¦   +-- subdira
¦       +-- another
¦           +-- stillmore
¦               +-- myfile01.txt
+-- subdir02
    +-- subdira
        +-- folder
            +-- hasfiles
                +-- myfile02.txt
8 directories, 2 files



As you can see, because the stillmore and hasfiles folders have files in them they were not deleted, all other empty folders have been deleted.

Bash email attachments (with body text)

I had a few issues when trying to send attachments (with an email body text too) from linux using mailx. It always seems to work with Gmail, but hardly ever with Outlook 2010.  It used to work before, when I had Outlook 2003 at work. 

I do not have any other email accounts that I can use for testing, for example Hotmail or Yahoo, so I can't tell if any of these have the same issues as Outlook, but this is how I eventually got it to work with both Gmail and Outlook 2010 on the receiving ends. 

  • clive@dogmatix > (uuecode file1 file1.txt; uuencode file2 file2.txt; cat emailbody.txt) | mailx -s 'Gmail OK, Outlook NO' user@gmail.com,user1@outlook.email 
  • ### So to get this to work I did this. ### 
  • clive@dogmatix > sudo apt-get install uudeview 
  • clive@dogmatix > uuenview -m user@gmail.com,user1@outlook.email -s "Subject uuenview" -a someimage.jpg -a myattach2.txt < myemailbody.txt