diff options
Diffstat (limited to 'public/post/mess-with-bash-2/index.html')
-rw-r--r-- | public/post/mess-with-bash-2/index.html | 275 |
1 files changed, 275 insertions, 0 deletions
diff --git a/public/post/mess-with-bash-2/index.html b/public/post/mess-with-bash-2/index.html new file mode 100644 index 0000000..7ee05a0 --- /dev/null +++ b/public/post/mess-with-bash-2/index.html @@ -0,0 +1,275 @@ +<!DOCTYPE html> +<html lang="en"> + +<head> + <meta charset="utf-8"> + +<title>Mess with Bash(2) | garhve's gibberish</title> + + + <link rel="shortcut icon" type="image/png" href="/images/favicon.png"> + <meta name="viewport" content="width=device-width,initial-scale=1"> + + <link id="stylesheet" rel="stylesheet" type="text/css" href="/dark.css"> + + <script type="text/javascript" src="/js/theme.js"></script> + +</head> + +<div class="header"> + <div class="site_title"> + <p><a href="/"><img src="https://blog.garhve.com/images/logo.ico" alt="garhve's gibberish" + width="70" height=auto></a></p> + <p><a href="/"> garhve's gibberish</a></p> + </div> + <div class="menu"> + <!-- <a href="/tags">tags</a> + --><a href="/categories">categories</a> + </div> +</div> + +<body onload="getTheme()"> + <section class="section"> + <div class="container"> + +<p> + <div class="title_postpage">Mess with Bash(2)</div> +</p> +<p> + <div class="date_postpage">2022-09-29</div> + <div class="taxonomies_postpage"> + + + <a href="https://blog.garhve.com/categories/code/">/code</a> + + + + +  <a href="https://blog.garhve.com/tags/bash/">#bash</a> + + + </div> +</p> + +<p> + <blockquote> +<p>More info is in this <a href="https://https://guide.bash.academy">tutorial</a></p> +</blockquote> +<blockquote> +<p>all value expansions (ie. all syntax with a <code>$</code> prefix) can only expand inside quoted arguments if the argument was <em>double-quoted</em> . Single quotes will turn the dollar-syntax into literal characters, causing bash to output the dollar rather than expand its value in-place!</p> +</blockquote> +<p><em>"Value expansions (<code>$...</code>) must <strong>always</strong> be double-quoted."</em></p> +<p><em>Never leave a value expansion unquoted.</em></p> +<h2 id="redirection">Redirection</h2> +<h3 id="file-redirection">File Redirection</h3> +<p><strong>0 is standard input, 1 is standard output, 2 is standard error</strong></p> +<p><code>[x] > file, [x] < file</code></p> +<p>Make <em><strong>File descriptor</strong></em>(FD) <code>x</code> write to / read from file.</p> +<blockquote> +<p><code>echo hello > ~/World</code></p> +<p><code>read line < ~/Word</code></p> +<p><code>rm file 2>/dev/null</code></p> +</blockquote> +<h3 id="file-descriptor-copying">File Descriptor copying</h3> +<p><code>[x] >& y, [x] <& y</code></p> +<p>make FD <code>x</code> write to / read from FD <code>y</code>'s stream</p> +<blockquote> +<p>the connection to the stream used by FD <code>y</code> is copied to FD <code>x</code></p> +<p><code>curl cip.cc > result 2>&1</code></p> +<p><code>ping localhost > result 2>&1</code></p> +<pre data-lang="bash" style="background-color:#2e3440;color:#d8dee9;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#616e88;"># exec can be used to change the file descriptors of bash itself, +</span><span style="color:#616e88;"># and if you use an x that doesn't yet exist, +</span><span style="color:#616e88;"># bash will create a new file descriptor ("plug") for you with that number. +</span><span style="color:#616e88;"># - in command is to close new FD 3 we'd created before. +</span><span style="color:#616e88;"># >&- is to close FD 1, <&- is to close FD0 +</span><span style="color:#88c0d0;">exec </span><span style="color:#b48ead;">3</span><span style="color:#81a1c1;">>&</span><span style="color:#b48ead;">1 </span><span style="color:#81a1c1;">></span><span>mylog</span><span style="color:#81a1c1;">; </span><span style="color:#88c0d0;">echo</span><span> moo</span><span style="color:#81a1c1;">; </span><span style="color:#88c0d0;">exec </span><span style="color:#b48ead;">1</span><span style="color:#81a1c1;">>&</span><span style="color:#b48ead;">3 3</span><span style="color:#81a1c1;">>&</span><span style="color:#eceff4;">- +</span></code></pre> +</blockquote> +<h3 id="appending-file-redirection">Appending file redirection</h3> +<p><code>[x] >> file</code></p> +<p>make FD <code>x</code> append to end of the file</p> +<blockquote> +<p>A stream to <code>file</code> is opened for writing in append mode and is connected to file descriptor <code>x</code>. The regular file redirection operator <code>></code> empties the file's contents when it opens the file so that only your bytes will be in the file.</p> +<p><code>echo hello >> ~/world</code></p> +<p><code>echo world >> ~/world</code></p> +</blockquote> +<h3 id="redirecting-standard-output-and-standard-error">Redirecting standard output and standard error</h3> +<p><code>&>file</code></p> +<p>Make both FD 1 (standard output) and FD 2 (standard error) write to file</p> +<blockquote> +<p>This is a convenience operator which does the same thing as <code>>file 2>&1</code> but is more concise. Again, you can append rather than truncate by doubling the arrow: <code>&>>file</code></p> +<p><code>ping localhost &>result</code></p> +</blockquote> +<h3 id="here-documents">Here documents</h3> +<pre data-lang="bash" style="background-color:#2e3440;color:#d8dee9;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#81a1c1;"><<delimiter +</span><span style="color:#a3be8c;"> Here document +</span><span style="color:#81a1c1;">delimiter +</span></code></pre> +<p>Make FD 0 read from the string between <code>delimiter</code>s</p> +<blockquote> +<p>Here-Documents are great for reading blocks of text to command line.</p> +<pre data-lang="bash" style="background-color:#2e3440;color:#d8dee9;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#88c0d0;">cat </span><span style="color:#81a1c1;"><< EOF +</span><span style="color:#a3be8c;">this is within here document +</span><span style="color:#a3be8c;">I can write as many lines as I like +</span><span style="color:#a3be8c;">and terminate with line of demiliter only +</span><span style="color:#a3be8c;">EOF //end of heredoc +</span></code></pre> +</blockquote> +<h3 id="here-strings">Here strings</h3> +<p><code><<< string</code></p> +<p>Make FD 0 read from the <code>string</code></p> +<blockquote> +<p>Here strings are very similar to here documents but more concise. They are generally preferred over here documents.</p> +<pre data-lang="bash" style="background-color:#2e3440;color:#d8dee9;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#88c0d0;">cat </span><span style="color:#81a1c1;"><<< </span><span style="color:#a3be8c;">"This, +</span><span style="color:#a3be8c;">is the here strings. tab will also be read." +</span></code></pre> +</blockquote> +<h3 id="moving-file-decipher">Moving file decipher</h3> +<p><code>[x]>&y-, [x]<&y-</code></p> +<p>Replace FD <code>x</code> with FD <code>y</code> and close FD <code>y</code></p> +<blockquote> +<p>Easy way of <code>[x]>&y, y>&-</code></p> +<pre data-lang="bash" style="background-color:#2e3440;color:#d8dee9;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#616e88;"># 3>&1-: copy FD 1 to FD 3 and close FD 1. +</span><span style="color:#616e88;"># >&3-: copy FD 3 to FD 1 and close FD 3. +</span><span style="color:#88c0d0;">exec </span><span style="color:#b48ead;">3</span><span style="color:#81a1c1;">>&</span><span style="color:#b48ead;">1</span><span>- </span><span style="color:#81a1c1;">></span><span>mylog</span><span style="color:#81a1c1;">; </span><span style="color:#88c0d0;">echo</span><span> moo</span><span style="color:#81a1c1;">; </span><span style="color:#88c0d0;">exec </span><span style="color:#81a1c1;">>&</span><span style="color:#b48ead;">3</span><span>- +</span></code></pre> +</blockquote> +<h3 id="reading-and-writing-with-file-descriptor">Reading and writing with file descriptor</h3> +<p><code>[x] <> file</code></p> +<p>Open FD <code>x</code> for both reading and writing to <code>file</code></p> +<blockquote> +<p>The file descriptor at x is opened with a stream to the file that can be used for writing as well as reading bytes. Usually you'll use two file descriptors for this. <strong>One of the rare cases where this is useful is when setting up a stream with a read/write device such as a network socket</strong>.</p> +<pre data-lang="bash" style="background-color:#2e3440;color:#d8dee9;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#88c0d0;">exec </span><span style="color:#b48ead;">5</span><span style="color:#81a1c1;"><></span><span>aFile +</span><span style="color:#88c0d0;">cat </span><span style="color:#81a1c1;">>&</span><span style="color:#b48ead;">5 </span><span style="color:#a3be8c;">"Hello world" </span><span style="color:#616e88;"># make FD 1 write to where FD 5 currently writing, copy file descriptor FD 5 to FD 1 +</span><span style="color:#88c0d0;">cat </span><span style="color:#81a1c1;"><&</span><span style="color:#b48ead;">5 </span><span style="color:#616e88;"># make FD 0 read from where FD 5 currently reading, copy file descriptor FD 5 to FD 0, then cat will send content to FD 1 +</span></code></pre> +</blockquote> +<p>Exercise</p> +<blockquote> +<p>Q: fix <code>exec 3>&2 2>log; echo 'Hello!'; exec 2>&3</code> so that the message is properly saved into the <code>log</code> file and such that FD 3 is properly closed afterwards:</p> +<p>A:</p> +<ol> +<li><code>exec 3>&1- 3>log; echo 'Hello!'; exec 1>&3-</code></li> +<li><code>exec 3>&1 1>&- 3>log; echo 'Hello!'; exec 1>&3 3>&-</code></li> +</ol> +</blockquote> +<h2 id="expansion">Expansion</h2> +<h3 id="pathname-expansion">pathname expansion</h3> +<ol> +<li> +<p>pattern expansion is performed by bash before command even execute</p> +<blockquote> +<p><code>file *</code> will show info about all file in current directory. <code>*</code> will expand to content before <code>file</code> execute.</p> +</blockquote> +</li> +<li> +<p>A <em>glob</em> is the name of the type of pattern supported by the bash shell.</p> +<blockquote> +<p>basic glob name supported by bash<img src="https://assets.garhve.com/pictures/screenshots/2022/10/1665123982.png" alt="explanation" /></p> +<p><img src="https://assets.garhve.com/pictures/screenshots/2022/10/1665133964.png" alt="example" /></p> +<p><strong>Those glob will only affect current directory, explicit expression is required to working on other directory.</strong> <code>ls /sub/*</code></p> +</blockquote> +</li> +<li> +<p>extended glob can be enable to get more powerful but also easy confusing feature of bash</p> +<blockquote> +<p>bash: <code>shopt -s extglob</code> +zsh. : <code>setopt extendedglob</code> +<img src="https://assets.garhve.com/pictures/screenshots/2022/10/1665134156.png" alt="explanation" /></p> +<p><img src="https://assets.garhve.com/pictures/screenshots/2022/10/1665134205.png" alt="!(my)* get expand because of * is outside !(), which makes it expland another whole pathname" /></p> +</blockquote> +</li> +</ol> +<h3 id="command-substitution">Command Substitution</h3> +<p>we can expansion commands within commands, but must use double-quote <code>""</code> instead of <code>''</code></p> +<pre data-lang="bash" style="background-color:#2e3440;color:#d8dee9;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#616e88;"># this will output contents in hello.h to screen +</span><span style="color:#88c0d0;">cat</span><span> hello.h +</span><span> +</span><span style="color:#616e88;"># this will expand `cat hello.h` to real contents in +</span><span style="color:#616e88;"># file hello.h and concatenate to previous sentence +</span><span style="color:#88c0d0;">echo </span><span style="color:#a3be8c;">"file hello.h contains contents of </span><span style="color:#81a1c1;">$</span><span style="color:#a3be8c;">(</span><span style="color:#88c0d0;">cat</span><span style="color:#a3be8c;"> hello.h)" +</span><span> +</span><span style="color:#616e88;"># this will output 'file hello.h contains contents of $(cat hello.h)' +</span><span style="color:#616e88;"># without expand command in $() +</span><span style="color:#88c0d0;">echo </span><span style="color:#a3be8c;">'file hello.h contains contents of $(cat hello.h)' +</span></code></pre> +<p>In command, <code>$()</code> is called <em>value expansion</em>, it consists of value-expansion prefix <code>$</code> and subshell <code>(...)</code>. A subshell is essentially a small new bash process that is used to run a command while the main bash shell waits for the result.</p> +<h2 id="parameters">Parameters</h2> +<p>There are three kind of parameters:</p> +<ol> +<li>Environment Parameter</li> +<li>Positional Parameter</li> +<li>Variables</li> +</ol> +<h3 id="environment-parameter">Environment Parameter</h3> +<p>environment variables exist at the process level. That means they are not a feature of the bash shell, but rather a feature of any program process on your system. They can inherit by children, but children's EV can't be given to parent.</p> +<h3 id="positional-parameter">Positional Parameter</h3> +<p>Just as name indicates, these kind of parameters indicate arguments' position, and always starting from 0.</p> +<p>for example, imaging we have a script <code>rename</code>, arguments could be passed to it to extend its usage:</p> +<p><code>rename dir name</code> there, we passed <code>dir</code> and <code>name</code> as argument, so that positional parameters in script would be <code>$1</code> and <code>$2</code>, representing arguments respectively. after <code>$2</code>, such as <code>$3</code> is unset since there has no more argument.</p> +<blockquote> +<p>Positional Parameter is read-only</p> +</blockquote> +<p>a new usage: <code>bash -c 'ls "$1"' -- '/home'</code>. This will working like <code>ls /home</code>, dash is necessary since it is first variable in shell we ran commands and it makes positional value of arguments populated after it stand as we expect in shell single-quoted command gonna run in.</p> +<h3 id="special-parameter">Special Parameter</h3> +<p>Special parameters are parameters whose name is a single symbolic character, they are used to request certain state information from the bash shell. Like positional parameter, they are <em>read-only</em>.</p> +<p><img src="https://assets.garhve.com/pictures/screenshots/2022/10/1666054171.png" alt="different kinds of special parameters and the information they hold" /></p> +<h3 id="variables">Variables</h3> +<p>definition: <code>name=value</code> <em>//no space around <code>=</code> like other programming language support</em></p> +<p>call: like <em>command expansion</em>, using variable is to expand it with prefix <code>$</code>, e.g. <code>$name</code></p> +<ul> +<li>Keep in mind, Expansion should always be double-quoted *</li> +</ul> +<h3 id="parameter-expansion">Parameter expansion</h3> +<blockquote> +<p><a href="https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html">GNU material</a></p> +</blockquote> +<p>we expand parameters by prefixing their name with a <code>$</code> symbol</p> +<blockquote> +<p>e.g. <code>name=me; echo hello "$name"</code>. <code>hello me</code>.</p> +</blockquote> +<p>In addition, we can put braces (<code>{</code> and <code>}</code>) around our parameter, which indicates where variable is about to begin and end.</p> +<blockquote> +<p>e.g. <code>name=orange; echo there are 4 "${name}s"</code> <code>there are 4 oranges</code>.</p> +<pre data-lang="bash" style="background-color:#2e3440;color:#d8dee9;" class="language-bash "><code class="language-bash" data-lang="bash"><span>name</span><span style="color:#81a1c1;">=</span><span style="color:#a3be8c;">orange +</span><span style="color:#88c0d0;">echo </span><span style="color:#a3be8c;">"there are 4 </span><span style="color:#81a1c1;">$</span><span style="color:#a3be8c;">{</span><span>name</span><span style="color:#a3be8c;">}s." </span><span style="color:#616e88;"># there are 4 oranges. +</span><span style="color:#88c0d0;">echo </span><span style="color:#a3be8c;">"there are 4 </span><span style="color:#81a1c1;">$</span><span>names</span><span style="color:#a3be8c;">." </span><span style="color:#616e88;"># there are 4 . +</span></code></pre> +<p>here, we put <code>{}</code>around<code>name</code>so that bash can be told that suffix <code>s</code> is not a part of variable. otherwise, it will treat <code>names</code> as parameter and looking for its value, which is none in our example.</p> +</blockquote> +<p>parameter expansion brings up a powerful feature: <em>parameter expansion oerators</em></p> +<blockquote> +<p>While expanding a parameter, it is possible to apply an operator to the expanding value without alternate original value.</p> +<p>I use these mostly</p> +<pre data-lang="bash" style="background-color:#2e3440;color:#d8dee9;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#616e88;"># remove string before pattern ${name#pattern} shortest ${name##pattern} longest +</span><span style="color:#616e88;"># remove string after pattern ${name%pattern} longest ${name%%pattern} shortest +</span><span style="color:#616e88;"># delete first matching pattern ${name/pattern} +</span><span style="color:#616e88;"># delete all matching pattern ${name//pattern} +</span><span style="color:#616e88;"># substitute pattern with string ${name//pattern/string} +</span><span> +</span><span>foo</span><span style="color:#81a1c1;">=</span><span style="color:#a3be8c;">"foo-bar-foobar" +</span><span style="color:#88c0d0;">echo </span><span style="color:#81a1c1;">$</span><span>{foo</span><span style="color:#81a1c1;">#*</span><span>-} </span><span style="color:#616e88;"># echoes 'bar-foobar' (Removes 'foo-' because that matches '*-') +</span><span style="color:#88c0d0;">echo </span><span style="color:#81a1c1;">$</span><span>{foo</span><span style="color:#81a1c1;">##*</span><span>-} </span><span style="color:#616e88;"># echoes 'foobar' (Removes 'foo-bar-') +</span><span style="color:#88c0d0;">echo </span><span style="color:#81a1c1;">$</span><span>{foo</span><span style="color:#81a1c1;">%</span><span>-</span><span style="color:#81a1c1;">*</span><span>} </span><span style="color:#616e88;"># echoes 'foo-bar' +</span><span style="color:#88c0d0;">echo </span><span style="color:#81a1c1;">$</span><span>{foo</span><span style="color:#81a1c1;">%%</span><span>-</span><span style="color:#81a1c1;">*</span><span>} </span><span style="color:#616e88;"># echoes 'foo' +</span><span style="color:#88c0d0;">echo </span><span style="color:#81a1c1;">$</span><span>{foo</span><span style="color:#81a1c1;">/</span><span>-} </span><span style="color:#616e88;"># echoes 'foobar-foobar' +</span><span style="color:#88c0d0;">echo </span><span style="color:#81a1c1;">$</span><span>{foo</span><span style="color:#81a1c1;">/</span><span>/-} </span><span style="color:#616e88;"># echoes 'foobarfoobar' +</span><span style="color:#88c0d0;">echo </span><span style="color:#81a1c1;">$</span><span>{foo</span><span style="color:#81a1c1;">/</span><span>/-</span><span style="color:#81a1c1;">/</span><span>_} </span><span style="color:#616e88;"># echoes 'foo_bar_foobar' +</span></code></pre> +</blockquote> +<p><img src="https://assets.garhve.com/pictures/screenshots/2022/10/1665660923.png" alt="part of operators as shown picture" /></p> + +</p> + + + + + </div> + </section> +</body> + +<div class="footer"> +  © garhve +</div> + +</html> |