1000umbrellas.com

Michael Descy's Personal Website

Browsing Posts tagged cron

This is definitely a newb-level topic, but I think it is important to understand how to redirect output from your command-line processes. This becomes important because regularly-schedule processes run via cron will email you whatever the output is. This is completely confusing when you first encounter it, and the complete solution isn’t exactly obvious.

StdOut

When you run a process on the command line, it will probably output right back to the terminal. This is StdOut, or “standard output.” In scripts and cron jobs, however, you might want to redirect output to a file instead, so you can review the output later.

You can redirect output to a new file by using the “>” operator.

$ ls -l > ~/directory_listing.txt

You can redirect output and append it to a file by using the “>>” operator. This method will create a file if it does not already exist.

StdErr

Error messages are output to StdErr, which by default is redirected to StdOut. This is why you see normal messages and error messages in the terminal when you run a command. StdErr does not have to be redirected to StdOut, however, and has to be treated separately from StdOut if you are redirecting StdOut.

/dev/null and 2>&1

Redirecting output to /del/null sends it nowhere, which effectively gets rid of it. You often see output redirected to /dev/null, followed by a cryptic construction 2>&1. Here is what that construction means:

In the command
$ tvnamer --batch > ~/log/tvnamer.log 2>&1

  • 2 refers to StdErr; and
  • &1 refers to the first redirection argument; in this case, /log/tvnamer.log.

My example uses a normal file, instead of /dev/null, to show that you can use  2>&1 with any old file.

This construction is very useful if you find that your cron jobs are sending you emails, even after you redirected their output to log files. Cron will automatically email the owner of the cron job any output (on StdOut) from them. This is why you sometimes are notified that you have emails when you log into your system. Effective redirection will eliminate these emails.

Transmission-daemon does not automatically remove completed torrents. I created a script to do so, and I run it via a cron job (under my own user ID) on my Ubuntu 10.04 Lucid Lynx Server.

This script uses command line utility transmission-remote (which is installed when you install the transmission-daemon package) to check on the progress of all active torrents. Torrents that have completed downloading and seeding will have a status of “Stopped” and a (download) percent done of “100%”. This script will identify such torrents, move their downloaded files to a different directory, and will remove the torrent from transmission-daemon.

This script depends on using a seeding ratio to stop your torrents from seeding after a certain percentage has been seeded. If your torrents seed indefinitely, transmission-daemon will never stop them, and this script will not know that the torrent is completed.

Note that transmission-daemon has a built-in option to store incomplete downloads in one folder, and move them, when the download completes, to another folder. This script is meant to pick the torrents up afterward, and move them from the download folder to somewhere more permanent. If you just want to remove completed torrents, comment out the line “transmission-remote --torrent $TORRENTID --netrc $NETRC --move $MOVEDIR“.

Script: movecompletedtorrents

This script is a modified version of the one found at http://forum.qnap.com/viewtopic.php?f=45&t=25553.

#!/bin/sh

# script to check for complete torrents in transmission folder, then stop and move them

MOVEDIR=/home/user/media
NETRC=/home/user/.netrc

# get torrent list from transmission-remote list
# delete first / last line of output
# remove leading spaces
# get first field from each line
TORRENTLIST=`transmission-remote --list --netrc $NETRC | sed -e '1d;$d;s/^ *//' | cut -s -d " " -f1`

# for each torrent in the list
for TORRENTID in $TORRENTLIST
do
  echo "* * * * * Operations on torrent ID $TORRENTID starting. * * * * *"

  # check if torrent was started
  STARTED=`transmission-remote --torrent $TORRENTID --info --netrc $NETRC | grep "Id: $TORRENTID"`
  # echo " - started state = $STARTED" # debug message

  # check if torrent download is completed
  COMPLETED=`transmission-remote --torrent $TORRENTID --info --netrc $NETRC | grep "Percent Done: 100%"`
  # echo " - completed state = $COMPLETED" # debug message

  # check torrent's current state is "Stopped"
  STOPPED=`transmission-remote --torrent $TORRENTID --info --netrc $NETRC | grep "State: Stopped"`
  # echo " - torrent stopped seeding = $STOPPED" # debug message

  # if the torrent is "Stopped" after downloading 100% and seeding, move the files and remove the torrent from Transmission
  if [ "$STARTED" != "" ] && [ "$COMPLETED" != "" ] && [ "$STOPPED" != "" ]; then
    echo "Torrent #$TORRENTID is completed."
    echo "Moving downloaded file(s) to $MOVEDIR."
    transmission-remote --torrent $TORRENTID --netrc $NETRC --move $MOVEDIR
    echo "Removing torrent from list."
    transmission-remote --torrent $TORRENTID --netrc $NETRC --remove
  else
    echo "Torrent #$TORRENTID is not completed. Ignoring."
  fi

  echo "* * * * * Operations on torrent ID $TORRENTID completed. * * * * *"

done

Scheduling

To run this script every hour, save the script somewhere (/home/user/bin), grant yourself permission to execute it…

$ chmod u+x ~/bin/movecompletedtorrents

…edit your crontab settings…

$ crontab -e

…and add the following line.

@hourly /home/user/bin/movecompletedtorrents

TVNamer is a Python application that will automatically renames TV episode files to a clean, consistent, and useful format. If you rip your DVDs, or download torrents (for shame!) on your server, you might find the “tvnamer” Python script very useful. I am running this on my Ubuntu 10.04 Lucid Lynx server right now, and I am very happy with it.

How It Works

I thought I would have to write a complex regular expressions script to reformat the junky file names I end up with. TVNamer does this behind the scenes, and goes one very useful step beyond that: it compares the file names you pass it to the TVDB database, via the TVDB API, to ensure you get a good match. The TVDB is an open database that stores the show titles, episode numbers, and so on, for nearly any show you can think of. As long as your file name contains the series title (in some format or another), and the season and episode numbers (S01E01, for example), TVNamer will rename them nicely.

Installation

TVNamer requires Python 2.6. If you don’t have it, install it as follows:

apt-get install python2.6

The tvnamer program is simple to install on Ubuntu (I run Ubuntu Server 10.04 Lucid Lynx) via Python’s “easy_install” command. (This probably works on all platforms that Python runs on, too.)

$ sudo easy_install tvnamer

Running Manually

You can run tvnamer on one file…

$ tvnamer seriesname.s01e01.crap.you.do.not.care.about.in.the.file.name.mkv

…or on an entire folder.

$ tvnamer ~/media/tv/

It can also recursively run on any folder tree that you pass to it. I have found this to be the default behavior, though, so the –recursive argument does not appear to be necessary. (I tend to use the argument in my cron jobs, in case future versions of tvnamer start to require it.)

$ tvnamer --recursive ~/media/tv/

Note that when you run the program as written above, it will run in interactive mode. For each file you pass to it, you will have to verify the series name and verify that you wish to rename the file.

Running Automatically on a Schedule

Fortunately, you can also run tvnamer in batch mode. Batch mode will not prompt the user at all, and will automatically select the most-relevant series title and will automatically rename each file. This is the mode to run tvnamer via a cron job or a shell script.

Batch mode:

$ tvnamer --batch ~/media/tv/

To schedule a cron job to run this script hourly, run:

$ crontab -e

and then add the following line to your crontab:

@hourly tvnamer --batch --recursive ~/media/tv/

and finally save the crontab file.