|
33 | 33 | echo is /bin/echo |
34 | 34 | </code></pre><p>As seen in the above result, the builtin command takes priority, so that is the default version.<p><strong>2)</strong> What output do you get for the command shown below? Does the documentation help understand the result?<pre><code class=language-bash>$ echo apple 42 'banana 100' |
35 | 35 | apple 42 banana 100 |
36 | | -</code></pre><p>Yes, the documentation helps to understand the above result. From <code>help echo</code> (since the builtin version is the default):<blockquote><p>Display the ARGs, separated by a single space character and followed by a newline, on the standard output.</blockquote><p>In the above command, there are three arguments passed to the <code>echo</code> command — <code>apple</code>, <code>42</code> and <code>'banana 100'</code>. The string represented by these arguments are displayed in the output separated by a single space character.<p><strong>3)</strong> Go through <a href=https://www.gnu.org/software/bash/manual/html_node/Tilde-Expansion.html>bash manual: Tilde Expansion</a>. Is <code>~/projects</code> a relative or an absolute path? See <a href=https://unix.stackexchange.com/q/221970/109046>this unix.stackexchange thread</a> for answers.<p>I do not much care if it is correct to call it a relative or absolute path. More importantly, I want to highlight this gotcha from the above unix.stackexchange thread:<blockquote><p><code>~</code> is syntax implemented by the shell (and other programs which imitate it for convenience) which expands it into a real pathname. To illustrate, <code>~/Documents</code> is approximately the same thing as <code>$HOME/Documents</code> (again, shell syntax). Since <code>$HOME</code> should be an absolute path, the value of <code>$HOME/Documents</code> is also an absolute path. But the text <code>$HOME/Documents</code> or <code>~/Documents</code> has to be expanded by the shell in order to become the path we mean.</blockquote><p>I spent a frustrating few hours trying to debug why one of my <a href=https://wiki.archlinux.org/title/Autostarting>autostart</a> script wasn't working. Yup, you guessed it. I used <code>~</code> while providing a file path.<p><strong>4)</strong> Which key would you use to get help while the <code>less</code> command is active?<p><code>h</code><p><strong>5)</strong> How would you bring the 50th line to the top of the screen while viewing a <code>man</code> page (assume <code>less</code> command is the <code>pager</code>)?<p><code>50g</code><p><strong>6)</strong> What does the <code>Ctrl+k</code> shortcut do?<p>Deletes from the current character to the end of the command line.<p><strong>7)</strong> Briefly explain the role of the following shell operators:<p><em>a)</em> <code>|</code> — redirects output from a command as input to another command<br> <em>b)</em> <code>></code> — redirects output from a command to a file (overwrites if the file already exists)<br> <em>c)</em> <code>>></code> — redirects output from a command to a file (appends if the file already exists)<p><strong>8)</strong> The <code>whatis</code> command displays one-line descriptions about commands. But it doesn't seem to work for <code>whatis type</code>. What should you use instead?<pre><code class=language-bash>$ whatis cat |
| 36 | +</code></pre><p>Yes, the documentation helps to understand the above result. From <code>help echo</code> (since the builtin version is the default):<blockquote><p>Display the ARGs, separated by a single space character and followed by a newline, on the standard output.</blockquote><p>In the above command, there are three arguments passed to the <code>echo</code> command — <code>apple</code>, <code>42</code> and <code>'banana 100'</code>. The string represented by these arguments are displayed in the output separated by a single space character.<p><strong>3)</strong> Go through <a href=https://www.gnu.org/software/bash/manual/html_node/Tilde-Expansion.html>bash manual: Tilde Expansion</a>. Is <code>~/projects</code> a relative or an absolute path? See <a href=https://unix.stackexchange.com/q/221970/109046>this unix.stackexchange thread</a> for answers.<p>I do not much care if it is correct to call it a relative or absolute path. More importantly, I want to highlight this gotcha from the above unix.stackexchange thread:<blockquote><p><code>~</code> is syntax implemented by the shell (and other programs which imitate it for convenience) which expands it into a real pathname. To illustrate, <code>~/Documents</code> is approximately the same thing as <code>$HOME/Documents</code> (again, shell syntax). Since <code>$HOME</code> should be an absolute path, the value of <code>$HOME/Documents</code> is also an absolute path. But the text <code>$HOME/Documents</code> or <code>~/Documents</code> has to be expanded by the shell in order to become the path we mean.</blockquote><p>I spent a frustrating few hours trying to debug why one of my <a href=https://wiki.archlinux.org/title/Autostarting>autostart</a> script wasn't working. Yup, you guessed it. The issue was using <code>~</code> and changing to the full path fixed it.<p><strong>4)</strong> Which key would you use to get help while the <code>less</code> command is active?<p><code>h</code><p><strong>5)</strong> How would you bring the 50th line to the top of the screen while viewing a <code>man</code> page (assume <code>less</code> command is the <code>pager</code>)?<p><code>50g</code><p><strong>6)</strong> What does the <code>Ctrl+k</code> shortcut do?<p>Deletes from the current character to the end of the command line.<p><strong>7)</strong> Briefly explain the role of the following shell operators:<p><em>a)</em> <code>|</code> — redirects output from a command as input to another command<br> <em>b)</em> <code>></code> — redirects output from a command to a file (overwrites if the file already exists)<br> <em>c)</em> <code>>></code> — redirects output from a command to a file (appends if the file already exists)<p><strong>8)</strong> The <code>whatis</code> command displays one-line descriptions about commands. But it doesn't seem to work for <code>whatis type</code>. What should you use instead?<pre><code class=language-bash>$ whatis cat |
37 | 37 | cat (1) - concatenate files and print on the standard output |
38 | 38 |
|
39 | 39 | $ whatis type |
|
142 | 142 |
|
143 | 143 | $ ls -1F |
144 | 144 | quest/ |
145 | | -</code></pre><p><strong>17)</strong> What does the <code>-f</code> option of <code>rm</code> command do?<blockquote><p><code>-f, --force</code><p>ignore nonexistent files and arguments, never prompt</blockquote><p>It also helps to remove write protected files (provided you have appropriate permissions to delete those files).<p><strong>18)</strong> Which option would you use to interactively delete files using the <code>rm</code> command?<blockquote><p><code>-i</code><p>prompt before every removal<p><code>-I</code><p>prompt once before removing more than three files, or when removing recursively; less intrusive than <code>-i</code>, while still giving protection against most mistakes</blockquote><p><strong>19)</strong> Can the files removed by <code>rm</code> easily be restored? Do you need to take some extra steps or use special commands to make the files more difficult to recover?<ul><li>Files removed using <code>rm</code> can still be recovered with time and skill <ul><li><a href=https://unix.stackexchange.com/q/80270/109046>unix.stackexchange: recover deleted files</a><li><a href=https://unix.stackexchange.com/q/2677/109046>unix.stackexchange: recovering accidentally deleted files</a></ul><li>Use commands like <code>shred</code> if you want to make it harder to recover deleted files <ul><li><a href=https://wiki.archlinux.org/title/Securely_wipe_disk>wiki.archlinux: Securely wipe disk</a></ul></ul><p><strong>20)</strong> Does your Linux distribution provide a tool to send deleted files to the trash (which would help to recover deleted files)?<p>On Ubuntu, you can use <code>sudo apt install trash-cli</code> to install the <code>trash</code> command. See also <a href=https://wiki.archlinux.org/title/Trash_management>wiki.archlinux: Trash management</a>.<p><strong>21)</strong> Which option would you use to interactively accept/prevent the <code>cp</code> command from overwriting a file of the same name? And which option would prevent overwriting without needing manual confirmation?<blockquote><p><code>-i, --interactive</code><p>prompt before overwrite (overrides a previous -n option)<p><code>-n, --no-clobber</code><p>do not overwrite an existing file (overrides a previous -i option)</blockquote><p><strong>22)</strong> Does the <code>cp</code> command allow you to rename the file or directory being copied? If so, can you rename multiple files/directories being copied?<p><code>cp</code> allows renaming single file or directory by specifying a different name in the destination path. You can't rename multiple files or directories.<p><strong>23)</strong> What do the <code>-u</code>, <code>-b</code> and <code>-t</code> options of <code>cp</code> command do?<blockquote><p><code>-u, --update</code><p>copy only when the SOURCE file is newer than the destination file or when the destination file is missing<p><code>--backup[=CONTROL]</code><p>make a backup of each existing destination file<p><code>-b</code><p>like <code>--backup</code> but does not accept an argument<p><code>-t, --target-directory=DIRECTORY</code><p>copy all SOURCE arguments into DIRECTORY</blockquote><p><strong>24)</strong> What's the difference between the two commands shown below?<pre><code class=language-bash>$ cp ip.txt op.txt |
| 145 | +</code></pre><p><strong>17)</strong> What does the <code>-f</code> option of <code>rm</code> command do?<blockquote><p><code>-f, --force</code><p>ignore nonexistent files and arguments, never prompt</blockquote><p>For example, it helps to remove write protected files (provided you have appropriate permissions to delete those files).<p><strong>18)</strong> Which option would you use to interactively delete files using the <code>rm</code> command?<blockquote><p><code>-i</code><p>prompt before every removal<p><code>-I</code><p>prompt once before removing more than three files, or when removing recursively; less intrusive than <code>-i</code>, while still giving protection against most mistakes</blockquote><p><strong>19)</strong> Can the files removed by <code>rm</code> easily be restored? Do you need to take some extra steps or use special commands to make the files more difficult to recover?<ul><li>Files removed using <code>rm</code> can still be recovered with time and skill <ul><li><a href=https://unix.stackexchange.com/q/80270/109046>unix.stackexchange: recover deleted files</a><li><a href=https://unix.stackexchange.com/q/2677/109046>unix.stackexchange: recovering accidentally deleted files</a></ul><li>Use commands like <code>shred</code> if you want to make it harder to recover deleted files <ul><li><a href=https://wiki.archlinux.org/title/Securely_wipe_disk>wiki.archlinux: Securely wipe disk</a></ul></ul><p><strong>20)</strong> Does your Linux distribution provide a tool to send deleted files to the trash (which would help to recover deleted files)?<p>On Ubuntu, you can use <code>sudo apt install trash-cli</code> to install the <code>trash</code> command. See also <a href=https://wiki.archlinux.org/title/Trash_management>wiki.archlinux: Trash management</a>.<p><strong>21)</strong> Which option would you use to interactively accept/prevent the <code>cp</code> command from overwriting a file of the same name? And which option would prevent overwriting without needing manual confirmation?<blockquote><p><code>-i, --interactive</code><p>prompt before overwrite (overrides a previous -n option)<p><code>-n, --no-clobber</code><p>do not overwrite an existing file (overrides a previous -i option)</blockquote><p><strong>22)</strong> Does the <code>cp</code> command allow you to rename the file or directory being copied? If so, can you rename multiple files/directories being copied?<p><code>cp</code> allows renaming single file or directory by specifying a different name in the destination path. You can't rename multiple files or directories with a single <code>cp</code> usage.<p><strong>23)</strong> What do the <code>-u</code>, <code>-b</code> and <code>-t</code> options of <code>cp</code> command do?<blockquote><p><code>-u, --update</code><p>copy only when the SOURCE file is newer than the destination file or when the destination file is missing<p><code>--backup[=CONTROL]</code><p>make a backup of each existing destination file<p><code>-b</code><p>like <code>--backup</code> but does not accept an argument<p><code>-t, --target-directory=DIRECTORY</code><p>copy all SOURCE arguments into DIRECTORY</blockquote><p><strong>24)</strong> What's the difference between the two commands shown below?<pre><code class=language-bash>$ cp ip.txt op.txt |
146 | 146 |
|
147 | 147 | $ mv ip.txt op.txt |
148 | 148 | </code></pre><ul><li><code>cp</code> makes a new copy of <code>ip.txt</code> named as <code>op.txt</code> — two files having the same content<li><code>mv</code> renames <code>ip.txt</code> as <code>op.txt</code> — there's only one file</ul><p><strong>25)</strong> Which option would you use to interactively accept/prevent the <code>mv</code> command from overwriting a file of the same name?<blockquote><p><code>-i, --interactive</code><p>prompt before overwrite</blockquote><p><strong>26)</strong> Use one or more commands to match the scenario shown below. You should have already created this directory structure in an earlier exercise.<pre><code class=language-bash>$ tree -F |
|
489 | 489 | # alternate solutions, but these won't scale well with more conditions |
490 | 490 | $ echo "$words" | grep -ow 's\w*t\w*' | grep 'e' |
491 | 491 | $ echo "$words" | grep -owE 's\w*(t\w*e|e\w*t)\w*' |
492 | | -</code></pre><p><strong>11)</strong> Extract all whole words having the same first and last word character.<pre><code class=language-bash>$ echo 'oreo not a _oh_ pip roar took 22' | grep -owE '\w|(\w)\w*\1' |
| 492 | +</code></pre><p><strong>11)</strong> Extract all whole words having the same first and last word character.<pre><code class=language-bash># can also use: grep -owE '(\w)(\w*\1)?' |
| 493 | +$ echo 'oreo not a _oh_ pip roar took 22' | grep -owE '\w|(\w)\w*\1' |
493 | 494 | oreo |
494 | 495 | a |
495 | 496 | _oh_ |
|
553 | 554 | $ find -type f -not -name '*[g-l]*' |
554 | 555 | ./todos/TRIP.txt |
555 | 556 | ./todos/wow.txt |
556 | | -</code></pre><p><strong>21)</strong> Find all regular files whose path has at least one directory name starting with <code>p</code> or <code>d</code>.<pre><code class=language-bash># can also use: find -type f -regex '.*/[pd].*' |
557 | | -$ find -type f -path '*/[pd]*' |
| 557 | +</code></pre><p><strong>21)</strong> Find all regular files whose path has at least one directory name starting with <code>p</code> or <code>d</code>.<pre><code class=language-bash># can also use: find -type f -regex '.*/[pd].*/.*' |
| 558 | +$ find -type f -path '*/[pd]*/*' |
558 | 559 | ./projects/tictactoe/game.py |
559 | 560 | ./projects/calculator/calc.sh |
560 | 561 | ./backups/dot_files/.bashrc |
|
564 | 565 | ./todos |
565 | 566 | ./backups |
566 | 567 | ./backups/dot_files |
567 | | -</code></pre><p><strong>23)</strong> Find all hidden directories.<pre><code class=language-bash>$ find -type d -name '.?*' |
| 568 | +</code></pre><p><strong>23)</strong> Find all hidden directories.<pre><code class=language-bash># can also use: find -mindepth 1 -type d -name '.*' |
| 569 | +$ find -type d -name '.?*' |
568 | 570 | ./projects/.venv |
569 | 571 | </code></pre><p><strong>24)</strong> Find all regular files at exact depth of <code>2</code>.<pre><code class=language-bash>$ find -mindepth 2 -maxdepth 2 -type f |
570 | 572 | ./todos/books.txt |
|
771 | 773 | $ perl -ne '$f=1 if /start/; print if !$f; $f=0 if /end/' uniform.txt |
772 | 774 | </code></pre><p><strong>7)</strong> Replace all occurrences of <code>42</code> with <code>[42]</code> unless it is at the edge of a word.<pre><code class=language-bash>$ echo 'hi42bye nice421423 bad42 cool_4242a 42c' | sed 's/\B42\B/[&]/g' |
773 | 775 | hi[42]bye nice[42]1[42]3 bad42 cool_[42][42]a 42c |
774 | | -</code></pre><p><strong>8)</strong> Replace all whole words with <code>X</code> that start and end with the same word character.<pre><code class=language-bash>$ echo 'oreo not a _a2_ roar took 22' | sed -E 's/\b(\w|(\w)\w*\2)\b/X/g' |
| 776 | +</code></pre><p><strong>8)</strong> Replace all whole words with <code>X</code> that start and end with the same word character.<pre><code class=language-bash># can also use: sed -E 's/\b(\w)(\w*\1)?\b/X/g' |
| 777 | +$ echo 'oreo not a _a2_ roar took 22' | sed -E 's/\b(\w|(\w)\w*\2)\b/X/g' |
775 | 778 | X not X X X took X |
776 | 779 | </code></pre><p><strong>9)</strong> For the input file <code>anchors.txt</code>, convert markdown anchors to hyperlinks as shown below.<pre><code class=language-bash>$ cat anchors.txt |
777 | 780 | # <a name="regular-expressions"></a>Regular Expressions |
|
1258 | 1261 | hello |
1259 | 1262 | </code></pre><p><strong>2)</strong> Will the command shown below work? If so, what would be the output?<p>Yes, it will work. <code>echo hello</code> is being passed as the script to be executed by the <code>bash</code> command.<pre><code class=language-bash>$ echo echo hello | bash |
1260 | 1263 | hello |
1261 | | -</code></pre><p><strong>3)</strong> When would you <code>source</code> a script instead of using <code>bash</code> or creating an executable using shebang?<p>Using <code>source</code> to execute scripts helps when you want to affect the current working environment.<p><strong>4)</strong> How would you display the contents of a variable with <code>shake</code> appended?<pre><code class=language-bash>$ fruit='banana' |
| 1264 | +</code></pre><p><strong>3)</strong> When would you <code>source</code> a script instead of using <code>bash</code> or creating an executable using shebang?<p>Using <code>source</code> to execute scripts helps when you want to work within the current shell environment instead of a sub-shell.<p><strong>4)</strong> How would you display the contents of a variable with <code>shake</code> appended?<pre><code class=language-bash>$ fruit='banana' |
1262 | 1265 |
|
1263 | 1266 | $ echo "${fruit}shake" |
1264 | 1267 | bananashake |
|
0 commit comments