<?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>Linux Certification &#187; Important for LPI 117-101</title>
	<atom:link href="http://lpilinux.com/LDAP%20Protocol/important-for-lpi-117-101/feed" rel="self" type="application/rss+xml" />
	<link>http://lpilinux.com</link>
	<description>LPI Certification - What, Why, and How</description>
	<lastBuildDate>Thu, 01 Sep 2011 13:53:33 +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>Cropping Multiple Images in the Same Way</title>
		<link>http://lpilinux.com/cropping-multiple-images-in-the-same-way.html</link>
		<comments>http://lpilinux.com/cropping-multiple-images-in-the-same-way.html#comments</comments>
		<pubDate>Sat, 03 Jul 2010 12:21:17 +0000</pubDate>
		<dc:creator>lpilinuxblog</dc:creator>
				<category><![CDATA[Important for LPI 117-101]]></category>

		<guid isPermaLink="false">http://lpilinux.com/cropping-multiple-images-in-the-same-way.html</guid>
		<description><![CDATA[&#8216;Getting the right cropping values using GIMP In 5 steps: Where to find the cropping values 1. Open up GIMP. 2. Open one of the images in GIMP. 3. Using the Rectangle Select Tool (hotkey &#8220;R&#8221;), select the area you &#8230; <a href="http://lpilinux.com/cropping-multiple-images-in-the-same-way.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Flpilinux.com%2Fcropping-multiple-images-in-the-same-way.html"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Flpilinux.com%2Fcropping-multiple-images-in-the-same-way.html&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>&#8216;Getting the right cropping values using GIMP</p>
<p>In 5 steps:<br />
Where to find the cropping values<br />
1. Open up GIMP.<br />
2. Open one of the images in GIMP.<br />
3. Using the Rectangle Select Tool (hotkey &#8220;R&#8221;), select the area you want to be cropped.<br />
4. Note the X, Y, Width and Height values GIMP gives you (have a look at the picture, you can find them in the GIMP main window).<br />
5. Close GIMP (or leave it open if you plan to use it again soon).</p>
<p>We now have the values we need to tell the mogrify utility what to crop. Let&#8217;s go on and write a line that&#8217;ll execute mogrify in such a way that it&#8217;ll crop all our images!<br />
Cropping the images</p>
<p>Now we&#8217;ll start working in the terminal. Open up your favourite one and cd to the directory where the images are located. Note that I strongly recommend having only the images that are to be cropped in the directory, nothing more. It saves you a lot of trouble. Well then, let&#8217;s start with the mogrify command. The syntax for cropping is as follows:</p>
<p>    [rechosen@localhost ~]$ mogrify -crop {Width}x{Height}+{X}+{Y} image.png</p>
<p>Now don&#8217;t be scared, the {Width}, {Height} and so on simply are the places where you should put the values you got from GIMP! Note that I use a png file as an example, while mogrify is able to handle over 100 image file types. You don&#8217;t have to use png files with it. Anyway, if I&#8217;d fill in the values from the screenshot, the mogrify command would look like this:</p>
<p>    [rechosen@localhost ~]$ mogrify -crop 643&#215;393+7+83 image.png</p>
<p>The logic behind this system is the following: crop an area of 643 by 393 pixels, starting at 7 pixels from the left and 83 pixels from the top of the image. Got it? Ok then. The above command would overwrite image.png with a cropped version. But this still manipulates just a single image. The easiest way to make mogrify modify all images is just this:</p>
<p>    [rechosen@localhost ~]$ mogrify -crop 643&#215;393+7+83 *.png</p>
<p>The asterisk makes bash fill in all png files in the current directory, and mogrify will handle them all happily. After a (hopefully short) wait, all the images will have been cropped. If you want to crop images of an other format, just change &#8220;*.png&#8221; to, for example, &#8220;*.jpg&#8221; or &#8220;*.gif&#8221;.</p>
<p>You might want to give the cropped images other names, so that the original images will not be overwritten and it will be clear which images have been cropped and which haven&#8217;t. This is more complex, but hey, we&#8217;re working on Linux! Everything is possible if you take the time to write it.<br />
Renaming the cropped images</p>
<p>In order to give the cropped images other names, we&#8217;ll use a bash loop. This time, we&#8217;ll use the convert utility. It is from the same family as mogrify, but it makes it easier for us to output to an other filename. I won&#8217;t explain the whole loop, as most of it is bash knowledge, but I will tell you which things you can/should alter to get the right results. There are loops for two cases, just pick the one of which you like the file naming the most.</p>
<p>    * Case 1: You want the output files to be named like this: originalfile.png => cropped_originalfile.png (again, you can insert any of the over 100 supported image formats here, I just like png). The loop should be like this:</p>
<p>          [rechosen@localhost ~]$ for file in *.png; do convert -crop {Width}x{Height}+{X}+{Y} $file cropped_$file; done</p>
<p>      You should replace &#8220;png&#8221; with the extension you want (think of jpg, gif, png (of course) and so on), and the &#8220;{Width}&#8221;, &#8220;{Height}&#8221; etc with the values you got from GIMP. You may also replace &#8220;cropped_&#8221; with any prefix you like.<br />
    * Case 2: You want the output files to be named like this: originalfile.png => originalfile_cropped.png (or originalfile.jpg => originalfile_cropped.jpg, you name it). In that case, you should use the following loop:</p>
<p>          [rechosen@localhost ~]$ for file in *.png; do convert -crop {Width}x{Height}+{X}+{Y} $file ${file%.png}_cropped.png; done</p>
<p>      Again, replace &#8220;png&#8221; with the extension you want (watch it, there are 3 instances of it) and the &#8220;{Width}&#8221;, &#8220;{Height}&#8221; etc with the values you got from GIMP. You can also replace &#8220;_cropped&#8221; with any suffix you like.</p>
<p>      Note that you can, in this case, easily modify the output format: if you want to output the cropped images in jpg format, you can just replace the third instance of &#8220;png&#8221; with &#8220;jpg&#8221;, no matter what format your input files are. The convert utility will detect it and change the image format automatically. &#8216; </p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Flpilinux.com%2Fcropping-multiple-images-in-the-same-way.html&amp;title=Cropping%20Multiple%20Images%20in%20the%20Same%20Way"><img src="http://lpilinux.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://lpilinux.com/cropping-multiple-images-in-the-same-way.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating an mpeg with mencoder that plays on Windows Media Player</title>
		<link>http://lpilinux.com/creating-an-mpeg-with-mencoder-that-plays-on-windows-media-player.html</link>
		<comments>http://lpilinux.com/creating-an-mpeg-with-mencoder-that-plays-on-windows-media-player.html#comments</comments>
		<pubDate>Sat, 03 Jul 2010 12:20:14 +0000</pubDate>
		<dc:creator>lpilinuxblog</dc:creator>
				<category><![CDATA[Important for LPI 117-101]]></category>

		<guid isPermaLink="false">http://lpilinux.com/creating-an-mpeg-with-mencoder-that-plays-on-windows-media-player.html</guid>
		<description><![CDATA[&#8216;Let&#8217;s have a look at a rather simple mencoder command that should create a WMP-compatible MPEG file: [rechosen@localhost ~]$ mencoder -oac lavc -ovc lavc -lavcopts acodec=mp2:vcodec=mpeg2video:mbd=1:vbitrate=1800 -of mpeg -o Replace &#8220; &#8221; with the video source (for example a file &#8230; <a href="http://lpilinux.com/creating-an-mpeg-with-mencoder-that-plays-on-windows-media-player.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Flpilinux.com%2Fcreating-an-mpeg-with-mencoder-that-plays-on-windows-media-player.html"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Flpilinux.com%2Fcreating-an-mpeg-with-mencoder-that-plays-on-windows-media-player.html&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>&#8216;Let&#8217;s have a look at a rather simple mencoder command that should create a WMP-compatible MPEG file:</p>
<p>    [rechosen@localhost ~]$ mencoder<br />
<input /> -oac lavc -ovc lavc -lavcopts acodec=mp2:vcodec=mpeg2video:mbd=1:vbitrate=1800 -of mpeg -o <outputfile></p>
<p>Replace &#8220;<br />
<input />&#8221; with the video source (for example a file or a DVD scene) and &#8220;</outputfile><outputfile>&#8221; with the file you want the output to be written to (e.g. &#8220;samplemovie.mpg&#8221; or &#8220;dvdbackup.mpeg&#8221;). You can also replace the value after &#8220;vbitrate=&#8221; with a higher or lower bitrate, depending on the desired quality of the outputfile (you could also leave it away entirely, but it will then default to 800, which is quite low and therefore pretty much only suitable for very low resolution movies).</p>
<p>Note that the above example will try to encode the movie at the same resolution and fps as the source. However, this does not always work correctly and also isn&#8217;t always what you want. Furthermore, the above example doesn&#8217;t use two-pass encoding. Two-pass encoding is useful because it results in a higher quality outputfile with about the same size (it needs to read the source twice, though).<br />
A more feature-rich example</p>
<p>The next example features rescaling (adapting the resolution), specifies a framerate for the outputfile and encodes in two passes.</p>
<p>    [rechosen@localhost ~]$ for i in {1,2}; do mencoder<br />
<input /> -oac lavc -ovc lavc -lavcopts acodec=mp2:vcodec=mpeg2video:mbd=1:vpass=$i:vbitrate=1800 -of mpeg -ofps 25 -vf scale=640:480 -o </outputfile><outputfile>; done</p>
<p>Replace &#8220;<br />
<input />&#8221; with any source that can be read twice (a file or a DVD scene) and &#8220;</outputfile><outputfile>&#8221; with the file you want the encoded data to be written to. You can alter the values after &#8220;-ofps=&#8221; and &#8220;-vf scale=&#8221; to change the framerate and the resolution of the outputfile, respectively (and of course you can alter the vbitrate again, too).</p>
<p>One more handy trick: you can set only the width of the encoded video and let mencoder determine the height, keeping the right aspect ratio:</p>
<p>    [rechosen@localhost ~]$ for i in {1,2}; do mencoder<br />
<input /> -oac lavc -ovc lavc -lavcopts acodec=mp2:vcodec=mpeg2video:mbd=1:vpass=$i:vbitrate=1800 -of mpeg -ofps 25 -vf scale -zoom -xy 640 -o </outputfile><outputfile>; done</p>
<p>Again, replace &#8220;<br />
<input />&#8221; with any source that can be read twice (a file or a DVD scene) and &#8220;</outputfile><outputfile>&#8221; with the file you want the encoded data to be written to. You can alter the value after &#8220;-ofps=&#8221; again to change the framerate of the outputted data, and after &#8220;-zoom -xy &#8221; is the value to change if you want a different width (note that values less than or equal to 8 will be interpreted as scaling factors, not as the width of the outputted video).&#8217;</outputfile> </p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Flpilinux.com%2Fcreating-an-mpeg-with-mencoder-that-plays-on-windows-media-player.html&amp;title=Creating%20an%20mpeg%20with%20mencoder%20that%20plays%20on%20Windows%20Media%20Player"><img src="http://lpilinux.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://lpilinux.com/creating-an-mpeg-with-mencoder-that-plays-on-windows-media-player.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>If Condition in Bash Script</title>
		<link>http://lpilinux.com/if-condition-in-bash-script.html</link>
		<comments>http://lpilinux.com/if-condition-in-bash-script.html#comments</comments>
		<pubDate>Sat, 03 Jul 2010 12:19:12 +0000</pubDate>
		<dc:creator>lpilinuxblog</dc:creator>
				<category><![CDATA[Important for LPI 117-101]]></category>

		<guid isPermaLink="false">http://lpilinux.com/if-condition-in-bash-script.html</guid>
		<description><![CDATA[&#8216;If you use bash for scripting you will undoubtedly have to use conditions a lot, for example for an if &#8230; then construct or a while loop. The syntax of these conditions can seem a bit daunting to learn and &#8230; <a href="http://lpilinux.com/if-condition-in-bash-script.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Flpilinux.com%2Fif-condition-in-bash-script.html"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Flpilinux.com%2Fif-condition-in-bash-script.html&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>&#8216;If you use bash for scripting you will undoubtedly have to use conditions a lot, for example for an if &#8230; then construct or a while loop. The syntax of these conditions can seem a bit daunting to learn and use. This tutorial aims to help the reader understanding conditions in bash, and provides a comprehensive list of the possibilities. A small amount of general shell knowledge is assumed.</p>
<p>Difficulty: Basic &#8211; Medium<br />
Introduction</p>
<p>Bash features a lot of built-in checks and comparisons, coming in quite handy in many situations. You&#8217;ve probably seen if statements like the following before:</p>
<p>    if [ $foo -ge 3 ]; then</p>
<p>The condition in this example is essentially a command. It may sound strange, but surrounding a comparison with square brackets is the same as using the built-in test command, like this:</p>
<p>    if test $foo -ge 3; then</p>
<p>If $foo is Greater then or Equal to 3, the block after &#8216;then&#8217; will be executed. If you always wondered why bash tends to use -ge or -eq instead of >= or ==, it&#8217;s because this condition type originates from a command, where -ge and -eq are options.<br />
And that&#8217;s what if does essentially, checking the exit status of a command. I&#8217;ll explain that in more detail further in the tutorial.<br />
There also are built-in checks that are more specific to shells. What<br />
about this one?</p>
<p>    if [ -f regularfile ]; then</p>
<p>The above condition is true if the file &#8216;regularfile&#8217; exists and<br />
is a regular file. A regular file means that it&#8217;s not a block or<br />
character device, or a directory. This way, you can make sure a usable<br />
file exists before doing something with it. You can even check if a<br />
file is readable!</p>
<p>    if [ -r readablefile]; then</p>
<p>The above condition is true if the file &#8216;readablefile&#8217; exists and is readable. Easy, isn&#8217;t it?<br />
The syntax of an if statement (a short explanation)</p>
<p>The basic syntax of an if &#8230; then statement is like this:</p>
<p>    if <condition>; then<br />
    <commands><br />
    fi</p>
<p>The condition is, depending on its type, surrounded by certain<br />
brackets, eg. [ ]. You can read about the different types further on<br />
in the tutorial. You can add commands to be executed when the condition is false using the else keyword, and use the elif (elseif) keyword to execute commands on another condition if the primary condition is false. The else keyword always comes last. Example:</p>
<p>    if [ -r somefile ]; then<br />
    content=$(cat somefile)<br />
    elif [ -f somefile ]; then<br />
    echo &#8220;The file &#8216;somefile&#8217; exists but is not readable to the script.&#8221;<br />
    else<br />
    echo &#8220;The file &#8216;somefile&#8217; does not exist.&#8221;<br />
    fi</p>
<p>A short explanation of the example: first we check if the file somefile is readable (&#8220;if [ -r somefile ]&#8220;). If so, we read it into a variable. If not, we check if it actually exists (&#8220;elif [ -f somefile ]&#8220;). If that&#8217;s true, we report that it exists but isn&#8217;t readable (if it was, we would have read the content). If the file doesn&#8217;t exist, we report so, too. The condition at elif is only executed if the condition at if was false. The commands belonging to else are only executed if both conditions are false.<br />
The basic rules of conditions</p>
<p>When you start writing and using your own conditions, there are some rules you should know to prevent getting errors that are hard to trace. Here follow three important ones:</p>
<p>   1. Always keep spaces between the brackets and the actual check/comparison. The following won&#8217;t work:</p>
<p>          if [$foo -ge 3]; then</p>
<p>      Bash will complain about a &#8220;missing `]&#8217;&#8221;.<br />
   2. Always terminate the line before putting a new keyword like &#8220;then&#8221;. The words if, then, else, elif and fi are shell keywords, meaning that they cannot share the same line. Put a &#8220;;&#8221; between the previous statement and the keyword or place the keyword on the start of a new line. Bash will throw errors like &#8220;syntax error near unexpected token `fi&#8217;&#8221; if you don&#8217;t.<br />
   3. It is a good habit to quote string variables if you use them in conditions, because otherwise they are likely to give trouble if they contain<br />
      spaces and/or newlines. By quoting I mean:</p>
<p>          if [ "$stringvar" == "tux" ]; then</p>
<p>      There are a few cases in which you should not<br />
      quote, but they are rare. You will see one of them further on in the tutorial. </p>
<p>Also, there are two things that may be useful to know:</p>
<p>   1. You can invert a condition by putting an &#8220;!&#8221; in front of it. Example:</p>
<p>          if [ ! -f regularfile ]; then</p>
<p>      Be sure to place the &#8220;!&#8221; inside the brackets!<br />
   2. You can combine conditions by using certain operators. For the single-bracket syntax that we&#8217;ve been using so far, you can use &#8220;-a&#8221; for and and &#8220;-o&#8221; for or. Example:</p>
<p>          if [ $foo -ge 3 -a $foo -lt 10 ]; then</p>
<p>      The above condition will return true if $foo contains an integer greater than or equal to 3 and Less Than 10. You can read more about these combining expressions at the respective condition syntaxes. </p>
<p>And, one more basic thing: don&#8217;t forget that conditions can also be used in other statements, like while and until. It is outside the scope of this tutorial to explain those, but you can read about them at the Bash Guide for Beginners.</p>
<p>Anyway, I&#8217;ve only shown you conditions between single brackets so far. There are more syntaxes, however, as you will read in the next section.<br />
Different condition syntaxes</p>
<p>Bash features different syntaxes for conditions. I will list the three of them:<br />
1. Single-bracket syntax</p>
<p>This is the condition syntax you have already seen in the previous paragraphs; it&#8217;s the oldest supported syntax. It supports three types of conditions:</p>
<p>    * File-based conditions<br />
          o Allows different kinds of checks on a file. Example:</p>
<p>                if [ -L symboliclink ]; then</p>
<p>            The above condition is true if the file &#8216;symboliclink&#8217; exists and is a symbolic link. For more file-based conditions see the table below.<br />
    * String-based conditions<br />
          o Allows checks on a string and comparing of strings. Example one:</p>
<p>                if [ -z "$emptystring" ]; then</p>
<p>            The above condition is true if $emptystring is an empty string or an uninitialized variable. Example two:</p>
<p>                if [ "$stringvar1" == "cheese" ]; then</p>
<p>            The above condition is true if $stringvar1 contains just the string &#8220;cheese&#8221;. For more string-based conditions see the table below.<br />
    * Arithmetic (number-based) conditions<br />
          o Allows comparing integer numbers. Example:</p>
<p>                if [ $num -lt 1 ]; then</p>
<p>            The above condition returns true if $num is less than 1. For more arithmetic conditions see the table below. </p>
<p>2. Double-bracket syntax</p>
<p>You may have encountered conditions enclosed in double square brackets already, which look like this:</p>
<p>    if [[ "$stringvar" == *string* ]]; then</p>
<p>The double-bracket syntax serves as an enhanced version of the single-bracket syntax; it mainly has the same features, but also some important differences with it. I will list them here:</p>
<p>    * The first difference can be seen in the above example; when comparing strings, the double-bracket syntax features shell globbing. This means that an asterisk (&#8220;*&#8221;) will expand to literally anything, just as you probably know from normal command-line usage. Therefore, if $stringvar contains the phrase &#8220;string&#8221; anywhere, the condition will return true. Other forms of shell globbing are allowed, too. If you&#8217;d like to match both &#8220;String&#8221; and &#8220;string&#8221;, you could use the following syntax:</p>
<p>          if [[ "$stringvar" == *[sS]tring* ]]; then</p>
<p>      Note that only general shell globbing is allowed. Bash-specific things like {1..4} or {foo,bar} will not work. Also note that the globbing will not work if you quote the right string. In this case you should leave it unquoted.<br />
    * The second difference is that word splitting is prevented. Therefore, you could omit placing quotes around string variables and use a condition like the following without problems:</p>
<p>          if [[ $stringvarwithspaces != foo ]]; then</p>
<p>      Nevertheless, the quoting string variables remains a good habit, so I recommend just to keep doing it.<br />
    * The third difference consists of not expanding filenames. I will illustrate this difference using two examples, starting with the old single-bracket situation:</p>
<p>          if [ -a *.sh ]; then</p>
<p>      The above condition will return true if there is one single file in the working directory that has a .sh extension. If there are none, it will return false. If there are several .sh files, bash will throw an error and stop executing the script. This is because *.sh is expanded to the files in the working directory. Using double brackets prevents this:</p>
<p>          if [[ -a *.sh ]]; then</p>
<p>      The above condition will return true only if there is a file in the working directory called &#8220;*.sh&#8221;, no matter what other .sh files exist. The asterisk is taken literally, because the double-bracket syntax does not expand filenames.<br />
    * The fourth difference is the addition of more generally known combining expressions, or, more specific, the operators &#8220;&#038;&#038;&#8221; and &#8220;||&#8221;. Example:</p>
<p>          if [[ $num -eq 3 &#038;&#038; "$stringvar" == foo ]]; then</p>
<p>      The above condition returns true if $num is equal to 3 and $stringvar is equal to &#8220;foo&#8221;. The -a and -o known from the single-bracket syntax is supported, too.</p>
<p>      Note that the and operator has precedence over the or operator, meaning that &#8220;&#038;&#038;&#8221; or &#8220;-a&#8221; will be evaluated before &#8220;||&#8221; or &#8220;-o&#8221;.<br />
    * The fifth difference is that the double-bracket syntax allows regex pattern matching using the &#8220;=~&#8221; operator. See the table for more information.</p>
<p>3. Double-parenthesis syntax</p>
<p>There also is another syntax for arithmetic (number-based) conditions, most likely adopted from the Korn shell:</p>
<p>    if (( $num < = 5 )); then</p>
<p>The above condition is true if $num is less than or equal to 5. This syntax may seem more familiar to programmers. It features all the 'normal' operators, like "==", "<" and ">=&#8221;. It supports the &#8220;&#038;&#038;&#8221; and &#8220;||&#8221; combining expressions (but not the -a and -o ones!). It is equivalent to the built-in let command.<br />
Table of conditions</p>
<p>The following table list the condition possibilities for both the single- and the double-bracket syntax. Save a single exception, the examples are given in single-bracket syntax, but are always compatible with double brackets.<br />
 1. File-based conditions:<br />
Condition 	True if 	Example/explanation<br />
[ -a existingfile ] 	file &#8216;existingfile&#8217; exists. 	if [ -a tmp.tmp ]; then<br />
    rm -f tmp.tmp # Make sure we&#8217;re not bothered by an old temporary file<br />
fi<br />
[ -b blockspecialfile ] 	file &#8216;blockspecialfile&#8217; exists and is block special. 	Block special files are special kernel files found in /dev, mainly used for ATA devices like hard disks, cd-roms and floppy disks.</p>
<p>if [ -b /dev/fd0 ]; then<br />
    dd if=floppy.img of=/dev/fd0 # Write an image to a floppy<br />
fi<br />
[ -c characterspecialfile ] 	file &#8216;characterspecialfile&#8217; exists and is character special. 	Character special files are special kernel files found in /dev, used for all kinds of purposes (audio hardware, tty&#8217;s, but also /dev/null).</p>
<p>if [ -c /dev/dsp ]; then<br />
    cat raw.wav > /dev/dsp # This actually works for certain raw wav files<br />
fi<br />
[ -d directory ] 	file &#8216;directory&#8217; exists and is a directory. 	In UNIX-style, directories are a special kind of file.</p>
<p>if [ -d ~/.kde ]; then<br />
    echo &#8220;You seem to be a kde user.&#8221;<br />
fi<br />
[ -e existingfile ] 	file &#8216;existingfile&#8217; exists. 	(same as -a, see that entry for an example)<br />
[ -f regularfile ] 	file &#8216;regularfile&#8217; exists and is a regular file. 	A regular file is neither a block or character special file nor a directory.</p>
<p>if [ -f ~/.bashrc ]; then<br />
    source ~/.bashrc<br />
fi<br />
[ -g sgidfile ] 	file &#8216;sgidfile&#8217; exists and is set-group-ID. 	When the SGID-bit is set on a directory, all files created in that directory will inherit the group of the directory.</p>
<p>if [ -g . ]; then<br />
   echo &#8220;Created files are inheriting the group &#8216;$(ls -ld . | awk &#8216;{ print $4 }&#8217;)&#8217; from the working directory.&#8221;<br />
fi<br />
[ -G fileownedbyeffectivegroup ] 	file &#8216;fileownedbyeffectivegroup&#8217; exists and is owned by the effective group ID. 	The effective group id is the primary group id of the executing user.</p>
<p>if [ ! -G file ]; then # An exclamation mark inverts the outcome of the condition following it<br />
   chgrp $(id -g) file # Change the group if it&#8217;s not the effective one<br />
fi<br />
[ -h symboliclink ] 	file &#8216;symboliclink&#8217; exists and is a symbolic link. 	if [ -h $pathtofile ]; then<br />
    pathtofile=$(readlink -e $pathtofile) # Make sure $pathtofile contains the actual file and not a symlink to it<br />
fi<br />
[ -k stickyfile ] 	file &#8216;stickyfile&#8217; exists and has its sticky bit set. 	The sticky bit has got quite a history, but is now used to prevent world-writable directories from having their contents deletable by anyone.</p>
<p>if [ ! -k /tmp ]; then # An exclamation mark inverts the outcome of the condition following it<br />
    echo &#8220;Warning! Anyone can delete and/or rename your files in /tmp!&#8221;<br />
fi<br />
[ -L symboliclink ] 	file &#8216;symboliclink&#8217; exists and is a symbolic link. 	(same as -h, see that entry for an example)<br />
[ -N modifiedsincelastread ] 	file &#8216;modifiedsincelastread&#8217; exists and was modified after the last read. 	if [ -N /etc/crontab ]; then<br />
    killall -HUP crond # SIGHUP makes crond reread all crontabs<br />
fi<br />
[ -O fileownedbyeffectiveuser ] 	file &#8216;fileownedbyeffectiveuser&#8217; exists and is owned by the user executing the script. 	if [ -O file ]; then<br />
    chmod 600 file # Makes the file private, which is a bad idea if you don&#8217;t own it<br />
fi<br />
[ -p namedpipe ] 	file &#8216;namedpipe&#8217; exists and is a named pipe. 	A named pipe is a file in /dev/fd/ that can be read just once. See my bash tutorial for a case in which it&#8217;s used.</p>
<p>if [ -p $file ]; then<br />
    cp $file tmp.tmp # Make sure we&#8217;ll be able to read<br />
    file=&#8221;tmp.tmp&#8221;    # the file as many times as we like<br />
fi<br />
[ -r readablefile ] 	file &#8216;readablefile&#8217; exists and is readable to the script. 	if [-r file ]; then<br />
    content=$(cat file) # Set $content to the content of the file<br />
fi<br />
[ -s nonemptyfile ] 	file &#8216;nonemptyfile&#8217; exists and has a size of more than 0 bytes. 	if [ -s logfile ]; then<br />
    gzip logfile    # Backup the old logfile<br />
    touch logfile # before creating a fresh one.<br />
fi<br />
[ -S socket ] 	file &#8216;socket&#8217; exists and is a socket. 	A socket file is used for inter-process communication, and features an interface similar to a network connection.</p>
<p>if [ -S /var/lib/mysql/mysql.sock ]; then<br />
    mysql &#8211;socket=/var/lib/mysql/mysql.sock # See this MySQL tip<br />
fi<br />
[ -t openterminal ] 	file descriptor &#8216;openterminal&#8217; exists and refers to an open terminal. 	Virtually everything is done using files on Linux/UNIX, and the terminal is no exception.</p>
<p>if [ -t /dev/pts/3 ]; then<br />
    echo -e &#8220;\nHello there. Message from terminal $(tty) to you.&#8221; > /dev/pts/3 # Anyone using that terminal will actually see this message!<br />
fi<br />
[ -u suidfile ] 	file &#8216;suidfile&#8217; exists and is set-user-ID. 	Setting the suid-bit on a file causes execution of that file to be done with the credentials of the owner of the file, not of the executing user.</p>
<p>if [ -u executable ]; then<br />
    echo &#8220;Running program executable as user $(ls -l executable | awk &#8216;{ print $3 }&#8217;).&#8221;<br />
fi<br />
[ -w writeablefile ] 	file &#8216;writeablefile&#8217; exists and is writeable to the script. 	if [ -w /dev/hda ]; then<br />
    grub-install /dev/hda<br />
fi<br />
[ -x executablefile ] 	file &#8216;executablefile&#8217; exists and is executable for the script. 	Note that the execute permission on a directory means that it&#8217;s searchable (you can see which files it contains).</p>
<p>if [ -x /root ]; then<br />
    echo &#8220;You can view the contents of the /root directory.&#8221;<br />
fi<br />
[ newerfile -nt olderfile ] 	file &#8216;newerfile&#8217; was changed more recently than &#8216;olderfile&#8217;, or if &#8216;newerfile&#8217; exists and &#8216;olderfile&#8217; doesn&#8217;t. 	if [ story.txt1 -nt story.txt ]; then<br />
    echo &#8220;story.txt1 is newer than story.txt; I suggest continuing with the former.&#8221;<br />
fi<br />
[ olderfile -ot newerfile ] 	file &#8216;olderfile&#8217; was changed longer ago than &#8216;newerfile&#8217;, or if &#8216;newerfile&#8217; exists and &#8216;olderfile&#8217; doesn&#8217;t. 	if [ /mnt/remote/remotefile -ot localfile ]; then<br />
    cp -f localfile /mnt/remote/remotefile # Make sure the remote location has the newest version of the file, too<br />
fi<br />
[ same -ef file ] 	file &#8216;same&#8217; and file &#8216;file&#8217; refer to the same device/inode number. 	if [ /dev/cdrom -ef /dev/dvd ]; then<br />
    echo &#8220;Your primary cd drive appears to read dvd&#8217;s, too.&#8221;<br />
fi<br />
 2. String-based conditions:<br />
Condition 	True if 	Example/explanation<br />
[ STRING1 == STRING2 ] 	STRING1 is equal to STRING2. 	if [ "$1" == "moo" ]; then<br />
    echo $cow # Ever tried executing &#8216;apt-get moo&#8217;?<br />
fi</p>
<p>Note: you can also use a single &#8220;=&#8221; instead of a double one.<br />
[ STRING1 != STRING2 ] 	STRING1 is not equal to STRING2. 	if [ "$userinput" != "$password" ]; then<br />
    echo &#8220;Access denied! Wrong password!&#8221;<br />
    exit 1 # Stops script execution right here<br />
fi<br />
[ STRING1 \> STRING2 ] 	STRING1 sorts after STRING2 in the current locale (lexographically). 	The backslash before the angle bracket is there because the bracket needs to be escaped to be interpreted correctly. As an example we have a basic bubble sort:</p>
<p>(Don&#8217;t feel ashamed if you don&#8217;t understand this, it is a more complex example)</p>
<p>array=( linux tutorial blog )<br />
swaps=1<br />
while (( swaps > 0 )); do</p>
<p>swaps=0<br />
    for (( i=0; i < (( ${#array[@]} - 1 )) ; i++ )); do<br />
        if [ "${array[$i]}" \> &#8220;${array[$(( i + 1 ))]}&#8221; ]; then # Here is the sorting condition<br />
            tempstring=${array[$i]}<br />
            array[$i]=${array[$(( i + 1 ))]}<br />
            array[$(( i + 1 ))]=$tempstring<br />
            (( swaps=swaps + 1 ))<br />
        fi<br />
    done<br />
done<br />
echo ${array[@]} # Returns &#8220;blog linux tutorial&#8221;<br />
[ STRING1 \< STRING2 ] 	STRING1 sorts before STRING2 in the current locale (lexographically).<br />
[ -n NONEMPTYSTRING ] 	NONEMPTYSTRING has a length of more than zero. 	This condition only accepts valid strings, so be sure to quote anything you give to it.</p>
<p>if [ -n "$userinput" ]; then<br />
    userinput=parse($userinput) # Only parse if the user actually gave some input.<br />
fi</p>
<p>Note that you can also omit the &#8220;-n&#8221;, as brackets with just a string in it behave the same.<br />
[ -z EMPTYSTRING ] 	EMPTYSTRING is an empty string. 	This condition also accepts non-string input, like an uninitialized variable:</p>
<p>if [ -z $uninitializedvar ]; then<br />
    uninitializedvar=&#8221;initialized&#8221; # -z returns true on an uninitialized variable, so we initialize it here.<br />
fi<br />
Double-bracket syntax only:<br />
[[ STRING1 =~ REGEXPATTERN ]] 	STRING1 matches REGEXPATTERN. 	If you are familiar with Regular Expressions, you can use this conditions to perform a regex match.</p>
<p>if [[ "$email" =~ "\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}\b&#8221; ]]; then<br />
    echo &#8220;\$email contains a valid e-mail address.&#8221;<br />
fi<br />
 3. Arithmetic (number-based) conditions:<br />
Condition 	True if 	Example/explanation<br />
[ NUM1 -eq NUM2 ] 	NUM1 is EQual to NUM2. 	These conditions only accept integer numbers. Strings will be converted to integer numbers, if possible. Some random examples:</p>
<p>if [ $? -eq 0 ]; then # $? returns the exit status of the previous command<br />
    echo &#8220;Previous command ran succesfully.&#8221;<br />
fi</p>
<p>if [ $(ps -p $pid -o ni=) -ne $(nice) ]; then<br />
    echo &#8220;Process $pid is running with a non-default nice value&#8221;<br />
fi</p>
<p>if [ $num -lt 0 ]; then<br />
    echo &#8220;Negative numbers not allowed; exiting&#8230;&#8221;<br />
    exit 1<br />
fi<br />
[ NUM1 -ne NUM2 ] 	NUM1 is Not Equal to NUM2.<br />
[ NUM1 -gt NUM2 ] 	NUM1 is Greater Than NUM2.<br />
[ NUM1 -ge NUM2 ] 	NUM1 is Greater than or Equal to NUM2.<br />
[ NUM1 -lt NUM2 ] 	NUM1 is Less Than NUM2.<br />
[ NUM1 -le NUM2 ] 	NUM1 is Less than or Equal to NUM2.<br />
4. Miscellaneous conditions:<br />
Condition 	True if 	Example/explanation<br />
[ -o shelloption ] 	shell option &#8216;shelloption&#8217; is enabled. 	Shell options modify the behaviour of bash, except a few unmodifiable ones that indicate the shell status.</p>
<p>if [ ! -o checkwinsize ] # An exclamation mark inverts the outcome of the condition following it<br />
    echo &#8220;Shell option checkwinsize is disabled; enabling it so you can resize you terminal window without problems.&#8221;<br />
    shopt -s checkwinsize # This shell option is modifiable<br />
fi</p>
<p>if [ -o login_shell ]; then<br />
    echo &#8220;This a a login shell.&#8221; # This shell option is not modifiable</p>
<p>fi</p>
<p>With the double-parenthesis syntax, you can use the following conditions:<br />
5. Double-parenthesis syntax conditions:<br />
Condition 	True if 	Example/explanation<br />
(( NUM1 == NUM2 )) 	NUM1 is equal to NUM2. 	These conditions only accept integer numbers. Strings will be converted to integer numbers, if possible. Some random examples:</p>
<p>if (( $? == 0 )); then # $? returns the exit status of the previous command<br />
    echo &#8220;Previous command ran succesfully.&#8221;<br />
fi</p>
<p>if (( $(ps -p $pid -o ni=) != $(nice) )); then<br />
    echo &#8220;Process $pid is running with a non-default nice value&#8221;<br />
fi</p>
<p>if (( $num < 0 )); then<br />
    echo "Negative numbers not allowed; exiting..."<br />
    exit 1<br />
fi<br />
(( NUM1 != NUM2 )) 	NUM1 is not equal to NUM2.<br />
(( NUM1 > NUM2 )) 	NUM1 is greater than NUM2.<br />
(( NUM1 >= NUM2 )) 	NUM1 is greater than or equal to NUM2.<br />
(( NUM1 < NUM2 )) 	NUM1 is less than NUM2.<br />
(( NUM1 <= NUM2 )) 	NUM1 is less than or equal to NUM2.</p>
<p>After this dry information load, here's a bit of explanation for those who want to know more...<br />
Diving a little deeper</p>
<p>I said I'd tell more about the fact that if essentially checks the exit status of commands. And so I will. The basic rule of bash when it comes to conditions is 0 equals true, >0 equals false.<br />
That&#8217;s pretty much the opposite of many programming languages where 0 equals false and 1 (or more) equals true. The reason behind this is that shells like bash deal with programs a lot. By UNIX convention, programs use an exit status for indicating whether execution went alright or an error occured. As a succesful execution doesn&#8217;t require any explanation, it needs only one exit status. If there was a problem, however, it is useful to know what went wrong. Therefore, 0 is used for a succesful execution, and 1-255 to indicate what kind of error occured. The meaning of the numbers 1-255 differs depending on the program returning them.</p>
<p>Anyway, if executes the block after then when the command returns 0. Yes, conditions are commands. The phrase [ $foo -ge 3 ] returns an exit status, and the other two syntaxes as well! Therefore, there&#8217;s a neat trick you can use to quickly test a condition:</p>
<p>    [ $foo -ge 3 ] &#038;&#038; echo true</p>
<p>In this example, &#8220;echo true&#8221; is only executed if &#8220;[ $foo -ge 3 ]&#8221; returns 0 (true). Why is that, you might ask. It&#8217;s because bash only evaluates a condition when needed. When using the and combining expression, both conditions need to be true to make the combining expression return true. If the first condition returns false, it doesn&#8217;t matter what the second one returns; the result will be false. Therefore, bash doesn&#8217;t evaluate the second condition, and that&#8217;s the reason why &#8220;echo true&#8221; is not executed in the example. This is the same for the or operator (&#8220;||&#8221;), where the second condition is not evaluated if the first one is true.</p>
<p>Well, so much for the diving. If you want to know even more, I&#8217;d like to point you to the Advanced Bash-Scripting Guide and maybe the Bash Reference Manual.&#8217;</commands></condition> </p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Flpilinux.com%2Fif-condition-in-bash-script.html&amp;title=If%20Condition%20in%20Bash%20Script"><img src="http://lpilinux.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://lpilinux.com/if-condition-in-bash-script.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to Prevent damage after system lockup?</title>
		<link>http://lpilinux.com/how-to-prevent-damage-after-system-lockup.html</link>
		<comments>http://lpilinux.com/how-to-prevent-damage-after-system-lockup.html#comments</comments>
		<pubDate>Mon, 24 May 2010 02:43:35 +0000</pubDate>
		<dc:creator>lpilinuxblog</dc:creator>
				<category><![CDATA[Important for LPI 117-101]]></category>

		<guid isPermaLink="false">http://lpilinux.com/?p=506</guid>
		<description><![CDATA[No matter how stable the Linux kernel is, things like hardware failures can still lock up your system quite effectively. If you ever encounter a case like that, rebooting is pretty much the only option. However, there is rebooting and &#8230; <a href="http://lpilinux.com/how-to-prevent-damage-after-system-lockup.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Flpilinux.com%2Fhow-to-prevent-damage-after-system-lockup.html"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Flpilinux.com%2Fhow-to-prevent-damage-after-system-lockup.html&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>No matter how stable the Linux kernel is, things like hardware failures can still lock up your system quite effectively. If you ever encounter a case like that, rebooting is pretty much the only option. However, there is rebooting and rebooting. This solution describes a way to reboot your system that will do things like terminating all processes, syncing the remounting the disks, in order to prevent damage as much as possible. This can save you a lot of fscking and data loss.<br />
What this is and what this isn&#8217;t</p>
<p>First of all, I&#8217;ll make it more clear what this solution is and what it isn&#8217;t. This solution is meant to be used when your system is locked up, e.g. the cursor doesn&#8217;t even move in X, Ctrl + Alt + Backspace or Ctrl + Alt + F1 and the likes don&#8217;t seem to work anymore, maybe even Num Lock doesn&#8217;t turn on and off when you press the button. This solution is not meant to use when a single application doesn&#8217;t work. In that case, just terminate the application, not the whole system. Explaining how to do that is outside the scope of this solution.<br />
Prerequisites</p>
<p>In order to be able to use the way of rebooting that this solution describes, you will need to have a kernel with &#8216;Magic SysRq key (CONFIG_MAGIC_SYSRQ)&#8217; enabled. The easiest way to check this at runtime (without downloading and examining your kernel source package, that is) is to check if the file /proc/sys/kernel/sysrq exists. You can easily do this at the terminal using the following command:</p>
<p>    [rechosen@localhost ~]$ ls /proc/sys/kernel/sysrq</p>
<p>If that command returns the name and location of the file (&#8220;/proc/sys/kernel/sysrq&#8221;), you will most probably be able to use the described solution. If it returns something like &#8220;cannot access /proc/sys/kernel/sysrq: No such file or directory&#8221;, you&#8217;ll have to get yourself a kernel with &#8216;Magic SysRq key&#8217; support or this solution won&#8217;t work.<br />
The actual keyboard shortcuts</p>
<p>Keyboard shortcuts? Yes, &#8216;Magic SysRq key&#8217; allows using the SysRq* key on your keyboard to make the kernel perform various actions, even if it is in serious trouble. We&#8217;ll use some of these for our purpose. To be exactly, the following ones, in the following order:</p>
<p>   1. Alt + SysRq + r (switch to &#8220;Raw&#8221; keyboard input)<br />
   2. Alt + SysRq + s (&#8220;Sync&#8221; mounted filesystems)<br />
   3. Alt + SysRq + e (send the &#8220;tErm&#8221; signal to all running processes)<br />
   4. Alt + SysRq + i (send the &#8220;kIll&#8221; signal to all running processes)<br />
   5. Alt + SysRq + u (&#8220;remoUnt&#8221; all mounted filesystems read-only)<br />
   6. Alt + SysRq + b (&#8220;reBoot&#8221; the computer)</p>
<p>Okay, now you might think: &#8220;I&#8217;ll never remember that!&#8221;. Fortunately, mnemonic devices exist. This site suggest remembering the sentence: &#8220;Raising Skinny Elephants Is Utterly Boring&#8221;. Although that one is pretty nice, I though adding some rhyme might make the keys easier to remember: &#8220;Red Stripe Ends In Unique Blends&#8221;. Or, though this one is a bit outdated: &#8220;Rebooting So Easy In Ubuntu Breezy&#8221;. I&#8217;m looking forward to all the creative sentences you can think of! If you know a good one, please leave a comment.</p>
<p>*: If you can&#8217;t find a SysRq key on your keyboard, try using the Print Screen key. In either way, the key is usually located on the right of the F12 key.<br />
How and when to use them</p>
<p>The keyboard shortcuts I mentioned about should be used, as described in What this is and what this isn&#8217;t, when your system is locked up. Though sometimes the kernel might be in troubles so big that it won&#8217;t respond, in most cases it will respond. I recommend allowing the kernel to take its time: don&#8217;t use the shortcuts too fast after each other. Wait at least 4-5 seconds before pressing the next one (and even longer on slower systems). After the last one (Alt + SysRq + b) the computer should reboot. If it doesn&#8217;t, the kernel probably was unable to accept the commands (it doesn&#8217;t support &#8216;Magic SysRq key&#8217; or it is locked up totally). In that case, you&#8217;ll just have to reset the computer and hope you won&#8217;t lose anything.<br />
More information about &#8216;Magic SysRq key&#8217;</p>
<p>For more information about this kernel feature (other keyboard shortcuts, how to use it on different architectures etc.), have a look at the kernel documentation about it. The Wikipedia entry about it might also give useful information (though, at the moment of writing, it recommends a slightly different order of keystrokes). </p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Flpilinux.com%2Fhow-to-prevent-damage-after-system-lockup.html&amp;title=How%20to%20Prevent%20damage%20after%20system%20lockup%3F"><img src="http://lpilinux.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://lpilinux.com/how-to-prevent-damage-after-system-lockup.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bash Script &#8211; Full Tutorial</title>
		<link>http://lpilinux.com/bash-script-full-tutorial.html</link>
		<comments>http://lpilinux.com/bash-script-full-tutorial.html#comments</comments>
		<pubDate>Mon, 24 May 2010 02:42:45 +0000</pubDate>
		<dc:creator>lpilinuxblog</dc:creator>
				<category><![CDATA[Important for LPI 117-101]]></category>

		<guid isPermaLink="false">http://lpilinux.com/?p=505</guid>
		<description><![CDATA[If you use bash for scripting you will undoubtedly have to use conditions a lot, for example for an if &#8230; then construct or a while loop. The syntax of these conditions can seem a bit daunting to learn and &#8230; <a href="http://lpilinux.com/bash-script-full-tutorial.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Flpilinux.com%2Fbash-script-full-tutorial.html"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Flpilinux.com%2Fbash-script-full-tutorial.html&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>If you use bash for scripting you will undoubtedly have to use conditions a lot, for example for an if &#8230; then construct or a while loop. The syntax of these conditions can seem a bit daunting to learn and use. This tutorial aims to help the reader understanding conditions in bash, and provides a comprehensive list of the possibilities. A small amount of general shell knowledge is assumed.</p>
<p>Difficulty: Basic &#8211; Medium<br />
Introduction</p>
<p>Bash features a lot of built-in checks and comparisons, coming in quite handy in many situations. You&#8217;ve probably seen if statements like the following before:</p>
<p>    if [ $foo -ge 3 ]; then</p>
<p>The condition in this example is essentially a command. It may sound strange, but surrounding a comparison with square brackets is the same as using the built-in test command, like this:</p>
<p>    if test $foo -ge 3; then</p>
<p>If $foo is Greater then or Equal to 3, the block after &#8216;then&#8217; will be executed. If you always wondered why bash tends to use -ge or -eq instead of >= or ==, it&#8217;s because this condition type originates from a command, where -ge and -eq are options.<br />
And that&#8217;s what if does essentially, checking the exit status of a command. I&#8217;ll explain that in more detail further in the tutorial.<br />
There also are built-in checks that are more specific to shells. What<br />
about this one?</p>
<p>    if [ -f regularfile ]; then</p>
<p>The above condition is true if the file &#8216;regularfile&#8217; exists and<br />
is a regular file. A regular file means that it&#8217;s not a block or<br />
character device, or a directory. This way, you can make sure a usable<br />
file exists before doing something with it. You can even check if a<br />
file is readable!</p>
<p>    if [ -r readablefile]; then</p>
<p>The above condition is true if the file &#8216;readablefile&#8217; exists and is readable. Easy, isn&#8217;t it?<br />
The syntax of an if statement (a short explanation)</p>
<p>The basic syntax of an if &#8230; then statement is like this:</p>
<p>    if <condition>; then<br />
    <commands><br />
    fi</p>
<p>The condition is, depending on its type, surrounded by certain<br />
brackets, eg. [ ]. You can read about the different types further on<br />
in the tutorial. You can add commands to be executed when the condition is false using the else keyword, and use the elif (elseif) keyword to execute commands on another condition if the primary condition is false. The else keyword always comes last. Example:</p>
<p>    if [ -r somefile ]; then<br />
    content=$(cat somefile)<br />
    elif [ -f somefile ]; then<br />
    echo &#8220;The file &#8216;somefile&#8217; exists but is not readable to the script.&#8221;<br />
    else<br />
    echo &#8220;The file &#8216;somefile&#8217; does not exist.&#8221;<br />
    fi</p>
<p>A short explanation of the example: first we check if the file somefile is readable (&#8220;if [ -r somefile ]&#8220;). If so, we read it into a variable. If not, we check if it actually exists (&#8220;elif [ -f somefile ]&#8220;). If that&#8217;s true, we report that it exists but isn&#8217;t readable (if it was, we would have read the content). If the file doesn&#8217;t exist, we report so, too. The condition at elif is only executed if the condition at if was false. The commands belonging to else are only executed if both conditions are false.<br />
The basic rules of conditions</p>
<p>When you start writing and using your own conditions, there are some rules you should know to prevent getting errors that are hard to trace. Here follow three important ones:</p>
<p>   1. Always keep spaces between the brackets and the actual check/comparison. The following won&#8217;t work:</p>
<p>          if [$foo -ge 3]; then</p>
<p>      Bash will complain about a &#8220;missing `]&#8217;&#8221;.<br />
   2. Always terminate the line before putting a new keyword like &#8220;then&#8221;. The words if, then, else, elif and fi are shell keywords, meaning that they cannot share the same line. Put a &#8220;;&#8221; between the previous statement and the keyword or place the keyword on the start of a new line. Bash will throw errors like &#8220;syntax error near unexpected token `fi&#8217;&#8221; if you don&#8217;t.<br />
   3. It is a good habit to quote string variables if you use them in conditions, because otherwise they are likely to give trouble if they contain<br />
      spaces and/or newlines. By quoting I mean:</p>
<p>          if [ "$stringvar" == "tux" ]; then</p>
<p>      There are a few cases in which you should not<br />
      quote, but they are rare. You will see one of them further on in the tutorial. </p>
<p>Also, there are two things that may be useful to know:</p>
<p>   1. You can invert a condition by putting an &#8220;!&#8221; in front of it. Example:</p>
<p>          if [ ! -f regularfile ]; then</p>
<p>      Be sure to place the &#8220;!&#8221; inside the brackets!<br />
   2. You can combine conditions by using certain operators. For the single-bracket syntax that we&#8217;ve been using so far, you can use &#8220;-a&#8221; for and and &#8220;-o&#8221; for or. Example:</p>
<p>          if [ $foo -ge 3 -a $foo -lt 10 ]; then</p>
<p>      The above condition will return true if $foo contains an integer greater than or equal to 3 and Less Than 10. You can read more about these combining expressions at the respective condition syntaxes. </p>
<p>And, one more basic thing: don&#8217;t forget that conditions can also be used in other statements, like while and until. It is outside the scope of this tutorial to explain those, but you can read about them at the Bash Guide for Beginners.</p>
<p>Anyway, I&#8217;ve only shown you conditions between single brackets so far. There are more syntaxes, however, as you will read in the next section.<br />
Different condition syntaxes</p>
<p>Bash features different syntaxes for conditions. I will list the three of them:<br />
1. Single-bracket syntax</p>
<p>This is the condition syntax you have already seen in the previous paragraphs; it&#8217;s the oldest supported syntax. It supports three types of conditions:</p>
<p>    * File-based conditions<br />
          o Allows different kinds of checks on a file. Example:</p>
<p>                if [ -L symboliclink ]; then</p>
<p>            The above condition is true if the file &#8216;symboliclink&#8217; exists and is a symbolic link. For more file-based conditions see the table below.<br />
    * String-based conditions<br />
          o Allows checks on a string and comparing of strings. Example one:</p>
<p>                if [ -z "$emptystring" ]; then</p>
<p>            The above condition is true if $emptystring is an empty string or an uninitialized variable. Example two:</p>
<p>                if [ "$stringvar1" == "cheese" ]; then</p>
<p>            The above condition is true if $stringvar1 contains just the string &#8220;cheese&#8221;. For more string-based conditions see the table below.<br />
    * Arithmetic (number-based) conditions<br />
          o Allows comparing integer numbers. Example:</p>
<p>                if [ $num -lt 1 ]; then</p>
<p>            The above condition returns true if $num is less than 1. For more arithmetic conditions see the table below. </p>
<p>2. Double-bracket syntax</p>
<p>You may have encountered conditions enclosed in double square brackets already, which look like this:</p>
<p>    if [[ "$stringvar" == *string* ]]; then</p>
<p>The double-bracket syntax serves as an enhanced version of the single-bracket syntax; it mainly has the same features, but also some important differences with it. I will list them here:</p>
<p>    * The first difference can be seen in the above example; when comparing strings, the double-bracket syntax features shell globbing. This means that an asterisk (&#8220;*&#8221;) will expand to literally anything, just as you probably know from normal command-line usage. Therefore, if $stringvar contains the phrase &#8220;string&#8221; anywhere, the condition will return true. Other forms of shell globbing are allowed, too. If you&#8217;d like to match both &#8220;String&#8221; and &#8220;string&#8221;, you could use the following syntax:</p>
<p>          if [[ "$stringvar" == *[sS]tring* ]]; then</p>
<p>      Note that only general shell globbing is allowed. Bash-specific things like {1..4} or {foo,bar} will not work. Also note that the globbing will not work if you quote the right string. In this case you should leave it unquoted.<br />
    * The second difference is that word splitting is prevented. Therefore, you could omit placing quotes around string variables and use a condition like the following without problems:</p>
<p>          if [[ $stringvarwithspaces != foo ]]; then</p>
<p>      Nevertheless, the quoting string variables remains a good habit, so I recommend just to keep doing it.<br />
    * The third difference consists of not expanding filenames. I will illustrate this difference using two examples, starting with the old single-bracket situation:</p>
<p>          if [ -a *.sh ]; then</p>
<p>      The above condition will return true if there is one single file in the working directory that has a .sh extension. If there are none, it will return false. If there are several .sh files, bash will throw an error and stop executing the script. This is because *.sh is expanded to the files in the working directory. Using double brackets prevents this:</p>
<p>          if [[ -a *.sh ]]; then</p>
<p>      The above condition will return true only if there is a file in the working directory called &#8220;*.sh&#8221;, no matter what other .sh files exist. The asterisk is taken literally, because the double-bracket syntax does not expand filenames.<br />
    * The fourth difference is the addition of more generally known combining expressions, or, more specific, the operators &#8220;&#038;&#038;&#8221; and &#8220;||&#8221;. Example:</p>
<p>          if [[ $num -eq 3 &#038;&#038; "$stringvar" == foo ]]; then</p>
<p>      The above condition returns true if $num is equal to 3 and $stringvar is equal to &#8220;foo&#8221;. The -a and -o known from the single-bracket syntax is supported, too.</p>
<p>      Note that the and operator has precedence over the or operator, meaning that &#8220;&#038;&#038;&#8221; or &#8220;-a&#8221; will be evaluated before &#8220;||&#8221; or &#8220;-o&#8221;.<br />
    * The fifth difference is that the double-bracket syntax allows regex pattern matching using the &#8220;=~&#8221; operator. See the table for more information.</p>
<p>3. Double-parenthesis syntax</p>
<p>There also is another syntax for arithmetic (number-based) conditions, most likely adopted from the Korn shell:</p>
<p>    if (( $num < = 5 )); then</p>
<p>The above condition is true if $num is less than or equal to 5. This syntax may seem more familiar to programmers. It features all the 'normal' operators, like "==", "<" and ">=&#8221;. It supports the &#8220;&#038;&#038;&#8221; and &#8220;||&#8221; combining expressions (but not the -a and -o ones!). It is equivalent to the built-in let command.<br />
Table of conditions</p>
<p>The following table list the condition possibilities for both the single- and the double-bracket syntax. Save a single exception, the examples are given in single-bracket syntax, but are always compatible with double brackets.<br />
 1. File-based conditions:<br />
Condition 	True if 	Example/explanation<br />
[ -a existingfile ] 	file &#8216;existingfile&#8217; exists. 	if [ -a tmp.tmp ]; then<br />
    rm -f tmp.tmp # Make sure we&#8217;re not bothered by an old temporary file<br />
fi<br />
[ -b blockspecialfile ] 	file &#8216;blockspecialfile&#8217; exists and is block special. 	Block special files are special kernel files found in /dev, mainly used for ATA devices like hard disks, cd-roms and floppy disks.</p>
<p>if [ -b /dev/fd0 ]; then<br />
    dd if=floppy.img of=/dev/fd0 # Write an image to a floppy<br />
fi<br />
[ -c characterspecialfile ] 	file &#8216;characterspecialfile&#8217; exists and is character special. 	Character special files are special kernel files found in /dev, used for all kinds of purposes (audio hardware, tty&#8217;s, but also /dev/null).</p>
<p>if [ -c /dev/dsp ]; then<br />
    cat raw.wav > /dev/dsp # This actually works for certain raw wav files<br />
fi<br />
[ -d directory ] 	file &#8216;directory&#8217; exists and is a directory. 	In UNIX-style, directories are a special kind of file.</p>
<p>if [ -d ~/.kde ]; then<br />
    echo &#8220;You seem to be a kde user.&#8221;<br />
fi<br />
[ -e existingfile ] 	file &#8216;existingfile&#8217; exists. 	(same as -a, see that entry for an example)<br />
[ -f regularfile ] 	file &#8216;regularfile&#8217; exists and is a regular file. 	A regular file is neither a block or character special file nor a directory.</p>
<p>if [ -f ~/.bashrc ]; then<br />
    source ~/.bashrc<br />
fi<br />
[ -g sgidfile ] 	file &#8216;sgidfile&#8217; exists and is set-group-ID. 	When the SGID-bit is set on a directory, all files created in that directory will inherit the group of the directory.</p>
<p>if [ -g . ]; then<br />
   echo &#8220;Created files are inheriting the group &#8216;$(ls -ld . | awk &#8216;{ print $4 }&#8217;)&#8217; from the working directory.&#8221;<br />
fi<br />
[ -G fileownedbyeffectivegroup ] 	file &#8216;fileownedbyeffectivegroup&#8217; exists and is owned by the effective group ID. 	The effective group id is the primary group id of the executing user.</p>
<p>if [ ! -G file ]; then # An exclamation mark inverts the outcome of the condition following it<br />
   chgrp $(id -g) file # Change the group if it&#8217;s not the effective one<br />
fi<br />
[ -h symboliclink ] 	file &#8216;symboliclink&#8217; exists and is a symbolic link. 	if [ -h $pathtofile ]; then<br />
    pathtofile=$(readlink -e $pathtofile) # Make sure $pathtofile contains the actual file and not a symlink to it<br />
fi<br />
[ -k stickyfile ] 	file &#8216;stickyfile&#8217; exists and has its sticky bit set. 	The sticky bit has got quite a history, but is now used to prevent world-writable directories from having their contents deletable by anyone.</p>
<p>if [ ! -k /tmp ]; then # An exclamation mark inverts the outcome of the condition following it<br />
    echo &#8220;Warning! Anyone can delete and/or rename your files in /tmp!&#8221;<br />
fi<br />
[ -L symboliclink ] 	file &#8216;symboliclink&#8217; exists and is a symbolic link. 	(same as -h, see that entry for an example)<br />
[ -N modifiedsincelastread ] 	file &#8216;modifiedsincelastread&#8217; exists and was modified after the last read. 	if [ -N /etc/crontab ]; then<br />
    killall -HUP crond # SIGHUP makes crond reread all crontabs<br />
fi<br />
[ -O fileownedbyeffectiveuser ] 	file &#8216;fileownedbyeffectiveuser&#8217; exists and is owned by the user executing the script. 	if [ -O file ]; then<br />
    chmod 600 file # Makes the file private, which is a bad idea if you don&#8217;t own it<br />
fi<br />
[ -p namedpipe ] 	file &#8216;namedpipe&#8217; exists and is a named pipe. 	A named pipe is a file in /dev/fd/ that can be read just once. See my bash tutorial for a case in which it&#8217;s used.</p>
<p>if [ -p $file ]; then<br />
    cp $file tmp.tmp # Make sure we&#8217;ll be able to read<br />
    file=&#8221;tmp.tmp&#8221;    # the file as many times as we like<br />
fi<br />
[ -r readablefile ] 	file &#8216;readablefile&#8217; exists and is readable to the script. 	if [-r file ]; then<br />
    content=$(cat file) # Set $content to the content of the file<br />
fi<br />
[ -s nonemptyfile ] 	file &#8216;nonemptyfile&#8217; exists and has a size of more than 0 bytes. 	if [ -s logfile ]; then<br />
    gzip logfile    # Backup the old logfile<br />
    touch logfile # before creating a fresh one.<br />
fi<br />
[ -S socket ] 	file &#8216;socket&#8217; exists and is a socket. 	A socket file is used for inter-process communication, and features an interface similar to a network connection.</p>
<p>if [ -S /var/lib/mysql/mysql.sock ]; then<br />
    mysql &#8211;socket=/var/lib/mysql/mysql.sock # See this MySQL tip<br />
fi<br />
[ -t openterminal ] 	file descriptor &#8216;openterminal&#8217; exists and refers to an open terminal. 	Virtually everything is done using files on Linux/UNIX, and the terminal is no exception.</p>
<p>if [ -t /dev/pts/3 ]; then<br />
    echo -e &#8220;\nHello there. Message from terminal $(tty) to you.&#8221; > /dev/pts/3 # Anyone using that terminal will actually see this message!<br />
fi<br />
[ -u suidfile ] 	file &#8216;suidfile&#8217; exists and is set-user-ID. 	Setting the suid-bit on a file causes execution of that file to be done with the credentials of the owner of the file, not of the executing user.</p>
<p>if [ -u executable ]; then<br />
    echo &#8220;Running program executable as user $(ls -l executable | awk &#8216;{ print $3 }&#8217;).&#8221;<br />
fi<br />
[ -w writeablefile ] 	file &#8216;writeablefile&#8217; exists and is writeable to the script. 	if [ -w /dev/hda ]; then<br />
    grub-install /dev/hda<br />
fi<br />
[ -x executablefile ] 	file &#8216;executablefile&#8217; exists and is executable for the script. 	Note that the execute permission on a directory means that it&#8217;s searchable (you can see which files it contains).</p>
<p>if [ -x /root ]; then<br />
    echo &#8220;You can view the contents of the /root directory.&#8221;<br />
fi<br />
[ newerfile -nt olderfile ] 	file &#8216;newerfile&#8217; was changed more recently than &#8216;olderfile&#8217;, or if &#8216;newerfile&#8217; exists and &#8216;olderfile&#8217; doesn&#8217;t. 	if [ story.txt1 -nt story.txt ]; then<br />
    echo &#8220;story.txt1 is newer than story.txt; I suggest continuing with the former.&#8221;<br />
fi<br />
[ olderfile -ot newerfile ] 	file &#8216;olderfile&#8217; was changed longer ago than &#8216;newerfile&#8217;, or if &#8216;newerfile&#8217; exists and &#8216;olderfile&#8217; doesn&#8217;t. 	if [ /mnt/remote/remotefile -ot localfile ]; then<br />
    cp -f localfile /mnt/remote/remotefile # Make sure the remote location has the newest version of the file, too<br />
fi<br />
[ same -ef file ] 	file &#8216;same&#8217; and file &#8216;file&#8217; refer to the same device/inode number. 	if [ /dev/cdrom -ef /dev/dvd ]; then<br />
    echo &#8220;Your primary cd drive appears to read dvd&#8217;s, too.&#8221;<br />
fi<br />
 2. String-based conditions:<br />
Condition 	True if 	Example/explanation<br />
[ STRING1 == STRING2 ] 	STRING1 is equal to STRING2. 	if [ "$1" == "moo" ]; then<br />
    echo $cow # Ever tried executing &#8216;apt-get moo&#8217;?<br />
fi</p>
<p>Note: you can also use a single &#8220;=&#8221; instead of a double one.<br />
[ STRING1 != STRING2 ] 	STRING1 is not equal to STRING2. 	if [ "$userinput" != "$password" ]; then<br />
    echo &#8220;Access denied! Wrong password!&#8221;<br />
    exit 1 # Stops script execution right here<br />
fi<br />
[ STRING1 \> STRING2 ] 	STRING1 sorts after STRING2 in the current locale (lexographically). 	The backslash before the angle bracket is there because the bracket needs to be escaped to be interpreted correctly. As an example we have a basic bubble sort:</p>
<p>(Don&#8217;t feel ashamed if you don&#8217;t understand this, it is a more complex example)</p>
<p>array=( linux tutorial blog )<br />
swaps=1<br />
while (( swaps > 0 )); do</p>
<p>swaps=0<br />
    for (( i=0; i < (( ${#array[@]} - 1 )) ; i++ )); do<br />
        if [ "${array[$i]}" \> &#8220;${array[$(( i + 1 ))]}&#8221; ]; then # Here is the sorting condition<br />
            tempstring=${array[$i]}<br />
            array[$i]=${array[$(( i + 1 ))]}<br />
            array[$(( i + 1 ))]=$tempstring<br />
            (( swaps=swaps + 1 ))<br />
        fi<br />
    done<br />
done<br />
echo ${array[@]} # Returns &#8220;blog linux tutorial&#8221;<br />
[ STRING1 \< STRING2 ] 	STRING1 sorts before STRING2 in the current locale (lexographically).<br />
[ -n NONEMPTYSTRING ] 	NONEMPTYSTRING has a length of more than zero. 	This condition only accepts valid strings, so be sure to quote anything you give to it.</p>
<p>if [ -n "$userinput" ]; then<br />
    userinput=parse($userinput) # Only parse if the user actually gave some input.<br />
fi</p>
<p>Note that you can also omit the &#8220;-n&#8221;, as brackets with just a string in it behave the same.<br />
[ -z EMPTYSTRING ] 	EMPTYSTRING is an empty string. 	This condition also accepts non-string input, like an uninitialized variable:</p>
<p>if [ -z $uninitializedvar ]; then<br />
    uninitializedvar=&#8221;initialized&#8221; # -z returns true on an uninitialized variable, so we initialize it here.<br />
fi<br />
Double-bracket syntax only:<br />
[[ STRING1 =~ REGEXPATTERN ]] 	STRING1 matches REGEXPATTERN. 	If you are familiar with Regular Expressions, you can use this conditions to perform a regex match.</p>
<p>if [[ "$email" =~ "\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}\b&#8221; ]]; then<br />
    echo &#8220;\$email contains a valid e-mail address.&#8221;<br />
fi<br />
 3. Arithmetic (number-based) conditions:<br />
Condition 	True if 	Example/explanation<br />
[ NUM1 -eq NUM2 ] 	NUM1 is EQual to NUM2. 	These conditions only accept integer numbers. Strings will be converted to integer numbers, if possible. Some random examples:</p>
<p>if [ $? -eq 0 ]; then # $? returns the exit status of the previous command<br />
    echo &#8220;Previous command ran succesfully.&#8221;<br />
fi</p>
<p>if [ $(ps -p $pid -o ni=) -ne $(nice) ]; then<br />
    echo &#8220;Process $pid is running with a non-default nice value&#8221;<br />
fi</p>
<p>if [ $num -lt 0 ]; then<br />
    echo &#8220;Negative numbers not allowed; exiting&#8230;&#8221;<br />
    exit 1<br />
fi<br />
[ NUM1 -ne NUM2 ] 	NUM1 is Not Equal to NUM2.<br />
[ NUM1 -gt NUM2 ] 	NUM1 is Greater Than NUM2.<br />
[ NUM1 -ge NUM2 ] 	NUM1 is Greater than or Equal to NUM2.<br />
[ NUM1 -lt NUM2 ] 	NUM1 is Less Than NUM2.<br />
[ NUM1 -le NUM2 ] 	NUM1 is Less than or Equal to NUM2.<br />
4. Miscellaneous conditions:<br />
Condition 	True if 	Example/explanation<br />
[ -o shelloption ] 	shell option &#8216;shelloption&#8217; is enabled. 	Shell options modify the behaviour of bash, except a few unmodifiable ones that indicate the shell status.</p>
<p>if [ ! -o checkwinsize ] # An exclamation mark inverts the outcome of the condition following it<br />
    echo &#8220;Shell option checkwinsize is disabled; enabling it so you can resize you terminal window without problems.&#8221;<br />
    shopt -s checkwinsize # This shell option is modifiable<br />
fi</p>
<p>if [ -o login_shell ]; then<br />
    echo &#8220;This a a login shell.&#8221; # This shell option is not modifiable</p>
<p>fi</p>
<p>With the double-parenthesis syntax, you can use the following conditions:<br />
5. Double-parenthesis syntax conditions:<br />
Condition 	True if 	Example/explanation<br />
(( NUM1 == NUM2 )) 	NUM1 is equal to NUM2. 	These conditions only accept integer numbers. Strings will be converted to integer numbers, if possible. Some random examples:</p>
<p>if (( $? == 0 )); then # $? returns the exit status of the previous command<br />
    echo &#8220;Previous command ran succesfully.&#8221;<br />
fi</p>
<p>if (( $(ps -p $pid -o ni=) != $(nice) )); then<br />
    echo &#8220;Process $pid is running with a non-default nice value&#8221;<br />
fi</p>
<p>if (( $num < 0 )); then<br />
    echo "Negative numbers not allowed; exiting..."<br />
    exit 1<br />
fi<br />
(( NUM1 != NUM2 )) 	NUM1 is not equal to NUM2.<br />
(( NUM1 > NUM2 )) 	NUM1 is greater than NUM2.<br />
(( NUM1 >= NUM2 )) 	NUM1 is greater than or equal to NUM2.<br />
(( NUM1 < NUM2 )) 	NUM1 is less than NUM2.<br />
(( NUM1 <= NUM2 )) 	NUM1 is less than or equal to NUM2.</p>
<p>After this dry information load, here's a bit of explanation for those who want to know more...<br />
Diving a little deeper</p>
<p>I said I'd tell more about the fact that if essentially checks the exit status of commands. And so I will. The basic rule of bash when it comes to conditions is 0 equals true, >0 equals false.<br />
That&#8217;s pretty much the opposite of many programming languages where 0 equals false and 1 (or more) equals true. The reason behind this is that shells like bash deal with programs a lot. By UNIX convention, programs use an exit status for indicating whether execution went alright or an error occured. As a succesful execution doesn&#8217;t require any explanation, it needs only one exit status. If there was a problem, however, it is useful to know what went wrong. Therefore, 0 is used for a succesful execution, and 1-255 to indicate what kind of error occured. The meaning of the numbers 1-255 differs depending on the program returning them.</p>
<p>Anyway, if executes the block after then when the command returns 0. Yes, conditions are commands. The phrase [ $foo -ge 3 ] returns an exit status, and the other two syntaxes as well! Therefore, there&#8217;s a neat trick you can use to quickly test a condition:</p>
<p>    [ $foo -ge 3 ] &#038;&#038; echo true</p>
<p>In this example, &#8220;echo true&#8221; is only executed if &#8220;[ $foo -ge 3 ]&#8221; returns 0 (true). Why is that, you might ask. It&#8217;s because bash only evaluates a condition when needed. When using the and combining expression, both conditions need to be true to make the combining expression return true. If the first condition returns false, it doesn&#8217;t matter what the second one returns; the result will be false. Therefore, bash doesn&#8217;t evaluate the second condition, and that&#8217;s the reason why &#8220;echo true&#8221; is not executed in the example. This is the same for the or operator (&#8220;||&#8221;), where the second condition is not evaluated if the first one is true.</p>
<p>Well, so much for the diving. If you want to know even more, I&#8217;d like to point you to the Advanced Bash-Scripting Guide and maybe the Bash Reference Manual.<br />
Conclusion</p>
<p>In this tutorial, you&#8217;ve been able to make a start at understanding the many possibilities of conditions in bash scripting. You&#8217;ve been able to read about the basic rules of writing and using conditions, about the three syntaxes and their properties, and maybe you took the opportunity to dive a little deeper. I hope you enjoyed the reading as much as I enjoyed the writing. You can always return here to look up conditions in the table (bookmark that link to see the table directly), or to refresh your knowledge. If you have any suggestions, additions or other feedback, feel free to comment. </commands></condition> </p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Flpilinux.com%2Fbash-script-full-tutorial.html&amp;title=Bash%20Script%20%26%238211%3B%20Full%20Tutorial"><img src="http://lpilinux.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://lpilinux.com/bash-script-full-tutorial.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to translate, squeeze and delete characters using tr in Linux</title>
		<link>http://lpilinux.com/how-to-translate-squeeze-and-delete-characters-using-tr-in-linux.html</link>
		<comments>http://lpilinux.com/how-to-translate-squeeze-and-delete-characters-using-tr-in-linux.html#comments</comments>
		<pubDate>Sun, 23 May 2010 04:59:08 +0000</pubDate>
		<dc:creator>lpilinuxblog</dc:creator>
				<category><![CDATA[Important for LPI 117-101]]></category>

		<guid isPermaLink="false">http://lpilinux.com/?p=501</guid>
		<description><![CDATA[Translate, squeeze, and/or delete characters from standard input, writ- ing to standard output. -c, -C, &#8211;complement first complement SET1 -d, &#8211;delete delete characters in SET1, do not translate -s, &#8211;squeeze-repeats replace each input sequence of a repeated character that is &#8230; <a href="http://lpilinux.com/how-to-translate-squeeze-and-delete-characters-using-tr-in-linux.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Flpilinux.com%2Fhow-to-translate-squeeze-and-delete-characters-using-tr-in-linux.html"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Flpilinux.com%2Fhow-to-translate-squeeze-and-delete-characters-using-tr-in-linux.html&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>Translate, squeeze, and/or delete characters from standard input, writ- ing to standard output. -c, -C, &#8211;complement first complement SET1 -d, &#8211;delete delete characters in SET1, do not translate -s, &#8211;squeeze-repeats replace each input sequence of a repeated character that is listed in SET1 with a single occurrence of that character -t, &#8211;truncate-set1 first truncate SET1 to length of SET2  </p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Flpilinux.com%2Fhow-to-translate-squeeze-and-delete-characters-using-tr-in-linux.html&amp;title=How%20to%20translate%2C%20squeeze%20and%20delete%20characters%20using%20tr%20in%20Linux"><img src="http://lpilinux.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://lpilinux.com/how-to-translate-squeeze-and-delete-characters-using-tr-in-linux.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>mysql command</title>
		<link>http://lpilinux.com/mysql-command.html</link>
		<comments>http://lpilinux.com/mysql-command.html#comments</comments>
		<pubDate>Sun, 16 May 2010 04:09:33 +0000</pubDate>
		<dc:creator>lpilinuxblog</dc:creator>
				<category><![CDATA[Important for LPI 117-101]]></category>

		<guid isPermaLink="false">http://lpilinux.com/mysql-command.html</guid>
		<description><![CDATA[The mysql program provides a curses-based interface to the SQL-based database server daemon, mysqld(1). Full fuller documentation, refer to the HTML documents installed with the package. OPTIONS -B&#124;&#8211;batch Print results with a tab as separator, each row on a new &#8230; <a href="http://lpilinux.com/mysql-command.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Flpilinux.com%2Fmysql-command.html"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Flpilinux.com%2Fmysql-command.html&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>The mysql program provides a curses-based interface to the SQL-based database server daemon, mysqld(1). Full fuller documentation, refer to the HTML documents installed with the package.<br />
OPTIONS</p>
<p>-B|&#8211;batch<br />
    Print results with a tab as separator, each row on a new line.<br />
-#|&#8211;debug=logfile<br />
    Employ the specified debug log.<br />
-T|&#8211;debug-info<br />
    Print debug information upon exiting.<br />
-e | &#8211;exec=command<br />
    Execute the specified command and quit (&#8211;batch is implicit).<br />
-f|&#8211;force<br />
    Continue even if the face of a SQL error.<br />
-?|&#8211;help<br />
    Display a help message and exit.<br />
-h|&#8211;host=hostname<br />
    Connect to the specified host.<br />
-n|&#8211;unbuffered<br />
    Flush the buffer after each query.<br />
-p|&#8211;password[=pwd]<br />
    Employ the specified password when connecting to the database server. If a password is not supplied, it will be requested interactively.<br />
-P|&#8211;port=pnum<br />
    Employ the specified port number for connecting to the database server.<br />
-q|&#8211;quick<br />
    Do not cache the result; print it row by row. This may slow down the server if the output is suspended.<br />
-r|&#8211;raw<br />
    Write fields without conversion. (used with &#8211;batch).<br />
-s|&#8211;silent<br />
    Silent mode: reduce the amount of output.<br />
-S|&#8211;socket=snum<br />
    Employ the specified socket file for connecting to the database server.<br />
-u|&#8211;user=uname<br />
    Employ the specified user name for logging in to the server.<br />
-v|&#8211;verbose<br />
    Verbose mode: write more Specifying this option twice produces a tabular output format.<br />
-V|&#8211;version<br />
    Print the mysql version number and exit.<br />
-w|&#8211;wait<br />
    Wait and retry if the database server connection is down. </p>
<p>FILES</p>
<p>/depot/bin/mysql<br />
    executable<br />
/depot/bin/mysqld<br />
    executable<br />
/depot/bin/safe_mysqld<br />
    executable shell script for starting mysqld safely<br />
/site/var/mysql/data<br />
    location of database files  </p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Flpilinux.com%2Fmysql-command.html&amp;title=mysql%20command"><img src="http://lpilinux.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://lpilinux.com/mysql-command.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>mzip command</title>
		<link>http://lpilinux.com/mzip-command.html</link>
		<comments>http://lpilinux.com/mzip-command.html#comments</comments>
		<pubDate>Sat, 15 May 2010 04:08:56 +0000</pubDate>
		<dc:creator>lpilinuxblog</dc:creator>
				<category><![CDATA[Important for LPI 117-101]]></category>

		<guid isPermaLink="false">http://lpilinux.com/mzip-command.html</guid>
		<description><![CDATA[The mzip command is used to issue ZIP disk specific commands on Linux, Solaris or HPUX. Its syntax is: mzip [-epqrwx] Mzip allows the following command line options: e Ejects the disk. f Force eject even if the disk is &#8230; <a href="http://lpilinux.com/mzip-command.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Flpilinux.com%2Fmzip-command.html"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Flpilinux.com%2Fmzip-command.html&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>The mzip command is used to issue ZIP disk specific commands on Linux, Solaris or HPUX. Its syntax is:</p>
<p>mzip [-epqrwx]</p>
<p>Mzip allows the following command line options:</p>
<p>e<br />
    Ejects the disk.<br />
f<br />
    Force eject even if the disk is mounted (must be given in addition to -e).<br />
r<br />
    Write protect the disk.<br />
w<br />
    Remove write protection.<br />
p<br />
    Password write protect.<br />
x<br />
    Password protect<br />
u<br />
    Temporarily unprotect the disk until it is ejected. The disk becomes writable, and reverts back to its old state when ejected.<br />
q<br />
    Queries the status </p>
<p>To remove the password, set it to one of the passwordless modes -r or -w: mzip will then ask you for the password, and unlock the disk. If you have forgotten the password, you can get rid of it by low-level formatting the disk (using your SCSI adaptor&#8217;s BIOS setup).</p>
<p>The ZipTools disk shipped with the drive is also password protected. On Dos or on a Mac, this password is automatically removed once the ZipTools have been installed. From various articles posted to Usenet, I learned that the password for the tools disk is APlaceForYourStuff. Mzip knows about this password, and tries it first, before prompting you for a password. Thus mzip -w z: unlocks the tools disk. The tools disk is formatted in a special way so as to be usable both in a PC and in a Mac. On a PC, the Mac filesystem appears as a hidden file named Infinitypartishn.macIntegral. You may erase it to reclaim the 50 Megs of space taken up by the Mac filesystem.</p>
<p>Bugs</p>
<p>This command is a big kludge. A proper implementation would take a rework of significant parts of mtools, but unfortunately I don&#8217;t have the time for this right now. The main downside of this implementation is that it is inefficient on some architectures (several successive calls to mtools, which defeats mtools&#8217; caching).</p>
<p>See Also<br />
Mtools&#8217; texinfo doc<br />
Viewing the texi doc<br />
This manpage has been automatically generated from mtools&#8217;s texinfo documentation. However, this process is only approximative, and some items, such as crossreferences, footnotes and indices are lost in this translation process. Indeed, these items have no appropriate representation in the manpage format. Moreover, not all information has been translated into the manpage version. Thus I strongly advise you to use the original texinfo doc. See the end of this manpage for instructions how to view the texinfo doc.</p>
<p>*<br />
    To generate a printable copy from the texinfo doc, run the following commands:</p>
<p>        ./configure; make dvi; dvips mtools.dvi</p>
<p>*<br />
    To generate a html copy, run:</p>
<p>        ./configure; make html</p>
<p>      A premade html can be found at: Infinityhttp://mtools.linux.luIntegral and also at: Infinityhttp://www.tux.org/pub/knaff/mtoolsIntegral<br />
*<br />
    To generate an info copy (browsable using emacs&#8217; info mode), run:</p>
<p>        ./configure; make info</p>
<p>The texinfo doc looks most pretty when printed or as html. Indeed, in the info version certain examples are difficult to read due to the quoting conventions used in info.</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Flpilinux.com%2Fmzip-command.html&amp;title=mzip%20command"><img src="http://lpilinux.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://lpilinux.com/mzip-command.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>anemone command</title>
		<link>http://lpilinux.com/anemone-command.html</link>
		<comments>http://lpilinux.com/anemone-command.html#comments</comments>
		<pubDate>Fri, 14 May 2010 04:08:18 +0000</pubDate>
		<dc:creator>lpilinuxblog</dc:creator>
				<category><![CDATA[Important for LPI 117-101]]></category>

		<guid isPermaLink="false">http://lpilinux.com/anemone-command.html</guid>
		<description><![CDATA[anemone [-display host:display.screen] [-visual visual] [-window] [-root] [-delay number] [-arms number] [-finpoints number] [-width number] DESCRIPTION Wiggling tentacles. OPTIONS -visual visual Specify which visual to use. Legal values are the name of a visual class, or the id number (decimal &#8230; <a href="http://lpilinux.com/anemone-command.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Flpilinux.com%2Fanemone-command.html"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Flpilinux.com%2Fanemone-command.html&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>anemone [-display host:display.screen] [-visual visual] [-window] [-root] [-delay number] [-arms number] [-finpoints number] [-width number]<br />
DESCRIPTION<br />
Wiggling tentacles.<br />
OPTIONS</p>
<p>-visual visual<br />
    Specify which visual to use. Legal values are the name of a visual class, or the id number (decimal or hex) of a specific visual.<br />
-window<br />
    Draw on a newly-created window. This is the default.<br />
-root<br />
    Draw on the root window.<br />
-delay number<br />
    Per-frame delay, in microseconds. Default: 40000 (0.04 seconds.).<br />
-arms number<br />
    Arms. 2 &#8211; 500. Default: 128.<br />
-finpoints number<br />
    Tentacles. 3 &#8211; 200. Default: 64.<br />
-withdraw number<br />
    Frequency that the arms withdraw. Arms withdraw on randomly generated values between 1 and 11; this value determines the maximum value of that range. So 100 spends a lot of time withdrawn, while 1000,000 tends not to withdraw at all. Default: 1200.<br />
-turnspeed number<br />
    How fast it turns. At zero, not at all, all they way up to thousands which are very fast indeed. Default: 50.<br />
-width number<br />
    Thickness. 1 &#8211; 10. Default: 2.</p>
<p>ENVIRONMENT</p>
<p>DISPLAY<br />
    to get the default host and display number.<br />
XENVIRONMENT<br />
    to get the name of a resource file that overrides the global resources stored in the RESOURCE_MANAGER property.  </p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Flpilinux.com%2Fanemone-command.html&amp;title=anemone%20command"><img src="http://lpilinux.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://lpilinux.com/anemone-command.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>alsactl &#8211; advanced controls for ALSA soundcard driver</title>
		<link>http://lpilinux.com/alsactl-advanced-controls-for-alsa-soundcard-driver.html</link>
		<comments>http://lpilinux.com/alsactl-advanced-controls-for-alsa-soundcard-driver.html#comments</comments>
		<pubDate>Thu, 13 May 2010 04:07:39 +0000</pubDate>
		<dc:creator>lpilinuxblog</dc:creator>
				<category><![CDATA[Important for LPI 117-101]]></category>

		<guid isPermaLink="false">http://lpilinux.com/alsactl-advanced-controls-for-alsa-soundcard-driver.html</guid>
		<description><![CDATA[alsactl is used to control advanced settings for the ALSA soundcard drivers. It supports multiple soundcards. If your card has features that you can&#8217;t seem to control from a mixer application, you have come to the right place. INVOKING alsactl &#8230; <a href="http://lpilinux.com/alsactl-advanced-controls-for-alsa-soundcard-driver.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Flpilinux.com%2Falsactl-advanced-controls-for-alsa-soundcard-driver.html"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Flpilinux.com%2Falsactl-advanced-controls-for-alsa-soundcard-driver.html&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>alsactl is used to control advanced settings for the ALSA soundcard drivers. It supports multiple soundcards. If your card has features that you can&#8217;t seem to control from a mixer application, you have come to the right place.</p>
<p>INVOKING</p>
<p>alsactl [options] [store|restore] <card # or id></p>
<p>Commands</p>
<p>store saves the current driver state for the selected soundcard to the configuration file.</p>
<p>restore loads driver state for the selected soundcard from the configuration file.</p>
<p>If no soundcards are specified, setup for all cards will be saved or loaded.</p>
<p>Options</p>
<p>-h, &#8211;help<br />
    Help: show available flags and commands.</p>
<p>-f, &#8211;file<br />
    Select the configuration file to use. The default is /etc/asound.state</p>
<p>-F, &#8211;force<br />
    Used with restore command. Try to restore the matching control elements as much as possible.</p>
<p>-d, &#8211;debug<br />
    Use debug mode: a bit more verbose.</p>
<p>-v, &#8211;version<br />
    Print alsactl version number.</p>
<p>FILES<br />
/etc/asound.state (or whatever file you specify with the -f flag) is used to store current settings for your soundcards. The settings include all the usual soundcard mixer settings. More importantly, alsactl is capable of controlling other card-specific features that mixer apps usually don&#8217;t know about.</p>
<p>The configuration file is generated automatically by running alsactl store. Editing the configuration file by hand may be necessary for some soundcard features (e.g. enabling/disabling automatic mic gain, digital output, joystick/game ports, some future MIDI routing options, etc). </card> </p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Flpilinux.com%2Falsactl-advanced-controls-for-alsa-soundcard-driver.html&amp;title=alsactl%20%26%238211%3B%20advanced%20controls%20for%20ALSA%20soundcard%20driver"><img src="http://lpilinux.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://lpilinux.com/alsactl-advanced-controls-for-alsa-soundcard-driver.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>mysql_fix_privilege_tables</title>
		<link>http://lpilinux.com/mysql_fix_privilege_tables.html</link>
		<comments>http://lpilinux.com/mysql_fix_privilege_tables.html#comments</comments>
		<pubDate>Wed, 12 May 2010 04:06:55 +0000</pubDate>
		<dc:creator>lpilinuxblog</dc:creator>
				<category><![CDATA[Important for LPI 117-101]]></category>

		<guid isPermaLink="false">http://lpilinux.com/mysql_fix_privilege_tables.html</guid>
		<description><![CDATA[This scripts updates the mysql.user, mysql.db, mysql.host and the mysql.func tables to MySQL 3.22.14 and above. This is needed if you want to use the new GRANT functions, CREATE AGGREGATE FUNCTION or want to use the more secure passwords in &#8230; <a href="http://lpilinux.com/mysql_fix_privilege_tables.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Flpilinux.com%2Fmysql_fix_privilege_tables.html"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Flpilinux.com%2Fmysql_fix_privilege_tables.html&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>This scripts updates the mysql.user, mysql.db, mysql.host and the mysql.func tables to MySQL 3.22.14 and above.</p>
<p>This is needed if you want to use the new GRANT functions, CREATE AGGREGATE FUNCTION or want to use the more secure passwords in 3.23</p>
<p>If you get &#8216;Access denied&#8217; errors, run the script again and give the MySQL root user password as an argument.</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Flpilinux.com%2Fmysql_fix_privilege_tables.html&amp;title=mysql_fix_privilege_tables"><img src="http://lpilinux.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://lpilinux.com/mysql_fix_privilege_tables.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Utilities to compress and uncompress files in Linux</title>
		<link>http://lpilinux.com/utilities-to-compress-and-uncompress-files-in-linux.html</link>
		<comments>http://lpilinux.com/utilities-to-compress-and-uncompress-files-in-linux.html#comments</comments>
		<pubDate>Tue, 11 May 2010 11:09:55 +0000</pubDate>
		<dc:creator>lpilinuxblog</dc:creator>
				<category><![CDATA[Important for LPI 117-101]]></category>

		<guid isPermaLink="false">http://lpilinux.com/?p=485</guid>
		<description><![CDATA[In this article, it is intended to discuss the following utilities that are used to compress and uncompress files in Linux: tar gzip &#38; gunzip bzip2 &#38; bunzip2 tar The tar (Tape Archive) utility was originally designed for tape backups. &#8230; <a href="http://lpilinux.com/utilities-to-compress-and-uncompress-files-in-linux.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Flpilinux.com%2Futilities-to-compress-and-uncompress-files-in-linux.html"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Flpilinux.com%2Futilities-to-compress-and-uncompress-files-in-linux.html&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>In this article, it is intended to discuss the following utilities that are used to compress and uncompress files in Linux:</p>
<ul>
<li>tar</li>
<li>gzip &amp; gunzip</li>
<li>bzip2 &amp; bunzip2</li>
</ul>
<p><strong>tar</strong></p>
<p>The tar (Tape Archive) utility was originally designed for tape backups. It is used to create a tar file anywhere on the filesystem. The tar utility does not compress files, but it creates one tar file out of several files and directories and keeps their absolute path information if required. Hence, a tar file takes the same amount of space as all the individual files (and folders) combined. However, a tar file can be compressed using the gzip or bzip2 utility.</p>
<p>Syntax</p>
<p><strong>tar -switch(es)</strong></p>
<p>where  is the name of the tar file.</p>
<p>Some important switches used with the tar command are as follows:</p>
<table border="1">
<tbody>
<tr>
<td>Switches</td>
<td>Description</td>
</tr>
<tr>
<td>X</td>
<td>It is used to extract the contents of a tar file.</td>
</tr>
<tr>
<td>C</td>
<td>It is used to create a tar file.</td>
</tr>
<tr>
<td>Z</td>
<td>It is used to uncompress a compressed tar file before extracting.</td>
</tr>
<tr>
<td>v</td>
<td>It is used to display the contents while creating a tar file or extracting from it.</td>
</tr>
<tr>
<td>t</td>
<td>It is used to list all the contents of a tar file.</td>
</tr>
</tbody>
</table>
<p>gzip &amp; gunzip</p>
<p>gzip and gunzip are GNU file compression and decompression utilities. The files that are compressed by gzip have a .gz extension. If a tar file is compressed by the gzip command, the file will have the .tgz extension.</p>
<p>Compressing files with the gzip command:  To compress a file, use the gzip command as shown below:</p>
<p><strong>gzip</strong></p>
<p>where  is the name of the file to be compressed.</p>
<p>After using the command, a file named filename.txt.gz will be created. By default, the gzip command will delete the filename.txt file.</p>
<p>Uncompressing files with the gunzip command: To uncompress a gzip file, execute the following command:</p>
<p><strong>gunzip</strong></p>
<p>where  is the name of the file to be uncompressed.</p>
<p>After using the command, a file named filename.txt will be created. By default, the gunzip command will delete the filename.txt.gz file.</p>
<p><strong>bzip2 &amp; bunzip2</strong></p>
<p><strong>bzip2 and bunzip2 are newer file </strong>compression and decompression utilities than gzip and gunzip. The bzip2 utility maintains greater compression ratios than gzip to keep the size of the compressed file lower. A bzip2 file can be 10-20 percent smaller than the same file zipped with the gzip utility. Files that have been compressed by bzip2 have a .bz2 extension.</p>
<p>bzip2 and bunzip2 are not as common yet, but they are rapidly gaining popularity.</p>
<p>Compressing files with the bzip command:  To compress a file, use the bzip command as shown below:</p>
<p><strong>bzip2</strong></p>
<p>where  is the name of the file to be compressed.</p>
<p>After using the command, a file named filename.txt.bz2 will be created. By default, the bzip command will delete the filename.txt file.</p>
<p>Uncompressing files with the bunzip command: To uncompress a bzip file, execute the following command:</p>
<p><strong>bunzip2</strong></p>
<p>where  is the name of the file to be uncompressed.</p>
<p>After using the command, a file named filename.txt will be created. By default, the bunzip command will delete the filename.txt.bz2 file </p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Flpilinux.com%2Futilities-to-compress-and-uncompress-files-in-linux.html&amp;title=Utilities%20to%20compress%20and%20uncompress%20files%20in%20Linux"><img src="http://lpilinux.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://lpilinux.com/utilities-to-compress-and-uncompress-files-in-linux.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>e2fsck command</title>
		<link>http://lpilinux.com/e2fsck-command.html</link>
		<comments>http://lpilinux.com/e2fsck-command.html#comments</comments>
		<pubDate>Tue, 27 Apr 2010 11:06:46 +0000</pubDate>
		<dc:creator>lpilinuxblog</dc:creator>
				<category><![CDATA[Important for LPI 117-101]]></category>

		<guid isPermaLink="false">http://lpilinux.com/?p=483</guid>
		<description><![CDATA[The e2fsck command is used to check the second extended file system (E2FS) of a Linux computer. Syntax: e2fsck [options] Where, is the file name of a mounted storage device (for example, /dev/hda1). Several options are used with the e2fsck &#8230; <a href="http://lpilinux.com/e2fsck-command.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Flpilinux.com%2Fe2fsck-command.html"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Flpilinux.com%2Fe2fsck-command.html&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>The e2fsck command is used to check the second extended file system (E2FS) of a Linux computer.</p>
<p>Syntax:</p>
<p>e2fsck [options]</p>
<p>Where,  is the file name of a mounted storage device (for example, /dev/hda1). Several options are used with the e2fsck command. Following is a list of some important options:</p>
<table border="1">
<tbody>
<tr>
<td>Option</td>
<td>Description</td>
</tr>
<tr>
<td>-p</td>
<td>This command  is used to automatically preen (repair) the file system without prompting any question to the user.</td>
</tr>
<tr>
<td valign="top">-b</td>
<td>This command uses the alternative superblock specified by . This option is normally used when the primary superblock has been corrupted.</td>
</tr>
<tr>
<td>-c</td>
<td>This option is used to find the bad blocks in a file system.</td>
</tr>
<tr>
<td>-f</td>
<td>This option is used to enforce the command to check the file system even if the file system seems clean.</td>
</tr>
</tbody>
</table>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Flpilinux.com%2Fe2fsck-command.html&amp;title=e2fsck%20command"><img src="http://lpilinux.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://lpilinux.com/e2fsck-command.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>LILO Bootloader &#8211; Full Tutorial</title>
		<link>http://lpilinux.com/lilo-bootloader-full-tutorial.html</link>
		<comments>http://lpilinux.com/lilo-bootloader-full-tutorial.html#comments</comments>
		<pubDate>Tue, 27 Apr 2010 11:01:43 +0000</pubDate>
		<dc:creator>lpilinuxblog</dc:creator>
				<category><![CDATA[Important for LPI 117-101]]></category>

		<guid isPermaLink="false">http://lpilinux.com/?p=477</guid>
		<description><![CDATA[Linux Loader (LILO) is the default boot loader (boot manager) for most Linux systems. It is used to boot a computer into Linux. LILO provides many tools for troubleshooting booting issues. It also allows a dual boot of the Linux &#8230; <a href="http://lpilinux.com/lilo-bootloader-full-tutorial.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Flpilinux.com%2Flilo-bootloader-full-tutorial.html"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Flpilinux.com%2Flilo-bootloader-full-tutorial.html&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>Linux Loader (LILO) is the default boot loader (boot manager) for most Linux systems. It is used to boot a computer into Linux. LILO provides many tools for troubleshooting booting issues. It also allows a dual boot of the Linux operating system with any other operating system. LILO uses the /etc/lilo.conf file for reading and editing its configuration information.</p>
<p>LILO does not depend on a specific file system, and can boot an operating system (e.g., Linux kernel images) from floppy disks and hard disks. One of up to sixteen different images can be selected at boot time. Various parameters, such as the root device, can be set independently for each kernel. LILO can be placed either in the master boot record (MBR) or the boot sector of a partition. In the latter case, something else must be placed in the MBR to load LILO.</p>
<p><strong>BIOS 1024 Cylinder Limit</strong></p>
<p>In the Linux operating system, a user can place the boot loader (LILO or GRUB) either into the MBR or in the root partition. This flexibility can cause a failure at boot time since the BIOS must load the boot loader into memory and start it. Since the BIOS cannot access portions of the disk beyond the 1024th cylinder, the boot loader must be within the 1024th cylinder. If the BIOS cannot read all of the boot loader, the boot fails. This is known as the BIOS 1024 cylinder limit.</p>
<p><strong>LILO.conf</strong></p>
<p>The lilo.conf file is typically located at /etc/lilo.conf.  There are two section types within lilo.conf. The first section, which defines the global options, contains parameters that specify boot location attributes. The second section contains parameters associated with the operating system images to be loaded. The section type can be repeated for up to 16 different boot selections.</p>
<p><strong>Master Boot Record</strong></p>
<p>MBR is the collection of boot records of a floppy or a hard disk that contains disk information such as disk architecture, cluster size, etc. The main work of MBR is to locate and run the necessary operating system files, which are required to run a floppy or a hard-disk. In the context of the operating system, MBR is also known as boot loader. If the boot loader is infected, the operating system will not boot.</p>
<p>LILO can write a Master Boot Record on a device using the following command syntax:</p>
<p>/sbin/lilo -M</p>
<p><strong>LILO Error Codes</strong></p>
<p>The error codes of LILO are used to identify the issues that have occurred during the loading of LILO. When LILO loads itself, it displays the word LILO. Each letter is displayed before or after performing some specific actions, which can be used to identify issues and take further actions in case LILO fails at any point. According to the Linux Documentation Project, the error codes are defined as follows:</p>
<table border="1">
<tbody>
<tr>
<td>Code</td>
<td>Description</td>
</tr>
<tr>
<td>(nothing)</td>
<td>No part of LILO has been loaded. Either LILO is not installed or the partition on which its boot sector is located is not active.</td>
</tr>
<tr>
<td>L</td>
<td>The first stage boot loader has been loaded and started, but the second stage boot loader cannot be loaded. The two-digit error codes indicate the type of issues. This condition usually indicates a media failure or a geometry mismatch (for example, bad disk parameters).</td>
</tr>
<tr>
<td>LI</td>
<td>The first stage boot loader was able to load the second stage boot loader, but it had failed to execute it. This can be caused either by a geometry mismatch or by moving /boot/boot.b without running the map installer.</td>
</tr>
<tr>
<td>LIL</td>
<td>The second stage boot loader has been started, but the descriptor table from the map file cannot be loaded. This is typically caused by a media failure or by a geometry mismatch.</td>
</tr>
<tr>
<td>LIL?</td>
<td>The second stage boot loader has been loaded at an incorrect address. This is typically caused by a subtle geometry mismatch or by moving /boot/boot.b without running the map installer.</td>
</tr>
<tr>
<td>LIL-</td>
<td>The descriptor table is corrupt. This can be caused either by a geometry mismatch or by moving/boot/map without running the map installer.</td>
</tr>
<tr>
<td>LILO</td>
<td>All parts of LILO have been successfully loaded.</td>
</tr>
</tbody>
</table>
<p>If the BIOS signals an error when LILO is trying to load a boot image, the respective error code is displayed. These codes range from 0&#215;00 through 0xbb. </p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Flpilinux.com%2Flilo-bootloader-full-tutorial.html&amp;title=LILO%20Bootloader%20%26%238211%3B%20Full%20Tutorial"><img src="http://lpilinux.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://lpilinux.com/lilo-bootloader-full-tutorial.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>What is lsattr command?</title>
		<link>http://lpilinux.com/what-is-lsattr-command.html</link>
		<comments>http://lpilinux.com/what-is-lsattr-command.html#comments</comments>
		<pubDate>Tue, 27 Apr 2010 10:59:18 +0000</pubDate>
		<dc:creator>lpilinuxblog</dc:creator>
				<category><![CDATA[Important for LPI 117-101]]></category>

		<guid isPermaLink="false">http://lpilinux.com/?p=474</guid>
		<description><![CDATA[lsattr is a command line program for listing the attributes on a Linux second extended file system (ext2). It is also a command to display attributes of devices on an AIX operating system. It displays the following attributes: don&#8217;t update &#8230; <a href="http://lpilinux.com/what-is-lsattr-command.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Flpilinux.com%2Fwhat-is-lsattr-command.html"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Flpilinux.com%2Fwhat-is-lsattr-command.html&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p><strong>lsattr is a command line program for listing the attributes on a Linux second extended file system (ext2). </strong>It is also a command to display attributes of devices on an AIX operating system. It displays the following attributes:</p>
<ul>
<li>don&#8217;t update atime (A)</li>
<li> synchronous updates (S)</li>
<li>synchronous directory updates (D)</li>
<li> append only (a)</li>
<li>compressed (c)</li>
<li>no dump (d)</li>
<li>immutable (i)</li>
<li>data journaling (j)</li>
<li>secure deletion (s)</li>
<li>top of directory hierarchy (T)</li>
<li>no tail-merging (t)</li>
<li>undeletable (u)</li>
</ul>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Flpilinux.com%2Fwhat-is-lsattr-command.html&amp;title=What%20is%20lsattr%20command%3F"><img src="http://lpilinux.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://lpilinux.com/what-is-lsattr-command.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

