<?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>Tadek's Blog &#187; Shell</title>
	<atom:link href="http://tadek.pietraszek.org/blog/category/tipstricks/shell/feed/" rel="self" type="application/rss+xml" />
	<link>http://tadek.pietraszek.org/blog</link>
	<description>Some random notes about computers, security, cool links and others.</description>
	<lastBuildDate>Fri, 12 Dec 2008 22:49:29 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>sed and awk &#8211; my two old friends</title>
		<link>http://tadek.pietraszek.org/blog/2007/09/30/sed-and-awk-my-two-old-friends/</link>
		<comments>http://tadek.pietraszek.org/blog/2007/09/30/sed-and-awk-my-two-old-friends/#comments</comments>
		<pubDate>Sun, 30 Sep 2007 21:35:48 +0000</pubDate>
		<dc:creator>tadekp</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Shell]]></category>
		<category><![CDATA[Tips&Tricks]]></category>

		<guid isPermaLink="false">http://tadek.pietraszek.org/blog/2007/09/30/sed-and-awk-my-two-old-friends/</guid>
		<description><![CDATA[Writing some shell scripts I needed to do some a little fancier variable substitution than the standard shell offers. The heavyweight solution would be to write a perl one-liner, but this is, well&#8230;, heavyweight?  

Here&#8217;s a couple of patterns I used:

--parameter=$(sed -re 's/ /,/g' -e 's/(^&#124;,)/\1file:/g' ]]></description>
			<content:encoded><![CDATA[<p>Writing some shell scripts I needed to do some a little fancier variable substitution than the standard shell offers. The heavyweight solution would be to write a perl one-liner, but this is, well&#8230;, heavyweight? <img src='http://tadek.pietraszek.org/blog/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>

<p>Here&#8217;s a couple of patterns I used:</p>

<ul><li><code>--parameter=$(sed -re 's/ /,/g' -e 's/(^|,)/\1file:/g' <<<$INPUT)</code> - replaces spaces with commas and prepends <code>file</code> to every file.</li>
<li><code>--parameter=$(awk '{split($0, a, /@/); printf "%s-?????-of-%05d", a[1], a[2]} <<<$INPUT)'<code></li> - replaces <code>file@5</code> with <code>file-?????-of-00005</code></li>
<li><code>--parameter=$(awk '{sub(/.*:/, ""); print $0}' <<<$INPUT) </code> - removes everything before the colon.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://tadek.pietraszek.org/blog/2007/09/30/sed-and-awk-my-two-old-friends/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Parsing parameters in bash &#8211; a getopt template</title>
		<link>http://tadek.pietraszek.org/blog/2007/08/16/parsing-parameters-in-bash-a-getopt-template/</link>
		<comments>http://tadek.pietraszek.org/blog/2007/08/16/parsing-parameters-in-bash-a-getopt-template/#comments</comments>
		<pubDate>Thu, 16 Aug 2007 13:48:28 +0000</pubDate>
		<dc:creator>tadekp</dc:creator>
				<category><![CDATA[Shell]]></category>
		<category><![CDATA[Tips&Tricks]]></category>

		<guid isPermaLink="false">http://tadek.pietraszek.org/blog/2007/08/16/parsing-parameters-in-bash-a-getopt-template/</guid>
		<description><![CDATA[Writing some bash scripts that parse command lines, I wrote this handy template with getopt. It is easy to apply even for simplest scripts.


OPTION_SPEC="help,flag1,flag2_params:"
PARSED_OPTIONS=$(getopt -n "$0" -a -o h --long $OPTION_SPEC -- "$@")
OPTIONS_RET=$?
eval set -- "$PARSED_OPTIONS"

Parsing error or no flags

if [ $OPTIONS_RET -ne 0 ] &#124;&#124; [ $# -le 0 ]; then
  usage;
  [...]]]></description>
			<content:encoded><![CDATA[<p>Writing some bash scripts that parse command lines, I wrote this handy template with <code>getopt</code>. It is easy to apply even for simplest scripts.</p>

<p><pre>
OPTION_SPEC="help,flag1,flag2_params:"
PARSED_OPTIONS=$(getopt -n "$0" -a -o h --long $OPTION_SPEC -- "$@")
OPTIONS_RET=$?
eval set -- "$PARSED_OPTIONS"</p>

<h1>Parsing error or no flags</h1>

<p>if [ $OPTIONS_RET -ne 0 ] || [ $# -le 0 ]; then
  usage;
  die;
fi</p>

<p>while [ $# -ge 1 ]; do
  case $1 in
    --help | -h )  usage; die;;
    --flag1 )  FLAG1=1;;
    --flag2_params )  shift; FLAG2_PARAMS="$1";;
    -- ) shift;;
    * ) echo "ERROR: unknown flag $1"; usage; die;;
  esac
  shift
done
</pre></p>

<p>No more unannotated <code>$n</code>s in my scripts!</p>
]]></content:encoded>
			<wfw:commentRss>http://tadek.pietraszek.org/blog/2007/08/16/parsing-parameters-in-bash-a-getopt-template/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Date of yesterday in bash?</title>
		<link>http://tadek.pietraszek.org/blog/2007/08/16/date-of-yesterday-in-bash/</link>
		<comments>http://tadek.pietraszek.org/blog/2007/08/16/date-of-yesterday-in-bash/#comments</comments>
		<pubDate>Thu, 16 Aug 2007 13:40:06 +0000</pubDate>
		<dc:creator>tadekp</dc:creator>
				<category><![CDATA[Shell]]></category>
		<category><![CDATA[Tips&Tricks]]></category>

		<guid isPermaLink="false">http://tadek.pietraszek.org/blog/2007/08/16/date-of-yesterday-in-bash/</guid>
		<description><![CDATA[I recently had to hack a small shell script that would read files in a directory structure generated based on the date, something like 2007/08/16. The trick was that the script would look at yesterday&#8217;s file or files generated a few days ago.

A quick search on info and here&#8217;s the magic command

FILE="...$(date -d 'yesterday' +%Y/%m/%d)"


Interestingly, [...]]]></description>
			<content:encoded><![CDATA[<p>I recently had to hack a small shell script that would read files in a directory structure generated based on the date, something like 2007/08/16. The trick was that the script would look at yesterday&#8217;s file or files generated a few days ago.</p>

<p>A quick search on info and here&#8217;s the magic command
<pre>
FILE="...$(date -d 'yesterday' +%Y/%m/%d)"
</pre></p>

<p>Interestingly, you can also use things like <code>3 days ago</code>, <code>next Monday</code>, <code>2 months</code> etc.
Cool!</p>
]]></content:encoded>
			<wfw:commentRss>http://tadek.pietraszek.org/blog/2007/08/16/date-of-yesterday-in-bash/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Shell variable assigment &#8211; a stupid bug</title>
		<link>http://tadek.pietraszek.org/blog/2007/01/19/shell-variable-assigment-a-stupid-bug/</link>
		<comments>http://tadek.pietraszek.org/blog/2007/01/19/shell-variable-assigment-a-stupid-bug/#comments</comments>
		<pubDate>Fri, 19 Jan 2007 11:06:22 +0000</pubDate>
		<dc:creator>tadekp</dc:creator>
				<category><![CDATA[Shell]]></category>
		<category><![CDATA[Tips&Tricks]]></category>

		<guid isPermaLink="false">http://tadek.pietraszek.org/blog/2007/01/19/shell-variable-assigment-a-stupid-bug/</guid>
		<description><![CDATA[I recently made a really stupid mistake. I wanted to do a simple variable assignment and run a command. What I did was the following:

VAR=value command $VAR


Obviously, this doesn&#8217;t work! As this is a single command, the shell does variable expansion before the assignment takes place, so the variable is null (or whatever it was [...]]]></description>
			<content:encoded><![CDATA[<p>I recently made a really stupid mistake. I wanted to do a simple variable assignment and run a command. What I did was the following:</p>

<pre><code>VAR=value command $VAR
</code></pre>

<p>Obviously, this doesn&#8217;t work! As this is a single command, the shell does variable expansion <strong>before</strong> the assignment takes place, so the variable is null (or whatever it was before). Obviously, the variable is set correctly within the command&#8217;s execution environment, but it&#8217;s too late then <img src='http://tadek.pietraszek.org/blog/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>

<p>What I should have done in this case was:</p>

<pre><code>VAR=value; command $VAR
</code></pre>

<p>Sadly, the command did not complain about my mistake and I only realized it after a lost night of computation. Phew!</p>
]]></content:encoded>
			<wfw:commentRss>http://tadek.pietraszek.org/blog/2007/01/19/shell-variable-assigment-a-stupid-bug/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Iterating through an array in Bash</title>
		<link>http://tadek.pietraszek.org/blog/2006/11/23/iterating-through-an-array-in-bash/</link>
		<comments>http://tadek.pietraszek.org/blog/2006/11/23/iterating-through-an-array-in-bash/#comments</comments>
		<pubDate>Thu, 23 Nov 2006 14:18:55 +0000</pubDate>
		<dc:creator>tadekp</dc:creator>
				<category><![CDATA[Shell]]></category>
		<category><![CDATA[Tips&Tricks]]></category>

		<guid isPermaLink="false">http://tadek.pietraszek.org/blog/2006/11/23/iterating-through-an-array-in-bash/</guid>
		<description><![CDATA[I don&#8217;t like programming in bash but it does make some things very simple. Unfortunately, it is not obvious how to do some simple things like iterating through an array  

Assuming that we have an array ITEMS=( a b c d ), we can use a ${ITEMS[@]} construct to iterate through all the elements [...]]]></description>
			<content:encoded><![CDATA[<p>I don&#8217;t like programming in bash but it does make some things very simple. Unfortunately, it is not obvious how to do some simple things like iterating through an array <img src='http://tadek.pietraszek.org/blog/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>

<p>Assuming that we have an array <code>ITEMS=( a b c d )</code>, we can use a <code>${ITEMS[@]}</code> construct to iterate through all the elements in a for loop:</p>

<pre><code>ITEMS=( a b c d )
for ITEM in ${ITEMS[@]}; do
    echo $ITEM
done
</code></pre>

<p>BTW: I found this pattern <a href="http://www.tech-recipes.com/bourne_shell_scripting_tips636.html">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://tadek.pietraszek.org/blog/2006/11/23/iterating-through-an-array-in-bash/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Background processes in shell scripts</title>
		<link>http://tadek.pietraszek.org/blog/2006/11/03/background-processes-in-shell-scripts/</link>
		<comments>http://tadek.pietraszek.org/blog/2006/11/03/background-processes-in-shell-scripts/#comments</comments>
		<pubDate>Fri, 03 Nov 2006 15:26:33 +0000</pubDate>
		<dc:creator>tadekp</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Shell]]></category>
		<category><![CDATA[Tips&Tricks]]></category>

		<guid isPermaLink="false">http://tadek.pietraszek.org/blog/2006/11/03/background-processes-in-shell-scripts/</guid>
		<description><![CDATA[I used it some time ago, but have already forgotten how I did it and had to reinvent the wheel. Here it goes.

You sometimes need to start a background process in shell, which can die right away, in which case you want to know about it. Situations in which it is useful include init.d scripts, [...]]]></description>
			<content:encoded><![CDATA[<p>I used it some time ago, but have already forgotten how I did it and had to reinvent the wheel. Here it goes.</p>

<p>You sometimes need to start a background process in shell, which can die right away, in which case you want to know about it. Situations in which it is useful include init.d scripts, running some background processes&#8230; Here are two useful shell functions:</p>

<pre><code>function pidactive () {
    #sends a signal which checks if the process is active (doesn't kill anything)
    kill -0 $1 2&gt; /dev/null
    return
}

function pidkill () {
    echo "killing pid"
    kill $1 || return
    #adjust depending how long it takes to die gracefully
    sleep 1
    if pidactive $1; then
        #escalating
        kill -9 $1
    fi  
}
</code></pre>

<p>What I do in the script is the following:</p>

<pre><code>&lt;command&gt; &amp;
PID=$!
#wait for the process to startup or die...
sleep 5
if ! pidactive $PID; then
    wait $PID
    die "Command failed with $?"
fi

...
#kill the process before exiting
pidkill $PID
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://tadek.pietraszek.org/blog/2006/11/03/background-processes-in-shell-scripts/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Messing up with command-line arguments in Bash: $*, $@, &quot;$*&quot;, &quot;$@&quot;,&#8230;</title>
		<link>http://tadek.pietraszek.org/blog/2006/01/05/messing-up-with-command-line-arguments-in-bash/</link>
		<comments>http://tadek.pietraszek.org/blog/2006/01/05/messing-up-with-command-line-arguments-in-bash/#comments</comments>
		<pubDate>Thu, 05 Jan 2006 08:18:14 +0000</pubDate>
		<dc:creator>tadekp</dc:creator>
				<category><![CDATA[Personal]]></category>
		<category><![CDATA[Shell]]></category>
		<category><![CDATA[Tips&Tricks]]></category>

		<guid isPermaLink="false">http://tadek.pietraszek.org/blog/?p=230</guid>
		<description><![CDATA[It&#8217;s stupid, but it took me a good hour to figure this out, so maybe I&#8217;m not the only one&#8230;

I&#8217;ve recently had a problem with command-line arguments in my Java program. The problem was that command line arguments containing spaces were parsed incorrectly, i.e. chopped into individual arguments. My initial suspect was gnu.Getopt package I [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s stupid, but it took me a good hour to figure this out, so maybe I&#8217;m not the only one&#8230;</p>

<p>I&#8217;ve recently had a problem with command-line arguments in my Java program. The problem was that command line arguments containing spaces were parsed incorrectly, i.e. chopped into individual arguments. My initial suspect was <a href="http://http://www.urbanophile.com/arenn/hacking/getopt/Package-gnu.getopt.html">gnu.Getopt</a> package I use for parsing arguments, but as it turned out I was wrong.</p>

<p>The real culprit was a shell wrapper script I used to wrap my java code. The code was the following:</p>

<pre><code>java &lt;some parameters&gt; &lt;programm.class&gt; $@
</code></pre>

<p>See the problem? I didn&#8217;t. You need quotes around <code>"$@"</code> in which case the parameter gets expanded to: <code>"$1" "$2" "$3"...</code> With no quotes the shell expands it to <code>$1 $2 $3</code>, hence all parameters containing spaces get chopped (also globbing takes place in this case).</p>

<p>BTW: There&#8217;s also <code>"$*"</code> which is used to combine all parameters into a single one, i.e, <code>"$*"</code> expands to <code>"$1c$2c$3c...</code>, where <code>c</code> is <code>$IFS</code> (or space). Here it&#8217;s also important to have it enclosed in quotes.</p>
]]></content:encoded>
			<wfw:commentRss>http://tadek.pietraszek.org/blog/2006/01/05/messing-up-with-command-line-arguments-in-bash/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Template replacement with M4</title>
		<link>http://tadek.pietraszek.org/blog/2005/10/20/template-replacement-with-m4/</link>
		<comments>http://tadek.pietraszek.org/blog/2005/10/20/template-replacement-with-m4/#comments</comments>
		<pubDate>Thu, 20 Oct 2005 15:13:24 +0000</pubDate>
		<dc:creator>tadekp</dc:creator>
				<category><![CDATA[Personal]]></category>
		<category><![CDATA[Shell]]></category>
		<category><![CDATA[Tips&Tricks]]></category>

		<guid isPermaLink="false">http://tadek.pietraszek.org/blog/?p=178</guid>
		<description><![CDATA[Trying to automate something I had to run a program with a configuration file modified for each run. The easy way to do this is to create a template file and generate the correct configuration file with variable substitution for each run.

This task could be done in a number of ways (sed, perl, shell),  [...]]]></description>
			<content:encoded><![CDATA[<p>Trying to automate something I had to run a program with a configuration file modified for each run. The easy way to do this is to create a template file and generate the correct configuration file with variable substitution for each run.</p>

<p>This task could be done in a number of ways (sed, perl, shell),  to name a few, but as Diego pointed out there is already a tool for this m4. It&#8217;s a bit archaic and has odd syntax (think strange quotes or strangely named built-in macros), but it&#8217;s ideal for my simple task.</p>

<p>At the end I run it like this:
<code>
m4 -Dparam1=value1 -Dparam2=value2 &lt;infile&gt; &gt; &lt;outfile&gt;
</code></p>

<p>As simple as that. Thanks Diego!
BTW: some pointers to M4: <a href="http://www.gnu.org/software/m4/manual/index.html">manual</a> and <a href="http://www.linuxjournal.com/article/5594">linux journal article</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://tadek.pietraszek.org/blog/2005/10/20/template-replacement-with-m4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ssh_config file</title>
		<link>http://tadek.pietraszek.org/blog/2005/10/04/ssh_config-file/</link>
		<comments>http://tadek.pietraszek.org/blog/2005/10/04/ssh_config-file/#comments</comments>
		<pubDate>Tue, 04 Oct 2005 08:00:09 +0000</pubDate>
		<dc:creator>tadekp</dc:creator>
				<category><![CDATA[Hacking]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Shell]]></category>

		<guid isPermaLink="false">http://tadek.pietraszek.org/blog/2005/10/04/ssh_config-file/</guid>
		<description><![CDATA[Recently learned about .ssh/config file, in which you can customize parameters used for connecting to different hosts. The complete syntax is described in &#8220;man ssh_config&#8221;, here is just a few highlights:

Host &#60;short hostname&#62;
Hostname &#60;full hostname&#62;
Port port
User user
LocalForward 54320 localhost:5432
Dynamic Forward 9050
]]></description>
			<content:encoded><![CDATA[<p>Recently learned about .ssh/config file, in which you can customize parameters used for connecting to different hosts. The complete syntax is described in &#8220;man ssh_config&#8221;, here is just a few highlights:</p>

<p>Host &lt;short hostname&gt;
Hostname &lt;full hostname&gt;
Port port
User user
LocalForward 54320 localhost:5432
Dynamic Forward 9050</p>
]]></content:encoded>
			<wfw:commentRss>http://tadek.pietraszek.org/blog/2005/10/04/ssh_config-file/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adding your ssh key to &#8220;authorized_keys&#8221;</title>
		<link>http://tadek.pietraszek.org/blog/2005/09/29/adding-your-ssh-key-to-authorized_keys/</link>
		<comments>http://tadek.pietraszek.org/blog/2005/09/29/adding-your-ssh-key-to-authorized_keys/#comments</comments>
		<pubDate>Thu, 29 Sep 2005 08:25:12 +0000</pubDate>
		<dc:creator>tadekp</dc:creator>
				<category><![CDATA[Security]]></category>
		<category><![CDATA[Shell]]></category>

		<guid isPermaLink="false">http://tadek.pietraszek.org/blog/2005/09/29/adding-your-ssh-key-to-authorized_keys/</guid>
		<description><![CDATA[As simple as that:
cat id_*.pub &#124; ssh servername &#8220;cat &#62;&#62; ~/.ssh/authorized_keys&#8221;
]]></description>
			<content:encoded><![CDATA[<p>As simple as that:
cat id_*.pub | ssh servername &#8220;cat &gt;&gt; ~/.ssh/authorized_keys&#8221;</p>
]]></content:encoded>
			<wfw:commentRss>http://tadek.pietraszek.org/blog/2005/09/29/adding-your-ssh-key-to-authorized_keys/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
