{"id":1775,"date":"2014-01-25T14:55:32","date_gmt":"2014-01-25T14:55:32","guid":{"rendered":"http:\/\/blog.bachi.net\/?p=1775"},"modified":"2024-03-08T21:09:42","modified_gmt":"2024-03-08T21:09:42","slug":"bash-scripting","status":"publish","type":"post","link":"https:\/\/blog.bachi.net\/?p=1775","title":{"rendered":"Bash scripting"},"content":{"rendered":"<p><!-- -------------------------------------------------------------------------------- --><\/p>\n<h3>Keyboard shortcuts<\/h3>\n<p><a href=\"http:\/\/www.math.utah.edu\/docs\/info\/features_7.html\">Command Line Editing<\/a><br \/>\n<a href=\"https:\/\/www.gnu.org\/software\/bash\/manual\/html_node\/Commands-For-Moving.html\">Commands For Moving<\/a><br \/>\n<a href=\"http:\/\/beerpla.net\/2008\/12\/22\/mastering-the-linux-shell-bash-shortcuts-explained\/\">Mastering The Linux Shell \u2013 Bash Shortcuts Explained (Now With Cheat Sheets)<\/a><br \/>\n<a href=\"http:\/\/ss64.com\/bash\/syntax-keyboard.html\">Bash Keyboard Shortcuts<\/a><\/p>\n<pre class=\"brush: plain; title: History; notranslate\" title=\"History\">\r\n&#x5B;CTRL + P]      Print previous command (Up arrow)\r\n&#x5B;CTRL + N]      Print next command (Down arrow)\r\n&#x5B;CTRL + R]      History search\r\n&#x5B;ALT  + R]      Cancel changes, put back like in the history\r\n&#x5B;!    + !]      Repeat last command\r\n&#x5B;!    + &lt;cmd&gt;]  Run last command starting with &lt;cmd&gt;\r\n&#x5B;!    + *]      Run all argument of previous command\r\n&#x5B;!    + $]      Run last argument of previous command\r\n&#x5B;ALT  + .]      Print last argument of previous command\r\n&#x5B;^&lt;p1&gt; + ^&lt;p2&gt;] Run last command, replace &lt;p1&gt; with &lt;p2&gt;\r\n<\/pre>\n<pre class=\"brush: plain; title: Move; notranslate\" title=\"Move\">\r\n&#x5B;CTRL + F]      Move forward one character (Right arrow)\r\n&#x5B;CTRL + B]      Move backward one character (Left arrow)\r\n\r\n&#x5B;ALT  + F]      Move forward one word\r\n&#x5B;ALT  + B]      Move backward one word\r\n\r\n&#x5B;CTRL + A]      Move to the start of the line\r\n&#x5B;CTRL + E]      Move to the end of the line\r\n\r\n&#x5B;CTRL + X + X]  Toggle between start of word and cursor\r\n<\/pre>\n<pre class=\"brush: plain; title: Delete; notranslate\" title=\"Delete\">\r\n&#x5B;CTRL + H]      Delete previous character from the cursor\r\n                (= Rubout, like Backspace)\r\n&#x5B;CTRL + D]      Delete current character from the cursor (Delete)\r\n<\/pre>\n<pre class=\"brush: plain; title: Cut\/Paste; notranslate\" title=\"Cut\/Paste\">\r\n&#x5B;CTRL + K]      Cut from the cursor to the end of the line\r\n&#x5B;CTRL + U]      Cut from the cursor to the start of the line\r\n                (like &#x5B;CTRL + X + BACKSPACE]\r\n\r\n&#x5B;ALT  + D]      Cut from the cursor to the end of the current word\r\n&#x5B;CTRL + W]      Cut from the cursor to the previous whitespace\r\n\r\n&#x5B;CTRL + Y]      Paste\r\n<\/pre>\n<pre class=\"brush: plain; title: Swap\/Replace; notranslate\" title=\"Swap\/Replace\">\r\n&#x5B;ALT  + T]      Swap current word with previous (or &#x5B;ESC + T])\r\n&#x5B;CTRL + T]      Swap the last two characters before the cursor (typo)\r\n\r\n&#x5B;ALT  + U]      Upper-case word and move to the end of the word\r\n&#x5B;ALT  + L]      Lower-case word and move to the end of the word\r\n&#x5B;ALT  + C]      Capitalize word and move to the end of the word\r\n<\/pre>\n<p><!-- -------------------------------------------------------------------------------- --><\/p>\n<h3>Job ID \/ Percent sign (%)<\/h3>\n<p><a href=\"http:\/\/superuser.com\/questions\/826562\/percent-sign-in-front-of-shell-command\">Percent sign (%) in front of shell command<\/a><\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n$ tail -f \/var\/log\/messages\r\n&#x5B;CTRL + Z]\r\n&#x5B;1]+  Stopped                 tail -f \/var\/log\/messages\r\n\r\n$ tail -f \/var\/log\/maillog\r\n&#x5B;CTRL + Z]\r\n&#x5B;2]+  Stopped                 tail -f \/var\/log\/maillog\r\n\r\n$ jobs\r\n&#x5B;1]-  Stopped                 tail -f \/var\/log\/messages\r\n&#x5B;2]+  Stopped                 tail -f \/var\/log\/maillog\r\n\r\n$ fg %2\r\ntail -f \/var\/log\/maillog\r\n&#x5B;CTRL + Z]\r\n&#x5B;2]+  Stopped                 tail -f \/var\/log\/maillog\r\n\r\n$ fg %1\r\ntail -f \/var\/log\/messages\r\n&#x5B;CTRL + Z]\r\n&#x5B;1]+  Stopped                 tail -f \/var\/log\/messages\r\n\r\n$ kill %1 %2\r\n&#x5B;1]-  Terminated              tail -f \/var\/log\/messages\r\n&#x5B;2]+  Terminated              tail -f \/var\/log\/maillog\r\n<\/pre>\n<p><!-- -------------------------------------------------------------------------------- --><\/p>\n<h3><strong>Simple commands<\/strong> vs <strong>Compound commands<\/strong><\/h3>\n<p><a href=\"https:\/\/stackoverflow.com\/questions\/39199299\/what-is-the-essential-difference-between-compound-command-and-normal-command-in\">What is the essential difference between compound command and normal command in bash?<\/a><\/p>\n<p>four types of compound commands:<\/p>\n<table>\n<tr>\n<td>Funktion<\/td>\n<td>Erkl\u00e4rung<\/td>\n<\/tr>\n<tr>\n<td>Group: <code>{...;}<\/code><\/td>\n<td>can be used to group simple commands together to form a compound command.<\/td>\n<\/tr>\n<tr>\n<td>Subshell: <code>(...)<\/code><\/td>\n<td>is similar to a group except that the commands are run in subshell environment.<\/td>\n<\/tr>\n<tr>\n<td>Arithmetic Expression: <code>((..))<\/code><\/td>\n<td>a series of comma-separated arithmetic calculations may be performed.<\/td>\n<\/tr>\n<tr>\n<td>Test Command: <code>[[...]]<\/code><\/td>\n<td>advanced form of the test command.<\/td>\n<\/tr>\n<\/table>\n<p><!-- -------------------------------------------------------------------------------- --><\/p>\n<h3>Bash Brackets Quick Reference<\/h3>\n<p><a href=\"https:\/\/dev.to\/rpalo\/bash-brackets-quick-reference-4eh6\">Bash Brackets Quick Reference<\/a><br \/>\n<a href=\"https:\/\/stackoverflow.com\/questions\/2188199\/how-to-use-double-or-single-brackets-parentheses-curly-braces\">How to use double or single brackets, parentheses, curly braces<\/a><br \/>\n<a href=\"https:\/\/stackoverflow.com\/questions\/8748831\/when-do-we-need-curly-braces-around-shell-variables\">When do we need curly braces around shell variables?<\/a><br \/>\n<a href=\"https:\/\/www.baeldung.com\/linux\/bash-single-vs-double-brackets\">Differences Between Single and Double Brackets in Bash<\/a><\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n( Single Parentheses )\r\n(( Double Parentheses ))\r\n&lt;( Angle Parentheses )\r\n$( Dollar Single Parentheses )\r\n$( Dollar Single Parentheses Dollar Q )$?\r\n$(( Dollar Double Parentheses ))\r\n&#x5B; Single Square Brackets ]\r\n&#x5B;&#x5B; Double Square Brackets ]]\r\n{ Single Curly Braces }\r\n${Dollar Braces}\r\n&lt;&lt;Double Angle Heredocs\r\n<\/pre>\n<p><!-- -------------------------------------------------------------------------------- --><\/p>\n<h3>if [ ]<\/h3>\n<p>File based<\/p>\n<table border=\"1\" class=\"CALSTABLE\">\n<thead>\n<tr>\n<th align=\"LEFT\" valign=\"MIDDLE\">Primary<\/th>\n<th align=\"LEFT\" valign=\"MIDDLE\">Meaning<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td align=\"LEFT\" valign=\"MIDDLE\">[ <tt class=\"option\">-a<\/tt> <tt class=\"filename\">FILE<\/tt> ]<\/td>\n<td align=\"LEFT\" valign=\"MIDDLE\">True if <tt class=\"filename\">FILE<\/tt> exists.<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" valign=\"MIDDLE\">[ <tt class=\"option\">-b<\/tt> <tt class=\"filename\">FILE<\/tt> ]<\/td>\n<td align=\"LEFT\" valign=\"MIDDLE\">True if <tt class=\"filename\">FILE<\/tt> exists and is a block-special file.\n            <\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" valign=\"MIDDLE\">[ <tt class=\"option\">-c<\/tt> <tt class=\"filename\">FILE<\/tt> ]<\/td>\n<td align=\"LEFT\" valign=\"MIDDLE\">True if <tt class=\"filename\">FILE<\/tt> exists and is a character-special<br \/>\n                file.<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" valign=\"MIDDLE\">[ <tt class=\"option\">-d<\/tt> <tt class=\"filename\">FILE<\/tt> ]<\/td>\n<td align=\"LEFT\" valign=\"MIDDLE\">True if <tt class=\"filename\">FILE<\/tt> exists and is a directory.<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" valign=\"MIDDLE\">[ <tt class=\"option\">-e<\/tt> <tt class=\"filename\">FILE<\/tt> ]<\/td>\n<td align=\"LEFT\" valign=\"MIDDLE\">True if <tt class=\"filename\">FILE<\/tt> exists.<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" valign=\"MIDDLE\">[ <tt class=\"option\">-f<\/tt> <tt class=\"filename\">FILE<\/tt> ]<\/td>\n<td align=\"LEFT\" valign=\"MIDDLE\">True if <tt class=\"filename\">FILE<\/tt> exists and is a regular file.<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" valign=\"MIDDLE\">[ <tt class=\"option\">-g<\/tt> <tt class=\"filename\">FILE<\/tt> ]<\/td>\n<td align=\"LEFT\" valign=\"MIDDLE\">True if <tt class=\"filename\">FILE<\/tt> exists and its SGID bit is set.<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" valign=\"MIDDLE\">[ <tt class=\"option\">-h<\/tt> <tt class=\"filename\">FILE<\/tt> ]<\/td>\n<td align=\"LEFT\" valign=\"MIDDLE\">True if <tt class=\"filename\">FILE<\/tt> exists and is a symbolic link.<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" valign=\"MIDDLE\">[ <tt class=\"option\">-k<\/tt> <tt class=\"filename\">FILE<\/tt> ]<\/td>\n<td align=\"LEFT\" valign=\"MIDDLE\">True if <tt class=\"filename\">FILE<\/tt> exists and its sticky bit is set.\n            <\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" valign=\"MIDDLE\">[ <tt class=\"option\">-p<\/tt> <tt class=\"filename\">FILE<\/tt> ]<\/td>\n<td align=\"LEFT\" valign=\"MIDDLE\">True if <tt class=\"filename\">FILE<\/tt> exists and is a named pipe (FIFO).\n            <\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" valign=\"MIDDLE\">[ <tt class=\"option\">-r<\/tt> <tt class=\"filename\">FILE<\/tt> ]<\/td>\n<td align=\"LEFT\" valign=\"MIDDLE\">True if <tt class=\"filename\">FILE<\/tt> exists and is readable.<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" valign=\"MIDDLE\">[ <tt class=\"option\">-s<\/tt> <tt class=\"filename\">FILE<\/tt> ]<\/td>\n<td align=\"LEFT\" valign=\"MIDDLE\">True if <tt class=\"filename\">FILE<\/tt> exists and has a size greater than<br \/>\n                zero.<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" valign=\"MIDDLE\">[ <tt class=\"option\">-t<\/tt> <tt class=\"filename\">FD<\/tt> ]<\/td>\n<td align=\"LEFT\" valign=\"MIDDLE\">True if file descriptor <tt class=\"filename\">FD<\/tt> is open and refers to<br \/>\n                a terminal.<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" valign=\"MIDDLE\">[ <tt class=\"option\">-u<\/tt> <tt class=\"filename\">FILE<\/tt> ]<\/td>\n<td align=\"LEFT\" valign=\"MIDDLE\">True if <tt class=\"filename\">FILE<\/tt> exists and its SUID (set user ID)<br \/>\n                bit is set.<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" valign=\"MIDDLE\">[ <tt class=\"option\">-w<\/tt> <tt class=\"filename\">FILE<\/tt> ]<\/td>\n<td align=\"LEFT\" valign=\"MIDDLE\">True if <tt class=\"filename\">FILE<\/tt> exists and is writable.<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" valign=\"MIDDLE\">[ <tt class=\"option\">-x<\/tt> <tt class=\"filename\">FILE<\/tt> ]<\/td>\n<td align=\"LEFT\" valign=\"MIDDLE\">True if <tt class=\"filename\">FILE<\/tt> exists and is executable.<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" valign=\"MIDDLE\">[ <tt class=\"option\">-O<\/tt> <tt class=\"filename\">FILE<\/tt> ]<\/td>\n<td align=\"LEFT\" valign=\"MIDDLE\">True if <tt class=\"filename\">FILE<\/tt> exists and is owned by the effective<br \/>\n                user ID.<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" valign=\"MIDDLE\">[ <tt class=\"option\">-G<\/tt> <tt class=\"filename\">FILE<\/tt> ]<\/td>\n<td align=\"LEFT\" valign=\"MIDDLE\">True if <tt class=\"filename\">FILE<\/tt> exists and is owned by the effective<br \/>\n                group ID.<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" valign=\"MIDDLE\">[ <tt class=\"option\">-L<\/tt> <tt class=\"filename\">FILE<\/tt> ]<\/td>\n<td align=\"LEFT\" valign=\"MIDDLE\">True if <tt class=\"filename\">FILE<\/tt> exists and is a symbolic link.<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" valign=\"MIDDLE\">[ <tt class=\"option\">-N<\/tt> <tt class=\"filename\">FILE<\/tt> ]<\/td>\n<td align=\"LEFT\" valign=\"MIDDLE\">True if <tt class=\"filename\">FILE<\/tt> exists and has been modified since<br \/>\n                it was last read.<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" valign=\"MIDDLE\">[ <tt class=\"option\">-S<\/tt> <tt class=\"filename\">FILE<\/tt> ]<\/td>\n<td align=\"LEFT\" valign=\"MIDDLE\">True if <tt class=\"filename\">FILE<\/tt> exists and is a socket.<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" valign=\"MIDDLE\">[ <tt class=\"filename\">FILE1<\/tt> <tt class=\"option\">-nt<\/tt> <tt\n                    class=\"filename\">FILE2<\/tt> ]<\/td>\n<td align=\"LEFT\" valign=\"MIDDLE\">True if <tt class=\"filename\">FILE1<\/tt> has been changed more recently than<br \/>\n                <tt class=\"filename\">FILE2<\/tt>, or if <tt class=\"filename\">FILE1<\/tt> exists and <tt\n                    class=\"filename\">FILE2<\/tt> does not.<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" valign=\"MIDDLE\">[ <tt class=\"filename\">FILE1<\/tt> <tt class=\"option\">-ot<\/tt> <tt\n                    class=\"filename\">FILE2<\/tt> ]<\/td>\n<td align=\"LEFT\" valign=\"MIDDLE\">True if <tt class=\"filename\">FILE1<\/tt> is older than <tt\n                    class=\"filename\">FILE2<\/tt>, or is <tt class=\"filename\">FILE2<\/tt> exists and <tt\n                    class=\"filename\">FILE1<\/tt> does not.<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" valign=\"MIDDLE\">[ <tt class=\"filename\">FILE1<\/tt> <tt class=\"option\">-ef<\/tt> <tt\n                    class=\"filename\">FILE2<\/tt> ]<\/td>\n<td align=\"LEFT\" valign=\"MIDDLE\">True if <tt class=\"filename\">FILE1<\/tt> and <tt class=\"filename\">FILE2<\/tt><br \/>\n                refer to the same device and inode numbers.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>String based<\/p>\n<table border=\"1\" class=\"CALSTABLE\">\n<thead>\n<tr>\n<th align=\"LEFT\" valign=\"MIDDLE\">Primary<\/th>\n<th align=\"LEFT\" valign=\"MIDDLE\">Meaning<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td align=\"LEFT\" valign=\"MIDDLE\">[ <tt class=\"option\">-o<\/tt> OPTIONNAME ]<\/td>\n<td align=\"LEFT\" valign=\"MIDDLE\">True if shell option <span class=\"QUOTE\">&#8220;OPTIONNAME&#8221;<\/span> is enabled.\n            <\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" valign=\"MIDDLE\"><tt class=\"option\">[ -z<\/tt> STRING ]<\/td>\n<td align=\"LEFT\" valign=\"MIDDLE\">True of the length if <span class=\"QUOTE\">&#8220;STRING&#8221;<\/span> is zero.<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" valign=\"MIDDLE\"><tt class=\"option\">[ -n<\/tt> STRING ] or [ STRING ]<\/td>\n<td align=\"LEFT\" valign=\"MIDDLE\">True if the length of <span class=\"QUOTE\">&#8220;STRING&#8221;<\/span> is non-zero.<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" valign=\"MIDDLE\">[ STRING1 == STRING2 ] <\/td>\n<td align=\"LEFT\" valign=\"MIDDLE\">True if the strings are equal. <span class=\"QUOTE\">&#8220;=&#8221;<\/span> may be used<br \/>\n                instead of <span class=\"QUOTE\">&#8220;==&#8221;<\/span> for strict POSIX compliance.<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" valign=\"MIDDLE\">[ STRING1 != STRING2 ] <\/td>\n<td align=\"LEFT\" valign=\"MIDDLE\">True if the strings are not equal.<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" valign=\"MIDDLE\">[ STRING1 &lt; STRING2 ] <\/td>\n<td align=\"LEFT\" valign=\"MIDDLE\">True if <span class=\"QUOTE\">&#8220;STRING1&#8221;<\/span> sorts before <span\n                    class=\"QUOTE\">&#8220;STRING2&#8221;<\/span> lexicographically in the current locale.<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" valign=\"MIDDLE\">[ STRING1 &gt; STRING2 ] <\/td>\n<td align=\"LEFT\" valign=\"MIDDLE\">True if <span class=\"QUOTE\">&#8220;STRING1&#8221;<\/span> sorts after <span\n                    class=\"QUOTE\">&#8220;STRING2&#8221;<\/span> lexicographically in the current locale.<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" valign=\"MIDDLE\">[ ARG1 OP ARG2 ]<\/td>\n<td align=\"LEFT\" valign=\"MIDDLE\"><span class=\"QUOTE\">&#8220;OP&#8221;<\/span> is one of <tt class=\"option\">-eq<\/tt>, <tt\n                    class=\"option\">-ne<\/tt>, <tt class=\"option\">-lt<\/tt>, <tt class=\"option\">-le<\/tt>, <tt\n                    class=\"option\">-gt<\/tt> or <tt class=\"option\">-ge<\/tt>. These arithmetic binary operators return<br \/>\n                true if <span class=\"QUOTE\">&#8220;ARG1&#8221;<\/span> is equal to, not equal to, less than, less than or equal to,<br \/>\n                greater than, or greater than or equal to <span class=\"QUOTE\">&#8220;ARG2&#8221;<\/span>, respectively. <span\n                    class=\"QUOTE\">&#8220;ARG1&#8221;<\/span> and <span class=\"QUOTE\">&#8220;ARG2&#8221;<\/span> are integers.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><!-- -------------------------------------------------------------------------------- --><\/p>\n<h3>Process List (ps)<\/h3>\n<pre class=\"brush: plain; title: Linux; notranslate\" title=\"Linux\">\r\n$ ps auxf\r\n<\/pre>\n<pre class=\"brush: plain; title: FreeBSD; notranslate\" title=\"FreeBSD\">\r\n$ ps auxd\r\n<\/pre>\n<p><!-- -------------------------------------------------------------------------------- --><\/p>\n<h3>#!\/usr\/bin\/env<\/h3>\n<p><a href=\"http:\/\/www.cyberciti.biz\/tips\/finding-bash-perl-python-portably-using-env.html\">Howto Make Script More Portable With #!\/usr\/bin\/env As a Shebang<\/a><\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n#!\/usr\/bin\/env bash\r\n\r\nrather than\r\n\r\n#!\/bin\/bash\r\n<\/pre>\n<p><a href=\"http:\/\/www.gnu.org\/software\/bash\/manual\/html_node\/Bash-Conditional-Expressions.html\">Bash Conditional Expressions<\/a><br \/>\n<a href=\"http:\/\/www.gnu.org\/software\/bash\/manual\/html_node\/The-Set-Builtin.html\">The Set Builtin<\/a><\/p>\n<p><!-- -------------------------------------------------------------------------------- --><\/p>\n<h3>Glob and Wildcard<\/h3>\n<p><a href=\"https:\/\/mywiki.wooledge.org\/glob\">glob<\/a><br \/>\n<a href=\"https:\/\/mywiki.wooledge.org\/Quotes\">Quotes<\/a><br \/>\n<a href=\"https:\/\/mywiki.wooledge.org\/BashGuide\/Arrays\">Arrays<\/a><\/p>\n<p><a href=\"https:\/\/docstore.mik.ua\/orelly\/unix3\/upt\/ch33_04.htm\">What if a Wildcard Doesn&#8217;t Match?<\/a><br \/>\n<a href=\"https:\/\/unix.stackexchange.com\/questions\/597850\/why-does-using-double-brackets-to-check-if-wildcard-matched-files-exists-fa\">Why does using double brackets &#8220;[[&#8221; to check if wildcard matched files exists fail, while single brackets &#8220;[&#8221; work?<\/a><br \/>\n<a href=\"https:\/\/unix.stackexchange.com\/questions\/79301\/test-if-there-are-files-matching-a-pattern-in-order-to-execute-a-script\">Test if there are files matching a pattern in order to execute a script<\/a><br \/>\n<a href=\"https:\/\/stackoverflow.com\/questions\/2937407\/test-whether-a-glob-has-any-matches-in-bash\">Test whether a glob has any matches in Bash<\/a><br \/>\n<a href=\"https:\/\/medium.com\/@leedowthwaite\/why-most-people-only-think-they-understand-wildcards-63bb9c2024ab\">Think You Understand Wildcards? Think Again.<\/a><br \/>\n<a href=\"https:\/\/superuser.com\/questions\/519374\/how-to-handle-bash-matching-when-there-are-no-matches\">how to handle bash * matching when there are no matches?<\/a><br \/>\n<a href=\"https:\/\/stackoverflow.com\/questions\/57353542\/how-does-bash-treat-unmatched-wildcard\"><\/a><\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nshopt -s nullglob\r\nset -- *.txt\r\nif &#x5B; &quot;$#&quot; -gt 0 ]; then\r\n  .\/script &quot;$@&quot; # call script with that list of files.\r\nfi\r\n\r\n# Or with bash arrays so you can keep the arguments:\r\nfiles=( *.txt )\r\n# apply C-style boolean on member count\r\n(( ${#files&#x5B;@]} )) &amp;&amp; .\/script &quot;${files&#x5B;@]}&quot;\r\n\r\n# Or with Bash built-in function\r\ncompgen -G &quot;&lt;glob-pattern&gt;&quot;\r\n\r\nif compgen -G &quot;\/tmp\/someFiles*&quot; &gt; \/dev\/null; then\r\n    echo &quot;Some files exist.&quot;\r\nfi\r\n<\/pre>\n<p><!-- -------------------------------------------------------------------------------- --><\/p>\n<h3>Arrays<\/h3>\n<p><a href=\"https:\/\/www.gnu.org\/software\/bash\/manual\/html_node\/Arrays.html\">6.7 Arrays<\/a><br \/>\n<a href=\"https:\/\/opensource.com\/article\/18\/5\/you-dont-know-bash-intro-bash-arrays\">You don&#8217;t know Bash: An introduction to Bash arrays<\/a><\/p>\n<ul>\n<li>Any element of an array may be referenced using <code>${name[subscript]}<\/code>.<\/li>\n<li>The braces are required to avoid conflicts with the shell\u2019s filename expansion operators.<\/li>\n<li>If the subscript is <code>\u2018@\u2019<\/code> or <code>\u2018*\u2019<\/code>, the word expands to all members of the array name<\/li>\n<\/ul>\n<table>\n<tr>\n<td>Funktion<\/td>\n<td>Erkl\u00e4rung<\/td>\n<\/tr>\n<tr>\n<td><code>arr=()<\/code><\/td>\n<td>Create an empty array<\/td>\n<\/tr>\n<tr>\n<td><code>arr=(1 2 3)<\/code><\/td>\n<td>Initialize array<\/td>\n<\/tr>\n<tr>\n<td><code>${arr[2]}<\/code><\/td>\n<td>Retrieve third element<\/td>\n<\/tr>\n<tr>\n<td><code>${arr[@]}<\/code><\/td>\n<td>Retrieve all elements<\/td>\n<\/tr>\n<tr>\n<td><code>${!arr[@]}<\/code><\/td>\n<td>Retrieve array indices<\/td>\n<\/tr>\n<tr>\n<td><code>${#arr[@]}<\/code><\/td>\n<td>Calculate array size<\/td>\n<\/tr>\n<tr>\n<td><code>arr[0]=3<\/code><\/td>\n<td>Overwrite 1st element<\/td>\n<\/tr>\n<tr>\n<td><code>arr+=(4)<\/code><\/td>\n<td>Append value(s)<\/td>\n<\/tr>\n<tr>\n<td><code>arr=( $(ls) )<\/code><\/td>\n<td>Save ls output as an array of files<\/td>\n<\/tr>\n<tr>\n<td><code>${arr[@]:s:n}<\/code><\/td>\n<td>Retrieve n elements starting at index s<\/td>\n<\/tr>\n<\/table>\n<p><!-- -------------------------------------------------------------------------------- --><\/p>\n<h3>Control Structures<\/h3>\n<h4>if<\/h4>\n<p><a href=\"https:\/\/phoenixnap.com\/kb\/bash-if-statement\">Bash if elif else Statement: A Comprehensive Tutorial<\/a><\/p>\n<table>\n<tr>\n<td>Syntax<\/td>\n<td>What it is<\/td>\n<td>When to use<\/td>\n<\/tr>\n<tr>\n<td><bash>if ( <commands> )<\/bash><\/td>\n<td>Subshell executed in a subprocess<\/td>\n<td>When the commands affect the current shell or environment. The changes do not remain when the subshell completes.<\/td>\n<\/tr>\n<tr>\n<td><bash>if (( <commands> ))<\/bash><\/td>\n<td>Bash extension<\/td>\n<td>Use for arithmetic operations and C-style variable manipulation.<\/td>\n<\/tr>\n<tr>\n<td><bash>if [ <commands> ]<\/bash><\/td>\n<td>POSIX builtin<\/td>\n<td>Comparing numbers and testing whether a file exists.<\/td>\n<\/tr>\n<tr>\n<td><bash>if [[ <commands> ]]<\/bash><\/td>\n<td>Bash extension<\/td>\n<td>String matching a wildcard pattern.<\/td>\n<\/tr>\n<\/table>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\n\r\n<\/pre>\n<h4>while<\/h4>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nwhile &#x5B; ]; do\r\n  command\r\ndone\r\n\r\nwhile &#x5B;&#x5B; ]]; do\r\n  command\r\ndone\r\n\r\nwhile (( )); do\r\n  command\r\ndone\r\n<\/pre>\n<h4>until<\/h4>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nuntil &#x5B;condition]\r\ndo\r\n  block of code\r\ndone\r\n<\/pre>\n<h4>for<\/h4>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\n\r\n<\/pre>\n<p><!-- -------------------------------------------------------------------------------- --><\/p>\n<h3>Parameter<\/h3>\n<table>\n<tr>\n<td>Parameter<\/td>\n<td>Purpose<\/td>\n<\/tr>\n<tr>\n<td nowrap><code>$0, $1, $2, etc.<\/code><\/td>\n<td>Positional parameters, passed from command line to script, passed to a function, or set to a variable.<\/td>\n<\/tr>\n<tr>\n<td nowrap><code>$#<\/code><\/td>\n<td>Number of command-line arguments or positional parameters<\/td>\n<\/tr>\n<tr>\n<td nowrap><code>$*<\/code><\/td>\n<td>All of the positional parameters, seen as a single word.<\/td>\n<\/tr>\n<tr>\n<td nowrap><code>$@<\/code><\/td>\n<td>Same as $*, but each parameter is a quoted string, that is, the parameters are passed on intact, without interpretation or expansion. This means, among other things, that each parameter in the argument list is seen as a separate word.<\/td>\n<\/tr>\n<\/table>\n<table>\n<tr>\n<td>Parameter<\/td>\n<td>Purpose<\/td>\n<\/tr>\n<tr>\n<td nowrap><code>$0, $1, $2, ...<\/code><\/td>\n<td>The positional parameters starting from parameter 0. Parameter 0 refers to the name of the program that started bash, or the name of the shell script if the function is running within a shell script. See the bash man pages for information on other possibilities, such as when bash is started with the -c parameter. A string enclosed in single or double quotes will be passed as a single parameter, and the quotes will be stripped. In the case of double quotes, any shell variables such as $HOME will be expanded before the function is called. You will need to use single or double quotes to pass parameters that contain embedded blanks or other characters that might have special meaning to the shell.<\/td>\n<\/tr>\n<tr>\n<td nowrap><code>$*<\/code><\/td>\n<td>The positional parameters starting from parameter 1. If the expansion is done within double quotes, then the expansion is a single word with the first character of the IFS special variable separating the parameters, or no intervening space if IFS is null. The default IFS value is a blank, tab, and newline. If IFS is unset, then the separator used is a blank, just as for the default IFS.<\/td>\n<\/tr>\n<tr>\n<td nowrap><code>$@<\/code><\/td>\n<td>The positional parameters starting from parameter 1. If the expansion is done within double quotes, then each parameter becomes a single word, so that &#8220;$@&#8221; is equivalent to &#8220;$1&#8221; &#8220;$2&#8221; &#8230; If your parameters are likely to contain embedded blanks, you will want to use this form.<\/td>\n<\/tr>\n<tr>\n<td nowrap><code>$#<\/code><\/td>\n<td>The number of parameters, not including parameter 0.<\/td>\n<\/tr>\n<\/table>\n<p><!-- -------------------------------------------------------------------------------- --><\/p>\n<h3>Internal Variables<\/h3>\n<p><a href=\"http:\/\/tldp.org\/LDP\/abs\/html\/internalvariables.html\">Advanced Bash-Scripting Guide: 9.1. Internal Variables<\/a><\/p>\n<table>\n<tr>\n<td>Variable<\/td>\n<td>Purpose<\/td>\n<\/tr>\n<tr>\n<td nowrap><code>$BASHPID<\/code><\/td>\n<td>Process ID of the current instance of Bash. This is not the same as the $$ variable, but it often gives the same result.<\/td>\n<\/tr>\n<tr>\n<td nowrap><code>$PS1<\/code><\/td>\n<td>This is the main prompt, seen at the command-line.<\/td>\n<\/tr>\n<tr>\n<td nowrap><code>$PS2<\/code><\/td>\n<td>The secondary prompt, seen when additional input is expected. It displays as &#8220;>&#8221;.<\/td>\n<\/tr>\n<tr>\n<td nowrap><code>$PS3<\/code><\/td>\n<td>The tertiary prompt, displayed in a select loop.<\/td>\n<\/tr>\n<tr>\n<td nowrap><code>$PS4<\/code><\/td>\n<td>The quartenary prompt, shown at the beginning of each line of output when invoking a script with the -x [verbose trace] option.<\/td>\n<\/tr>\n<tr>\n<td nowrap><code>$PWD<\/code><\/td>\n<td>Working directory (directory you are in at the time).<\/td>\n<\/tr>\n<tr>\n<td nowrap><code>$OLDPWD<\/code><\/td>\n<td>Old working directory.<\/td>\n<\/tr>\n<tr>\n<td nowrap><code>$HOME<\/code><\/td>\n<td>PHome directory of the user.<\/td>\n<\/tr>\n<tr>\n<td nowrap><code>$-<\/code><\/td>\n<td>Flags passed to script.<\/td>\n<\/tr>\n<tr>\n<td nowrap><code>$!<\/code><\/td>\n<td>PID (process ID) of last job run in background.<\/td>\n<\/tr>\n<tr>\n<td nowrap><code>$_<\/code><\/td>\n<td>Special variable set to final argument of previous command executed.<\/td>\n<\/tr>\n<tr>\n<td nowrap><code>$?<\/code><\/td>\n<td>Exit status of a command, function, or the script itself.<\/td>\n<\/tr>\n<tr>\n<td nowrap><code>$$<\/code><\/td>\n<td>Process ID (PID) of the script itself. The $$ variable often finds use in scripts to construct &#8220;unique&#8221; temp file names.<\/td>\n<\/tr>\n<\/table>\n<p><a href=\"https:\/\/stackoverflow.com\/questions\/21063765\/get-pid-in-shell-bash\">get pid in shell (bash)<\/a><\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n$ ( echo $$; echo $BASHPID )\r\n11436\r\n8408\r\n<\/pre>\n<p><!-- -------------------------------------------------------------------------------- --><\/p>\n<h3>Default values<\/h3>\n<table>\n<tr>\n<td>Expansion<\/td>\n<td>Purpose<\/td>\n<\/tr>\n<tr>\n<td nowrap><code>${PARAMETER:-WORD}<\/code><\/td>\n<td>If PARAMETER is unset or null, the shell expands WORD and substitutes the result.The value of PARAMETER is not changed.<\/td>\n<\/tr>\n<tr>\n<td nowrap><code>${PARAMETER:=WORD}<\/code><\/td>\n<td>If PARAMETER is unset or null, the shell expands WORD and assigns the result to PARAMETER. This value is then substituted. You cannot assign values to positional parameters or special parameters this way.<\/td>\n<\/tr>\n<tr>\n<td nowrap><code>${PARAMETER:?WORD}<\/code><\/td>\n<td>If PARAMETER is unset or null, the shell expands WORD and writes the result to standard error. If WORD is not present a message is written instead. If the shell is not interactive, it exits.<\/td>\n<\/tr>\n<tr>\n<td nowrap><code>${PARAMETER:+WORD}<\/code><\/td>\n<td>If PARAMETER is unset or null, nothing is substituted. Otherwise the shell expands WORD and substitutes the result.<\/td>\n<\/tr>\n<\/table>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nAPP_NAME=${APP_NAME:-&quot;default_name&quot;}\r\n\r\n$ export FOO=first\r\n$ echo &quot;The ${FOO:-second} choice&quot;\r\nThe first choice\r\n\r\n$ unset FOO\r\n$ echo &quot;The ${FOO:-second} choice&quot;\r\nThe second choice\r\n\r\n$ export FOO=\r\n$ echo &quot;The ${FOO:-second} choice&quot;\r\nThe second choice\r\n<\/pre>\n<p><a href=\"http:\/\/docs.codehaus.org\/display\/ninja\/Bash+Default+Values\">Default values<\/a><br \/>\n<a href=\"http:\/\/stackoverflow.com\/questions\/4437573\/bash-assign-default-value\">bash assign default value<\/a><\/p>\n<p><!-- -------------------------------------------------------------------------------- --><\/p>\n<h3>Field splitting \/ Word splitting \/ String splitting<\/h3>\n<p><a href=\"https:\/\/unix.stackexchange.com\/questions\/26661\/what-is-word-splitting-why-is-it-important-in-shell-programming\">What is word splitting? Why is it important in shell programming?<\/a><\/p>\n<ul>\n<li>Early shells had only a single data type: strings.<\/li>\n<li>To store a list of file names in a variable, you would put spaces between them.\/li>\n<li>At the time, spaces in file names were either forbidden or widely considered Not Done.<\/li>\n<\/ul>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nlist=&quot;a b c&quot;\r\nfor entry in list; do\r\n  echo $entry\r\ndone\r\n<\/pre>\n<ul>\n<li>These days, spaces in file names are something you need to cope with<\/li>\n<li>Always use double quotes, i.e. write &#8220;$foo&#8221;, unless you understand why you need word splitting<\/li>\n<li>The term <strong>word splitting<\/strong> also called <strong>field splitting<\/strong>, because what constitutes a word (also called field) can be configured by setting the <code>IFS<\/code> variable<\/li>\n<li>By default, <code>IFS<\/code> contains basic whitespace characters (ASCII space, tab and newline)<\/li>\n<\/ul>\n<p><a href=\"https:\/\/www.baeldung.com\/linux\/bash-string-split-into-array\">How to Split a String Into an Array in Bash<\/a><\/p>\n<ul>\n<li>A <em>for loop construct<\/em> in <code>Bash<\/code> can split a <strong>string value<\/strong> and iterate over the <strong>tokens<\/strong>.<\/li>\n<li>The <em>for loop<\/em> performs <strong>string splitting<\/strong> based on the characters defined in the <strong>IFS shell variable<\/strong>.<\/li>\n<li>Splitting a string into an array is a common task.<\/li>\n<li>The sentence was split into words and the words were added to the words array correctly<\/li>\n<\/ul>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nsentence='Hello World of Linux'\r\nwords=()\r\nfor i in $sentence; do words+=($i) ; done\r\nfor word in ${words&#x5B;@]}; do echo $word ; done\r\n# Result:\r\nHello\r\nWorld\r\nof\r\nLinux\r\n<\/pre>\n<ul>\n<li>The for loop uses the characters in the <code>IFS<\/code> shell variable to split strings.<\/li>\n<li><code>IFS<\/code> stands for <strong>Internal Field Separator<\/strong> and <code>Bash<\/code> uses it to recognize fields.<\/li>\n<li>Its value defaults to <code>\" \\t\\n\"<\/code>, meaning that the shell uses the space, the tab, or the newline characters to split a string value into fields or words.<\/li>\n<\/ul>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nIFS=$IFS#\r\nprintf &quot;%q&quot; &quot;$IFS&quot;\r\n# Result\r\n' \\t\\n#'\r\n\r\nsentence='Hello#World#of#Linux'\r\nwords=()\r\nfor i in $sentence; do words+=($i) ; done\r\nfor word in ${words&#x5B;@]}; do echo $word ; done\r\n# Result:\r\nHello\r\nWorld\r\nof\r\nLinux\r\n<\/pre>\n<ul>\n<li>Finally, we can reset IFS to its initial value by removing the # character:<\/li>\n<li>We extract a three-character length substring of <code>IFS<\/code>, starting from position 0, and assigned it back to the <code>IFS<\/code> variable<\/li>\n<\/ul>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nIFS=&quot;${IFS:0:3}&quot;\r\n$ printf '%q' &quot;${IFS}&quot;\r\n# Result:\r\n' \\t\\n'\r\n<\/pre>\n<p><!-- -------------------------------------------------------------------------------- --><\/p>\n<h3>Single (&#8216;) and Double (&#8220;) Quotes<\/h3>\n<p><a href=\"https:\/\/stackoverflow.com\/questions\/6697753\/difference-between-single-and-double-quotes-in-bash\">Difference between single and double quotes in Bash<\/a><\/p>\n<p><!-- -------------------------------------------------------------------------------- --><\/p>\n<h3>Parameter Expansion<\/h3>\n<p><a href=\"http:\/\/wiki.bash-hackers.org\/syntax\/pe\">Parameter expansion<\/a><br \/>\n<a href=\"http:\/\/mywiki.wooledge.org\/BashGuide\/Parameters\">Parameter Expansion<\/a><\/p>\n<ul>\n<li>Simple usage<\/li>\n<li>Indirection<\/li>\n<li>Case modification <\/li>\n<li>Variable name expansion<\/li>\n<li>Substring removal<\/li>\n<li>Search and replace<\/li>\n<li>String length<\/li>\n<li>Substring expansion<\/li>\n<li>Use a default value<\/li>\n<li>Assign a default value<\/li>\n<li>Use an alternate value<\/li>\n<li>Display error if null or unset<\/li>\n<\/ul>\n<p><a href=\"https:\/\/tldp.org\/LDP\/abs\/html\/string-manipulation.html\">Manipulating Strings<\/a><br \/>\n<a href=\"http:\/\/stackoverflow.com\/questions\/12671406\/bash-removing-part-of-a-string\">Bash : removing part of a string<\/a> (= Parameter Expansion)<\/p>\n<h4>Substring Removal (Abschneiden von Mustern)<\/h4>\n<p>Eine gew\u00f6hnungsbed\u00fcrftige, aber doch sehr nette Funktion ist das Herausschneiden bestimmter Muster aus der Zeichenkette einer Variablen.<\/p>\n<table>\n<tr>\n<td>Funktion<\/td>\n<td>Erkl\u00e4rung<\/td>\n<\/tr>\n<tr>\n<td><code>${variable%muster}<\/code><\/td>\n<td>Entfernt rechts das kleinste passende St\u00fcck.<\/td>\n<\/tr>\n<tr>\n<td><code>${variable%%muster}<\/code><\/td>\n<td>Entfernt rechts das gr\u00f6\u00dfte passende St\u00fcck.<\/td>\n<\/tr>\n<tr>\n<td><code>${variable#muster}<\/code><\/td>\n<td>Entfernt links das kleinste passende St\u00fcck.<\/td>\n<\/tr>\n<tr>\n<td><code>${variable##muster}<\/code><\/td>\n<td>Entfernt links das gr\u00f6\u00dfte passende St\u00fcck.<\/td>\n<\/tr>\n<\/table>\n<pre class=\"brush: plain; title: Substring removal; notranslate\" title=\"Substring removal\">\r\nFrom the beginning:\r\npath1=&quot;\/usr\/local\/bin\/bash&quot;\r\n${PARAMETER#PATTERN}  =&gt; shortest matching: ${path1#\/*}  =&gt; usr\/local\/bin\/bash\r\n${PARAMETER##PATTERN} =&gt; longest matching:  ${path1##*\/} =&gt; bash\r\n\r\nFrom the end:\r\npath2=&quot;x\/usr\/local\/bin\/bash&quot;\r\n${PARAMETER%PATTERN}  =&gt; shortest matching: ${path2%\/*}  =&gt; x\/usr\/local\/bin\r\n${PARAMETER%%PATTERN} =&gt; longest matching:  ${path2%%\/*} =&gt; x\r\n\r\nvar=&quot;Memory Used: 19.54M&quot;\r\nvar=${var#*: }            # Remove everything up to a colon and space\r\nvar=${var%M}              # Remove the M at the end\r\n<\/pre>\n<h4>Substring Replacement<\/h4>\n<table>\n<tr>\n<td>Funktion<\/td>\n<td>Erkl\u00e4rung<\/td>\n<\/tr>\n<tr>\n<td><code>${string\/substring\/replacement}<\/code><\/td>\n<td>Replace first match of $substring with $replacement.<\/td>\n<\/tr>\n<tr>\n<td><code>${string\/\/substring\/replacement}<\/code><\/td>\n<td>Replace all matches of $substring with $replacement.<\/td>\n<\/tr>\n<tr>\n<td><code>${string\/#substring\/replacement}<\/code><\/td>\n<td>If $substring matches front end of $string, substitute $replacement for $substring.<\/td>\n<\/tr>\n<tr>\n<td><code>${string\/%substring\/replacement}<\/code><\/td>\n<td>If $substring matches back end of $string, substitute $replacement for $substring.<\/td>\n<\/tr>\n<\/table>\n<pre class=\"brush: bash; title: Substring Replacement; notranslate\" title=\"Substring Replacement\">\r\nstringZ=abcABC123ABCabc\r\n\r\necho ${stringZ\/#abc\/XYZ}          # XYZABC123ABCabc\r\n                                  # Replaces front-end match of 'abc' with 'XYZ'.\r\n\r\necho ${stringZ\/%abc\/XYZ}          # abcABC123ABCXYZ\r\n                                  # Replaces back-end match of 'abc' with 'XYZ'.\r\n<\/pre>\n<p><!-- -------------------------------------------------------------------------------- --><\/p>\n<h3>Lists of Commands, Command Sequences<\/h3>\n<p><a href=\"http:\/\/www.gnu.org\/software\/bash\/manual\/html_node\/Lists.html#Lists\">Lists of Commands<\/a><br \/>\n<a href=\"http:\/\/innovationsts.com\/?p=1896\">Writing Better Shell Scripts \u2013 Part 2<\/a><br \/>\n<a href=\"http:\/\/stackoverflow.com\/questions\/16357755\/meaning-of-colon-in-bash-after-a-double-pipe\">Meaning of colon in Bash after a double pipe<\/a><br \/>\n<a href=\"http:\/\/www.gnu.org\/software\/bash\/manual\/html_node\/Bourne-Shell-Builtins.html#index-_003a\">Bourne Shell Builtins<\/a><br \/>\n<a href=\"http:\/\/serverfault.com\/questions\/373052\/is-there-a-difference-between-how-two-ampersands-and-a-semi-colon-operate-in-bas\">Is there a difference between how two ampersands and a semi-colon operate in bash?<\/a><\/p>\n<ul>\n<li>Two logical short-circuits are the double ampersand (&#038;&#038;) and double pipe (||) operators.<\/li>\n<li>The &#038;&#038; only allows the command that comes after it in the series to be executed if the previous command exited with a status of 0.<\/li>\n<li>The || operator does the opposite by only allowing the next command to be executed if the previous one returned a non-zero exit status.<\/li>\n<li>The ; just separates one command from another.<\/li>\n<li>The : is a null statement, so it does nothing.<\/li>\n<li>The . executes a script in the current shell, not starting a new shell<\/li>\n<\/ul>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\n$ true; echo $?\r\n0\r\n\r\n$ false; echo $?\r\n1\r\n\r\n\r\n=== &amp;&amp; ===\r\n$ true &amp;&amp; echo &quot;hello&quot;\r\nhello\r\n\r\n$ false &amp;&amp; echo &quot;hello&quot;\r\n&lt;no output&gt;\r\n\r\n\r\n=== || ===\r\n$ true || echo &quot;hello&quot;\r\n&lt;no output&gt;\r\n\r\n$ false || echo &quot;hello&quot;\r\nhello\r\n\r\n\r\n=== ; ===\r\n$ true; echo &quot;hallo&quot;\r\nhallo\r\n\r\n$ false; echo &quot;hallo&quot;\r\nhallo\r\n\r\n\r\n=======================\r\n\r\n&#x5B; -n STRING ] =&gt; True if the length of &quot;STRING&quot; is non-zero.\r\n\r\n=== return value ===\r\n$ &#x5B; -n &quot;hallo&quot; ]; echo $?\r\n0\r\n\r\n$ &#x5B; -n &quot;&quot; ]; echo $?\r\n1\r\n\r\n\r\n=== if then ===\r\n$ if &#x5B; -n &quot;hallo&quot; ]; then echo &quot;welt&quot;; fi\r\nwelt\r\n\r\n$ if &#x5B; -n &quot;&quot; ]; then echo &quot;welt&quot;; fi\r\n&lt;no output&gt;\r\n\r\n\r\n=== &amp;&amp; ===\r\n$ &#x5B; -n &quot;hallo&quot; ] &amp;&amp; echo &quot;welt&quot;\r\nwelt\r\n\r\n$ &#x5B; -n &quot;&quot; ] &amp;&amp; echo &quot;welt&quot;\r\n&lt;no output&gt;\r\n\r\n\r\n=== || ===\r\n$ &#x5B; -n &quot;hallo&quot; ] || echo &quot;welt&quot;\r\n&lt;no output&gt;\r\n\r\n$ &#x5B; -n &quot;&quot; ] || echo &quot;welt&quot;\r\nwelt\r\n<\/pre>\n<pre class=\"brush: bash; title: Not a good test for exception:; notranslate\" title=\"Not a good test for exception:\">\r\ntestfunc() {\r\n    return $1\r\n}\r\n\r\n{\r\n    echo &quot;success&quot;\r\n    testfunc 0\r\n    echo &quot;success&quot;\r\n    testfunc 0\r\n    echo &quot;failure&quot;\r\n    testfunc 4\r\n} &amp;&amp; {\r\n    echo &quot;good 1&quot;\r\n} || {\r\n    echo &quot;exception 1&quot;\r\n}\r\n# Result:\r\nexception 1\r\n\r\n{\r\n    echo &quot;success&quot;\r\n    testfunc 0\r\n    echo &quot;success&quot;\r\n    testfunc 0\r\n    echo &quot;failure&quot;\r\n    testfunc 4\r\n    echo &quot;success&quot;\r\n    testfunc 0\r\n} &amp;&amp; {\r\n    echo &quot;good 2&quot;\r\n} || {\r\n    echo &quot;exception 2&quot;\r\n}\r\n# Result\r\ngood 2\r\n\r\n# Just test the last function!\r\n<\/pre>\n<p><!-- -------------------------------------------------------------------------------- --><\/p>\n<h3>Bang dollar-sign<\/h3>\n<p><a href=\"http:\/\/samrowe.com\/wordpress\/advancing-in-the-bash-shell\/\">Advancing in the Bash Shell<\/a><\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n$ .\/app a b c d e f\r\n\r\n$ !*\r\na b c d e f\r\n-bash: a: command not found\r\n\r\n$ !$\r\nf\r\n-bash: f: command not found\r\n<\/pre>\n<p><!-- -------------------------------------------------------------------------------- --><\/p>\n<h3>Brace Expansion<\/h3>\n<p><a href=\"http:\/\/samrowe.com\/wordpress\/advancing-in-the-bash-shell\/\">Advancing in the Bash Shell<\/a><\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n$ cp filename filename-old\r\n$ cp filename-old filename\r\n<\/pre>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n$ cp filename{,-old}\r\n$ cp filename{-old,}\r\n$ cp filename{-v1,-v2}\r\n<\/pre>\n<p><!-- -------------------------------------------------------------------------------- --><\/p>\n<h3>Arithmetic Expansion<\/h3>\n<p><a href=\"https:\/\/phoenixnap.com\/kb\/bash-math\">Bash Math Operations (Bash Arithmetic) Explained<\/a><\/p>\n<ul>\n<li>No <code>$<\/code> in Arithmetic Expansion&#8230;<\/li>\n<li>&#8230; except that you want to assign\/output\/store it in the script<\/li>\n<li>Compound notation <code>(())<\/code> which evaluates the expression<\/li>\n<li>The variable operator <code>$<\/code> to store the result<\/li>\n<\/ul>\n<pre class=\"brush: bash; title: Math with Integers; notranslate\" title=\"Math with Integers\">\r\n$((expression))\r\n\r\necho $((2+3))\r\n# Result\r\n5\r\n\r\necho $((x=2, y=3, x+y))\r\n# Result\r\n5\r\n\r\n((x=2, y=3, a=x+y, b=x*y, c=x**y)); echo $a, $b, $c\r\n# Result\r\n5, 6, 7\r\n<\/pre>\n<pre class=\"brush: bash; title: Incrementing and Decrementing; notranslate\" title=\"Incrementing and Decrementing\">\r\nnumber=1\r\necho $((++number))\r\necho $number\r\n# Result\r\n2\r\n2\r\n\r\nnumber=1\r\necho $((number++))\r\necho $number\r\n# Result\r\n1\r\n2\r\n\r\nnumber=1\r\n((number=number+2))\r\necho $number\r\n# Result\r\n3\r\n<\/pre>\n<pre class=\"brush: bash; title: if and while; notranslate\" title=\"if and while\">\r\nnumber=1\r\nif ((number &gt; 0)); then\r\n  echo &quot;hurra!&quot;\r\nfi\r\n\r\nidx=0\r\ncount=3\r\nwhile ((idx &lt; count)); do\r\n  echo $idx\r\n  ((idx++))\r\ndone\r\n<\/pre>\n<p><!-- -------------------------------------------------------------------------------- --><\/p>\n<h3>Process Substitution<\/h3>\n<ul>\n<li><strong>pipe<\/strong>. Passes the output (stdout) of a previous command to the input (<code>stdin<\/code>) of the next one, or to the shell. This is a method of chaining commands together.<\/li>\n<li><strong>redirection<\/strong>. <code>scriptname >filename<\/code> redirects the output of <code>scriptname<\/code> to file <code>filename<\/code><\/li>\n<li><strong>process substitution<\/strong>.<\/li>\n<\/ul>\n<p><a href=\"https:\/\/tldp.org\/LDP\/abs\/html\/process-sub.html\">Chapter 23. Process Substitution<\/a><br \/>\n<a href=\"https:\/\/tecadmin.net\/bash-process-substitution\/\">A Comprehensive Guide to Process Substitution in Bash<\/a><\/p>\n<p><!-- -------------------------------------------------------------------------------- --><\/p>\n<h3>Exit code<\/h3>\n<p><a href=\"http:\/\/tldp.org\/LDP\/abs\/html\/exit-status.html\">Exit and Exit Status<\/a><br \/>\n<a href=\"http:\/\/tldp.org\/LDP\/abs\/html\/exitcodes.html\">Exit Codes With Special Meanings<\/a><br \/>\n<a href=\"http:\/\/bencane.com\/2014\/09\/02\/understanding-exit-codes-and-how-to-use-them-in-bash-scripts\/\">Understanding Exit Codes and how to use them in bash scripts<\/a><\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n$ bla\r\n-bash: bla: command not found\r\n\r\n$ echo $?\r\n127\r\n<\/pre>\n<table class=\"CALSTABLE\" border=\"1\">\n<thead>\n<tr>\n<th align=\"LEFT\" valign=\"TOP\">Exit Code Number<\/th>\n<th align=\"LEFT\" valign=\"TOP\">Meaning<\/th>\n<th align=\"LEFT\" valign=\"TOP\">Example<\/th>\n<th align=\"LEFT\" valign=\"TOP\">Comments<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td align=\"LEFT\" valign=\"TOP\"><tt class=\"OPTION\">1<\/tt><\/td>\n<td align=\"LEFT\" valign=\"TOP\">Catchall for general errors<\/td>\n<td align=\"LEFT\" valign=\"TOP\">let &#8220;var1 = 1\/0&#8221;<\/td>\n<td align=\"LEFT\" valign=\"TOP\">Miscellaneous errors, such as <span class=\"QUOTE\">&#8220;divide by<br \/>\n\t        zero&#8221;<\/span> and other impermissible operations<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" valign=\"TOP\"><tt class=\"OPTION\">2<\/tt><\/td>\n<td align=\"LEFT\" valign=\"TOP\">Misuse of shell builtins (according to Bash documentation)<\/td>\n<td align=\"LEFT\" valign=\"TOP\">empty_function() {}<\/td>\n<td align=\"LEFT\" valign=\"TOP\"><a href=\"debugging.html#MISSINGKEYWORD\">Missing keyword<\/a><br \/>\n              or command, or permission problem (and <a href=\"filearchiv.html#DIFFERR2\"><i class=\"FIRSTTERM\">diff<\/i> return code<br \/>\n\t      on a failed binary file comparison<\/a>).<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" valign=\"TOP\"><tt class=\"OPTION\">126<\/tt><\/td>\n<td align=\"LEFT\" valign=\"TOP\">Command invoked cannot execute<\/td>\n<td align=\"LEFT\" valign=\"TOP\">\/dev\/null<\/td>\n<td align=\"LEFT\" valign=\"TOP\">Permission problem or command is not an executable<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" valign=\"TOP\"><tt class=\"OPTION\">127<\/tt><\/td>\n<td align=\"LEFT\" valign=\"TOP\"><span class=\"QUOTE\">&#8220;command not found&#8221;<\/span><\/td>\n<td align=\"LEFT\" valign=\"TOP\">illegal_command<\/td>\n<td align=\"LEFT\" valign=\"TOP\">Possible problem with <tt class=\"VARNAME\">$PATH<\/tt> or a typo<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" valign=\"TOP\"><tt class=\"OPTION\">128<\/tt><\/td>\n<td align=\"LEFT\" valign=\"TOP\">Invalid argument to <a href=\"exit-status.html#EXITCOMMANDREF\">exit<\/a><\/td>\n<td align=\"LEFT\" valign=\"TOP\">exit 3.14159<\/td>\n<td align=\"LEFT\" valign=\"TOP\"><b class=\"COMMAND\">exit<\/b> takes only integer args in the<br \/>\n\t\trange <span class=\"RETURNVALUE\">0 &#8211; 255<\/span> (see<br \/>\n\t\tfirst footnote)<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" valign=\"TOP\"><tt class=\"OPTION\">128+n<\/tt><\/td>\n<td align=\"LEFT\" valign=\"TOP\">Fatal error signal <span class=\"QUOTE\">&#8220;n&#8221;<\/span><\/td>\n<td align=\"LEFT\" valign=\"TOP\"><i class=\"FIRSTTERM\">kill -9<\/i> <tt class=\"VARNAME\">$PPID<\/tt> of script<\/td>\n<td align=\"LEFT\" valign=\"TOP\"><tt class=\"USERINPUT\"><b>$?<\/b><\/tt> returns<br \/>\n\t      <span class=\"ERRORCODE\">137<\/span> (128 + 9)<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" valign=\"TOP\"><tt class=\"OPTION\">130<\/tt><\/td>\n<td align=\"LEFT\" valign=\"TOP\">Script terminated by Control-C<\/td>\n<td align=\"LEFT\" valign=\"TOP\"><em>Ctl-C<\/em><\/td>\n<td align=\"LEFT\" valign=\"TOP\">Control-C is fatal error signal<br \/>\n\t      <span class=\"ERRORCODE\">2<\/span>, (130 = 128 + 2, see above)<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" valign=\"TOP\"><tt class=\"OPTION\">255*<\/tt><\/td>\n<td align=\"LEFT\" valign=\"TOP\">Exit status out of range<\/td>\n<td align=\"LEFT\" valign=\"TOP\">exit <span class=\"RETURNVALUE\">-1<\/span><\/td>\n<td align=\"LEFT\" valign=\"TOP\"><b class=\"COMMAND\">exit<\/b> takes only integer args in the<br \/>\n\t        range <span class=\"ERRORCODE\">0 &#8211; 255<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n","protected":false},"excerpt":{"rendered":"<p>Keyboard shortcuts Command Line Editing Commands For Moving Mastering The Linux Shell \u2013 Bash Shortcuts Explained (Now With Cheat Sheets) Bash Keyboard Shortcuts &#x5B;CTRL + P] Print previous command (Up arrow) &#x5B;CTRL + N] Print next command (Down arrow) &#x5B;CTRL + R] History search &#x5B;ALT + R] Cancel changes, put back like in the history [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1775","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/blog.bachi.net\/index.php?rest_route=\/wp\/v2\/posts\/1775","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.bachi.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.bachi.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.bachi.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.bachi.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1775"}],"version-history":[{"count":39,"href":"https:\/\/blog.bachi.net\/index.php?rest_route=\/wp\/v2\/posts\/1775\/revisions"}],"predecessor-version":[{"id":14471,"href":"https:\/\/blog.bachi.net\/index.php?rest_route=\/wp\/v2\/posts\/1775\/revisions\/14471"}],"wp:attachment":[{"href":"https:\/\/blog.bachi.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1775"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.bachi.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1775"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.bachi.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1775"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}