{"id":188,"date":"2009-04-11T22:50:00","date_gmt":"2009-04-12T05:50:00","guid":{"rendered":"http:\/\/thesmithfam.org\/blog\/?p=188"},"modified":"2019-08-12T07:15:58","modified_gmt":"2019-08-12T13:15:58","slug":"bash-bracket-hacking","status":"publish","type":"post","link":"https:\/\/thesmithfam.org\/blog\/2009\/04\/11\/bash-bracket-hacking\/","title":{"rendered":"Bash bracket hacking"},"content":{"rendered":"<p>I am no shell scripting expert, but I have written a lot of bash code in my day. Most of my shell scripting know-how has come from trial-and-error and desperate googling. This has (slowly) taught me a few nifty tricks and some of the more interesting details of how bash actually &#8220;works&#8221; (for lack of a better word). I&#8217;d like to share one small tidbit with you now.<\/p>\n<p>The &#8220;<b>[<\/b>&#8221; program.<\/p>\n<p>No, that&#8217;s  not a mistake. There actually <b>is<\/b> a program on UNIX systems called &#8220;[&#8220;, and it generally lives in \/usr\/bin. Don&#8217;t believe me? Check out this <b>which<\/b> command:<\/p>\n<blockquote><p><code># which [<br \/>\n\/usr\/bin\/[<br \/>\n<\/code><\/p><\/blockquote>\n<p>Isn&#8217;t that odd? On some systems (namely Fedora-variants) the &#8220;[&#8221; program is actually a symbolic link (&#8220;symlink&#8221; among friends) to a program called &#8220;<b>test<\/b>&#8220;:<\/p>\n<blockquote><p><code># ls -l \/usr\/bin\/[<br \/>\nlrwxrwxrwx root    \/usr\/bin\/[ -> test<\/code><\/p><\/blockquote>\n<p>You see, every good UNIX-like OS ships with a handy utility called test (<tt>man 1 test<\/tt>). It&#8217;s a simple program that can answer questions like &#8220;is variable $foo greater than 42?&#8221;, like this:<\/p>\n<blockquote><p><code># foo=43<br \/>\n# test $foo -gt 42<br \/>\n# echo $?<br \/>\n0<br \/>\n# test $foo -lt 42<br \/>\n# echo $?<br \/>\n1<\/code><\/p><\/blockquote>\n<p>It can do a whole slew of other comparisons too, including math, string comparisons, file operations (does file $foo exist?), and a bunch of other stuff (<tt>man 1 test<\/tt> for full details)<\/p>\n<p>The &#8220;test&#8221; program gives output solely by its exit status (that&#8217;s what $? stores after you run a program in bash). That way, you can use it in bash if statements, like this:<\/p>\n<blockquote><p><code>foo=43<br \/>\nif test $foo -gt 42; then<br \/>\n&nbsp;&nbsp;    echo $foo is greater than 42<br \/>\nelse<br \/>\n&nbsp;&nbsp;    echo $foo is NOT greater than 42<br \/>\nfi<\/code><\/p><\/blockquote>\n<p>It turns out that our good UNIX forebears hated typing, so they invented the &#8220;[&#8221; program, which does exactly the same thing, but it <b>looks<\/b> a heck of a lot like a C conditional when used in shell scripts, like this:<\/p>\n<blockquote><p><code>foo=43<br \/>\nif [ $foo -gt 42 ]; then<br \/>\n&nbsp;&nbsp;    echo $foo is greater than 42<br \/>\nelse<br \/>\n&nbsp;&nbsp;    echo $foo is NOT greater than 42<br \/>\nfi<\/code><\/p><\/blockquote>\n<p>The only difference between &#8220;test&#8221; and &#8220;[&#8221; is that &#8220;[&#8221; requires you to have a matching &#8220;]&#8221; as its last argument or it complains on stderr. Isn&#8217;t that nifty? I think so. This explains why, by the way, you have to have spaces before and after the &#8220;[&#8221; and &#8220;]&#8221;. It&#8217;s because &#8220;[&#8221; is actually a program name and &#8220;]&#8221; is just a command line argument like any other argument.<\/p>\n<p>Now get back to that shell script you were hacking.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I am no shell scripting expert, but I have written a lot of bash code in my day. Most of my shell scripting know-how has come from trial-and-error and desperate googling. This has (slowly) taught me a few nifty tricks and some of the more interesting details of how bash actually &#8220;works&#8221; (for lack of [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-188","post","type-post","status-publish","format-standard","hentry","category-code-and-cruft"],"_links":{"self":[{"href":"https:\/\/thesmithfam.org\/blog\/wp-json\/wp\/v2\/posts\/188","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/thesmithfam.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/thesmithfam.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/thesmithfam.org\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/thesmithfam.org\/blog\/wp-json\/wp\/v2\/comments?post=188"}],"version-history":[{"count":21,"href":"https:\/\/thesmithfam.org\/blog\/wp-json\/wp\/v2\/posts\/188\/revisions"}],"predecessor-version":[{"id":1547,"href":"https:\/\/thesmithfam.org\/blog\/wp-json\/wp\/v2\/posts\/188\/revisions\/1547"}],"wp:attachment":[{"href":"https:\/\/thesmithfam.org\/blog\/wp-json\/wp\/v2\/media?parent=188"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/thesmithfam.org\/blog\/wp-json\/wp\/v2\/categories?post=188"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/thesmithfam.org\/blog\/wp-json\/wp\/v2\/tags?post=188"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}