<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Michael Schuerig &#187; Shell</title>
	<atom:link href="http://www.schuerig.de/michael/blog/index.php/category/shell/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.schuerig.de/michael/blog</link>
	<description>Sentenced to making sense</description>
	<lastBuildDate>Tue, 06 Sep 2011 07:21:06 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Bash completion for script/generate</title>
		<link>http://www.schuerig.de/michael/blog/index.php/2007/11/18/script-generate-bash-completion/</link>
		<comments>http://www.schuerig.de/michael/blog/index.php/2007/11/18/script-generate-bash-completion/#comments</comments>
		<pubDate>Sun, 18 Nov 2007 00:45:50 +0000</pubDate>
		<dc:creator>michael</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[Shell]]></category>

		<guid isPermaLink="false">http://schuerig.de/michael/blog/index.php/2007/11/18/script-generate-bash-completion/</guid>
		<description><![CDATA[The Rails generator script/generate knows pretty well what things it can generate. In fact, it knows much better than I do. So, I think it could really give me some help when I&#8217;m typing along on the command line. If you save the snippet below as /etc/bash_completion.d/generate you can enjoy this help, too. _generate() { [...]]]></description>
			<content:encoded><![CDATA[<p>The Rails generator <tt>script/generate</tt> knows pretty well what things it can generate. In fact, it knows much better than I do. So, I think it could really give me some help when I&#8217;m typing along on the command line.</p>
<p>If you save the snippet below as <tt>/etc/bash_completion.d/generate</tt> you can enjoy this help, too.</p>
<p><code>
<pre>
_generate()
{
  local cur

  COMPREPLY=()
  cur=${COMP_WORDS[COMP_CWORD]}

  if [ ! -d "$PWD/script" ]; then
    return 0
  fi

  if [ $COMP_CWORD == 1 ] &#038;&#038; [[ "$cur" == -* ]]; then
    COMPREPLY=( $( compgen -W '-h -v\\
      --help --version'\\
      -- $cur ))
    return 0
  fi

  if [ $COMP_CWORD == 2 ] &#038;&#038; [[ "$cur" == -* ]]; then
    COMPREPLY=( $( compgen -W '-p -f -s -q -t -c\\
      --pretend --force --skip --quiet --backtrace --svn'\\
      -- $cur ))
    return 0
  fi

  COMPREPLY=( $(script/generate --help | \\
    awk -F ': ' '/^  (Plugins|Rubygems|Builtin|User):/ { gsub(/, */, "\n", $2); print $2 }' | \\
    command grep "^$cur" \\
  ))
}

complete -F _generate $default generate
</pre>
<p></code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.schuerig.de/michael/blog/index.php/2007/11/18/script-generate-bash-completion/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Bash Completion for the gem Command</title>
		<link>http://www.schuerig.de/michael/blog/index.php/2007/02/24/gem-bash-completion/</link>
		<comments>http://www.schuerig.de/michael/blog/index.php/2007/02/24/gem-bash-completion/#comments</comments>
		<pubDate>Sat, 24 Feb 2007 01:41:39 +0000</pubDate>
		<dc:creator>michael</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Shell]]></category>

		<guid isPermaLink="false">http://schuerig.de/michael/blog/index.php/2007/02/24/gem-bash-completion/</guid>
		<description><![CDATA[The gem command is the command line user interface to the RubyGems system for managing Ruby packages. This command has a few sub-commands itself and a long list of options that differ per sub-command. Remembering and typing them can be tedious, but thankfully, if you are using the bash command shell, it can help with [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://rubygems.org/read/book/2"><code>gem</code></a> command is the command line user interface to the <a href="http://rubygems.org/">RubyGems</a> system for managing Ruby packages.</p>
<p>This command has a few sub-commands itself and a long list of options that differ per sub-command. Remembering and typing them can be tedious, but thankfully, if you are using the <code>bash</code> command shell, it can help with this task. It only has to be told <em>how</em>.</p>
<p>I&#8217;ve packaged the <em>how</em> in <a href="http://www.schuerig.de/michael/ruby/gem.bash_completion.old">this file</a>. Copy it to <code>/etc/bash_completion.d</code> and hope that your <code>bash</code> installation picks it up the next time you start a shell.</p>
<p>On Debian/Linux system that&#8217;s just how it works. If this does not work on your particular version of Linux or Unix, you&#8217;ll have to look up how completions are handled on your system.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.schuerig.de/michael/blog/index.php/2007/02/24/gem-bash-completion/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Timestamping files from commandline and Konqueror</title>
		<link>http://www.schuerig.de/michael/blog/index.php/2007/02/05/timestamp-servicemenu/</link>
		<comments>http://www.schuerig.de/michael/blog/index.php/2007/02/05/timestamp-servicemenu/#comments</comments>
		<pubDate>Mon, 05 Feb 2007 15:20:27 +0000</pubDate>
		<dc:creator>michael</dc:creator>
				<category><![CDATA[KDE]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Shell]]></category>

		<guid isPermaLink="false">http://schuerig.de/michael/blog/?p=15</guid>
		<description><![CDATA[In order to keep multiple versions of a file, I sometimes add a timestamp to the filename. Doing this by hand is tedious and error-prone, but this chore can be automated by a small shell script. /usr/local/bin/timestamp #! /bin/sh for oldname ; do ts=`date +'%Y%m%d%H%M' --reference="$oldname"` newname=`echo $oldname &#124; sed -nre "s/^(\\.?)([^\\.]+)(-[[:digit:]]{12})(\\..*)\$/\\1\\2-$ts\\4/p"` if [ -z [...]]]></description>
			<content:encoded><![CDATA[<p>In order to keep multiple versions of a file, I sometimes add a timestamp to the filename. Doing this by hand is tedious and error-prone, but this chore can be automated by a small shell script.</p>
<p><code>/usr/local/bin/timestamp</code></p>
<p><code>
<pre>
#! /bin/sh

for oldname ; do
  ts=`date +'%Y%m%d%H%M' --reference="$oldname"`

  newname=`echo $oldname | sed -nre "s/^(\\.?)([^\\.]+)(-[[:digit:]]{12})(\\..*)\$/\\1\\2-$ts\\4/p"`
  if [ -z "$newname" ]; then
    newname=`echo $oldname | sed -nre "s/^(\\.?)([^\\.]+)(\\..*)\$/\\1\\2-$ts\\3/p"`
  fi
  if [ -z "$newname" ]; then
    newname=`echo $oldname | sed -nre "s/^(\\.?)([^\\.]+)(-[[:digit:]]{12})\$/\\1\\2-$ts/p"`
  fi
  if [ -z "$newname" ]; then
    newname=`echo $oldname | sed -nre "s/^(\\.?)([^\\.]+)\$/\\1\\2-$ts/p"`
  fi

  if [ -f "$newname" ]; then
    if [ "$newname" != "$oldname" ]; then
      echo "Can't rename $oldname to $newname: file already exists."
    fi
  else
    echo mv "$oldname" "$newname"
    mv "$oldname" "$newname"
  fi
done
</pre>
<p></code></p>
<p>As I&#8217;m using KDE as my desktop, I like to have the timestamping integrated. Fortunately, it&#8217;s easy.</p>
<p><code>~/.kde/share/apps/konqueror/servicemenus</code></p>
<p><code>
<pre>
Actions=timestamp
ServiceTypes=all/all

[Desktop Action timestamp]
Exec=/usr/local/bin/timestamp %u
Icon=clock
Name=Timestamp
</pre>
<p></code></p>
<p>See <a href="http://developer.kde.org/documentation/tutorials/dot/servicemenus.html">Creating Konqueror Service Menus</a> for a general introduction.</p>
<h4>Update, 2007-02-06</h4>
<p>I&#8217;ve updated the script to insert the timestamp before all the first extension and to also work with filename starting with a &#8216;<code>.</code>&#8216;.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.schuerig.de/michael/blog/index.php/2007/02/05/timestamp-servicemenu/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RSnapshotting on your own schedule</title>
		<link>http://www.schuerig.de/michael/blog/index.php/2006/11/26/rsnapshotting-on-your-own-schedule/</link>
		<comments>http://www.schuerig.de/michael/blog/index.php/2006/11/26/rsnapshotting-on-your-own-schedule/#comments</comments>
		<pubDate>Sun, 26 Nov 2006 01:36:48 +0000</pubDate>
		<dc:creator>michael</dc:creator>
				<category><![CDATA[Administration]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Shell]]></category>

		<guid isPermaLink="false">http://schuerig.de/michael/blog/?p=4</guid>
		<description><![CDATA[I&#8217;m using rsnapshot for making regular backups of my Linux box. Neither the computer, nor the external backup disk is running all the time, therefore it would not work to simply have cron run rsnapshot at fixed times. I want a little more flexibility than that. When the computer is off, there&#8217;s no point in [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m using <a href="http://www.rsnapshot.org/">rsnapshot</a> for making regular backups of my Linux box. Neither the computer, nor the external backup disk is running all the time, therefore it would not work to simply have <tt>cron</tt> run <tt>rsnapshot</tt> at fixed times.</p>
<p>I want a little more flexibility than that. When the computer is off, there&#8217;s no point in making a snapshot. Fine, there&#8217;s no work left to handle that case. But in cases where the computer is running, but the backup disk is not, I want it to be recorded that something should have been done&#8211;if only the disk had been on. Then, next time the disk is running again, the recorded (queued) tasks are executed in order.</p>
<p>As there are multiple processes involved, for enqueueing tasks and for dequeueing them, and as the later can take some time, there&#8217;s a bit of mutual exclusing involved. Luckily, Debian GNU/Linux provides very useful helper programs in the <tt>lockfile-progs</tt> package.</p>
<p><strong>/usr/local/lib/snapshot/dequeue</strong><br />
<code></p>
<pre>
#! /bin/sh

QUEUEFILE=/var/lib/snapshot/queue
LOCKFILE=/var/lib/snapshot/LCK..queue

lockfile-create $LOCKFILE
if ! test -f $QUEUEFILE || ! grep -Fqs -- "$*" $QUEUEFILE ; then
  echo $* >> $QUEUEFILE
fi
lockfile-remove $LOCKFILE
</pre>
<p></code></p>
<p><strong>/usr/local/lib/snapshot/dequeue</strong><br />
<code></p>
<pre>
#! /bin/sh

SNAPDIR=/var/cache/rsnapshot
QUEUEFILE=/var/lib/snapshot/queue
LOCKFILE=/var/lib/snapshot/LCK..queue
PIDFILE=/var/run/snapshot.pid

test -f $PIDFILE &#038;&#038; exit 0
test -s $QUEUEFILE || exit 0

echo $$ > $PIDFILE

was_mounted=0
if egrep -qs "\\B$SNAPDIR\\b" /etc/mtab; then
  was_mounted=1
  mount -o remount,rw $SNAPDIR 2> /dev/null
else
  mount -o rw $SNAPDIR 2> /dev/null
fi

if [ $? != 0 ]; then
  rm -f $PIDFILE
  exit 0
fi

cleanup ()
{
  if [ $was_mounted == 1 ]; then
    mount -o remount,ro $SNAPDIR
  else
    umount $SNAPDIR
  fi
  rm -f $PIDFILE
}

trap "cleanup" EXIT TERM INT

while true; do
  lockfile-create $LOCKFILE
  if [ -f $QUEUEFILE ] ; then
    ARGS=`head -n1 $QUEUEFILE`
    sed -i '1d' $QUEUEFILE
  fi
  lockfile-remove $LOCKFILE

  if [ -n "$ARGS" ]; then
    nice rsnapshot $ARGS
  else
    break
  fi

done

exit 0
</pre>
<p></code></p>
<p>Things are tied together by several <tt>cron</tt> jobs that define when things should, if possible, happen. Of course, this is highly dependent on the individual <tt>rsnapshot</tt> configuration.</p>
<p><strong>/etc/cron.d/snapshot</strong><br />
<code></p>
<pre>
7   12,20       * * *   root    /usr/local/lib/snapshot/enqueue hourly
11  20          * * *   root    /usr/local/lib/snapshot/enqueue daily
13  20          * * 1   root    /usr/local/lib/snapshot/enqueue weekly
17  20          1 * *   root    /usr/local/lib/snapshot/enqueue monthly
*/5  *          * * *   root    /usr/local/lib/snapshot/dequeue
</pre>
<p></code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.schuerig.de/michael/blog/index.php/2006/11/26/rsnapshotting-on-your-own-schedule/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

