bash-hackers-wiki/snipplets/rndstr/index.html

76 lines
58 KiB
HTML
Raw Normal View History

<!doctype html><html lang=en class=no-js> <head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><link href=https://flokoe.github.io/bash-hackers-wiki/snipplets/rndstr/ rel=canonical><link href=../print_horizontal_line/ rel=prev><link href=../screen_saverestore/ rel=next><link rel=icon href=../../assets/images/favicon.png><meta name=generator content="mkdocs-1.6.1, mkdocs-material-9.5.44"><title>Print a random string or select random elements - The Bash Hackers Wiki</title><link rel=stylesheet href=../../assets/stylesheets/main.0253249f.min.css><link rel=stylesheet href=../../assets/stylesheets/palette.06af60db.min.css><link rel=preconnect href=https://fonts.gstatic.com crossorigin><link rel=stylesheet href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback"><style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style><script>__md_scope=new URL("../..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script></head> <body dir=ltr data-md-color-scheme=default data-md-color-primary=indigo data-md-color-accent=indigo> <input class=md-toggle data-md-toggle=drawer type=checkbox id=__drawer autocomplete=off> <input class=md-toggle data-md-toggle=search type=checkbox id=__search autocomplete=off> <label class=md-overlay for=__drawer></label> <div data-md-component=skip> <a href=#print-a-random-string-or-select-random-elements class=md-skip> Skip to content </a> </div> <div data-md-component=announce> </div> <header class=md-header data-md-component=header> <nav class="md-header__inner md-grid" aria-label=Header> <a href=../.. title="The Bash Hackers Wiki" class="md-header__button md-logo" aria-label="The Bash Hackers Wiki" data-md-component=logo> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg> </a> <label class="md-header__button md-icon" for=__drawer> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg> </label> <div class=md-header__title data-md-component=header-title> <div class=md-header__ellipsis> <div class=md-header__topic> <span class=md-ellipsis> The Bash Hackers Wiki </span> </div> <div class=md-header__topic data-md-component=header-topic> <span class=md-ellipsis> Print a random string or select random elements </span> </div> </div> </div> <form class=md-header__option data-md-component=palette> <input class=md-option data-md-color-media data-md-color-scheme=default data-md-color-primary=indigo data-md-color-accent=indigo aria-label="Switch to dark mode" type=radio name=__palette id=__palette_0> <label class="md-header__button md-icon" title="Switch to dark mode" for=__palette_1 hidden> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M12 8a4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 10a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z"/></svg> </label> <input class=md-option data-md-color-media data-md-color-scheme=slate data-md-color-primary=indigo data-md-color-accent=indigo aria-label="Switch to light mode" type=radio name=__palette id=__palette_1> <label class="md-header__button md-icon" title="Switch to light mode" for=__palette_0 hidden> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12s-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6a6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z"/></svg> </label> </form> <script>var palette=__md_get("__palette");if(palett
<a id=__codelineno-0-2 name=__codelineno-0-2 href=#__codelineno-0-2></a><span class=c1># rndstr len [ var ]</span>
<a id=__codelineno-0-3 name=__codelineno-0-3 href=#__codelineno-0-3></a><span class=k>function</span><span class=w> </span>rndstr<span class=w> </span><span class=o>{</span>
<a id=__codelineno-0-4 name=__codelineno-0-4 href=#__codelineno-0-4></a><span class=w> </span><span class=k>if</span><span class=w> </span><span class=o>[[</span><span class=w> </span><span class=nv>$FUNCNAME</span><span class=w> </span><span class=o>==</span><span class=w> </span><span class=s2>&quot;</span><span class=si>${</span><span class=nv>FUNCNAME</span><span class=p>[1]</span><span class=si>}</span><span class=s2>&quot;</span><span class=w> </span><span class=o>]]</span><span class=p>;</span><span class=w> </span><span class=k>then</span>
<a id=__codelineno-0-5 name=__codelineno-0-5 href=#__codelineno-0-5></a><span class=w> </span><span class=nb>unset</span><span class=w> </span>-v<span class=w> </span>a
<a id=__codelineno-0-6 name=__codelineno-0-6 href=#__codelineno-0-6></a><span class=w> </span><span class=nb>printf</span><span class=w> </span><span class=s2>&quot;</span><span class=nv>$@</span><span class=s2>&quot;</span>
<a id=__codelineno-0-7 name=__codelineno-0-7 href=#__codelineno-0-7></a><span class=w> </span><span class=k>elif</span><span class=w> </span><span class=o>[[</span><span class=w> </span><span class=nv>$1</span><span class=w> </span>!<span class=o>=</span><span class=w> </span>+<span class=o>([[</span>:digit:<span class=o>]])</span><span class=w> </span><span class=o>]]</span><span class=p>;</span><span class=w> </span><span class=k>then</span>
<a id=__codelineno-0-8 name=__codelineno-0-8 href=#__codelineno-0-8></a><span class=w> </span><span class=k>return</span><span class=w> </span><span class=m>1</span>
<a id=__codelineno-0-9 name=__codelineno-0-9 href=#__codelineno-0-9></a><span class=w> </span><span class=k>elif</span><span class=w> </span><span class=o>((</span><span class=w> </span><span class=nv>$1</span><span class=w> </span><span class=o>))</span><span class=p>;</span><span class=w> </span><span class=k>then</span>
<a id=__codelineno-0-10 name=__codelineno-0-10 href=#__codelineno-0-10></a><span class=w> </span><span class=nb>typeset</span><span class=w> </span>-a<span class=w> </span><span class=nv>a</span><span class=o>=({</span>a..z<span class=o>}</span><span class=w> </span><span class=o>{</span>A..Z<span class=o>}</span><span class=w> </span><span class=o>{</span><span class=m>0</span>..9<span class=o>})</span>
<a id=__codelineno-0-11 name=__codelineno-0-11 href=#__codelineno-0-11></a><span class=w> </span><span class=nb>eval</span><span class=w> </span><span class=s1>&#39;${2:+&quot;$FUNCNAME&quot; -v} &quot;${2:-printf}&quot; -- %s &quot;${a[RANDOM%&#39;</span><span class=s2>&quot;</span><span class=si>${#</span><span class=nv>a</span><span class=p>[@]</span><span class=si>}</span><span class=s2>&quot;</span><span class=s1>&#39;]&quot;{1..&#39;</span><span class=s2>&quot;</span><span class=nv>$1</span><span class=s2>&quot;</span><span class=s1>&#39;}&quot;}&quot;&#39;</span>
<a id=__codelineno-0-12 name=__codelineno-0-12 href=#__codelineno-0-12></a><span class=w> </span><span class=k>fi</span>
<a id=__codelineno-0-13 name=__codelineno-0-13 href=#__codelineno-0-13></a><span class=o>}</span>
</code></pre></div> <p>This example prints 10 random positional parameters and operates on basically the same principle as the <code>rndstr</code> function above.</p> <div class=highlight><pre><span></span><code> ~ $ ( set -- foo bar baz bork; printf &#39;%s &#39; &quot;${!_[_=RANDOM%$#+1,0]&quot;{0..10}&quot;}&quot;; echo )
bork bar baz baz foo baz baz baz baz baz bork
</code></pre></div> <div hide> This has some interesting option parsing concepts, but is overly complex. This is a good example of working too hard to avoid an eval for no benefit and some performance penalty. :/ <div class=highlight><pre><span></span><code><a id=__codelineno-1-1 name=__codelineno-1-1 href=#__codelineno-1-1></a><span class=c1># Print or assign a random alphanumeric string of a given length.</span>
<a id=__codelineno-1-2 name=__codelineno-1-2 href=#__codelineno-1-2></a><span class=c1># rndstr [ -v var ] len</span>
<a id=__codelineno-1-3 name=__codelineno-1-3 href=#__codelineno-1-3></a><span class=c1># Bash-only</span>
<a id=__codelineno-1-4 name=__codelineno-1-4 href=#__codelineno-1-4></a>rndstr<span class=o>()</span>
<a id=__codelineno-1-5 name=__codelineno-1-5 href=#__codelineno-1-5></a><span class=w> </span><span class=k>if</span><span class=w> </span><span class=o>[[</span><span class=w> </span><span class=nv>$FUNCNAME</span><span class=w> </span><span class=o>==</span><span class=w> </span><span class=s2>&quot;</span><span class=si>${</span><span class=nv>FUNCNAME</span><span class=p>[1]</span><span class=si>}</span><span class=s2>&quot;</span><span class=w> </span><span class=o>]]</span><span class=p>;</span><span class=w> </span><span class=k>then</span>
<a id=__codelineno-1-6 name=__codelineno-1-6 href=#__codelineno-1-6></a><span class=w> </span><span class=c1># On recursion, this branch unsets the outer scope&#39;s locals and assigns the result.</span>
<a id=__codelineno-1-7 name=__codelineno-1-7 href=#__codelineno-1-7></a><span class=w> </span><span class=nb>unset</span><span class=w> </span>-v<span class=w> </span>a<span class=w> </span>b
<a id=__codelineno-1-8 name=__codelineno-1-8 href=#__codelineno-1-8></a><span class=w> </span><span class=nb>printf</span><span class=w> </span>-v<span class=w> </span><span class=s2>&quot;</span><span class=nv>$1</span><span class=s2>&quot;</span><span class=w> </span>%s<span class=w> </span><span class=s2>&quot;</span><span class=si>${</span><span class=p>@:</span><span class=nv>2</span><span class=si>}</span><span class=s2>&quot;</span>
<a id=__codelineno-1-9 name=__codelineno-1-9 href=#__codelineno-1-9></a><span class=w> </span><span class=k>elif</span><span class=w> </span>!<span class=w> </span><span class=o>{</span><span class=w> </span><span class=o>[[</span><span class=w> </span><span class=nv>$1</span><span class=w> </span><span class=o>==</span><span class=w> </span>-v<span class=w> </span><span class=o>]]</span><span class=w> </span><span class=o>&amp;&amp;</span><span class=w> </span>shift<span class=p>;</span><span class=w> </span><span class=o>}</span><span class=p>;</span><span class=w> </span><span class=o>[[</span><span class=w> </span><span class=nv>$?</span>+1<span class=w> </span>-ne<span class=w> </span><span class=nv>$#</span><span class=w> </span><span class=o>||</span><span class=w> </span><span class=si>${</span><span class=p>!#</span><span class=si>}</span><span class=w> </span>!<span class=o>=</span><span class=w> </span>+<span class=o>([[</span>:digit:<span class=o>]])</span><span class=w> </span><span class=o>||</span><span class=w> </span><span class=o>(</span><span class=w> </span><span class=nv>$?</span><span class=w> </span>-gt<span class=w> </span><span class=m>0</span><span class=w> </span><span class=o>&amp;&amp;</span><span class=w> </span>-z<span class=w> </span><span class=nv>$1</span><span class=w> </span><span class=o>)</span><span class=w> </span><span class=o>]]</span><span class=p>;</span><span class=w> </span><span class=k>then</span>
<a id=__codelineno-1-10 name=__codelineno-1-10 href=#__codelineno-1-10></a><span class=w> </span><span class=c1># This branch does input validation, strips -v, and guarantees we&#39;re left with either 1 or 2 args.</span>
<a id=__codelineno-1-11 name=__codelineno-1-11 href=#__codelineno-1-11></a><span class=w> </span><span class=k>return</span><span class=w> </span><span class=m>1</span>
<a id=__codelineno-1-12 name=__codelineno-1-12 href=#__codelineno-1-12></a><span class=w> </span><span class=k>elif</span><span class=w> </span><span class=o>((</span><span class=w> </span>!<span class=w> </span><span class=si>${</span><span class=p>!#</span><span class=si>}</span><span class=w> </span><span class=o>))</span><span class=p>;</span><span class=w> </span><span class=k>then</span>
<a id=__codelineno-1-13 name=__codelineno-1-13 href=#__codelineno-1-13></a><span class=w> </span><span class=c1># If a zero-length string is requested, return success.</span>
<a id=__codelineno-1-14 name=__codelineno-1-14 href=#__codelineno-1-14></a><span class=w> </span><span class=k>return</span>
<a id=__codelineno-1-15 name=__codelineno-1-15 href=#__codelineno-1-15></a><span class=w> </span><span class=k>else</span>
<a id=__codelineno-1-16 name=__codelineno-1-16 href=#__codelineno-1-16></a><span class=w> </span><span class=c1># This line generates the string and assigns it to &quot;b&quot;.</span>
<a id=__codelineno-1-17 name=__codelineno-1-17 href=#__codelineno-1-17></a><span class=w> </span><span class=nb>local</span><span class=w> </span>-a<span class=w> </span><span class=nv>a</span><span class=o>=({</span>a..z<span class=o>}</span><span class=w> </span><span class=o>{</span>A..Z<span class=o>}</span><span class=w> </span><span class=o>{</span><span class=m>0</span>..9<span class=o>})</span><span class=w> </span><span class=s1>&#39;b=(&quot;${a[RANDOM%&#39;</span><span class=s2>&quot;</span><span class=si>${#</span><span class=nv>a</span><span class=p>[@]</span><span class=si>}</span><span class=s2>&quot;</span><span class=s1>&#39;]&quot;{1..&#39;</span><span class=s2>&quot;</span><span class=si>${</span><span class=p>!#</span><span class=si>}</span><span class=s2>&quot;</span><span class=s1>&#39;}&quot;}&quot;)&#39;</span>
<a id=__codelineno-1-18 name=__codelineno-1-18 href=#__codelineno-1-18></a><span class=w> </span><span class=k>if</span><span class=w> </span><span class=o>((</span><span class=w> </span><span class=nv>$#</span><span class=w> </span><span class=o>==</span><span class=w> </span><span class=m>2</span><span class=w> </span><span class=o>))</span><span class=p>;</span><span class=w> </span><span class=k>then</span>
<a id=__codelineno-1-19 name=__codelineno-1-19 href=#__codelineno-1-19></a><span class=w> </span><span class=c1># If -v, then pass a variable name and value to assign and recurse once.</span>
<a id=__codelineno-1-20 name=__codelineno-1-20 href=#__codelineno-1-20></a><span class=w> </span><span class=s2>&quot;</span><span class=nv>$FUNCNAME</span><span class=s2>&quot;</span><span class=w> </span><span class=s2>&quot;</span><span class=nv>$1</span><span class=s2>&quot;</span><span class=w> </span><span class=s2>&quot;</span><span class=si>${</span><span class=nv>b</span><span class=p>[@]</span><span class=si>}</span><span class=s2>&quot;</span>
<a id=__codelineno-1-21 name=__codelineno-1-21 href=#__codelineno-1-21></a><span class=w> </span><span class=k>else</span>
<a id=__codelineno-1-22 name=__codelineno-1-22 href=#__codelineno-1-22></a><span class=w> </span><span class=c1># If no -v, write to stdout.</span>
<a id=__codelineno-1-23 name=__codelineno-1-23 href=#__codelineno-1-23></a><span class=w> </span><span class=nb>printf</span><span class=w> </span>%s<span class=w> </span><span class=s2>&quot;</span><span class=si>${</span><span class=nv>b</span><span class=p>[@]</span><span class=si>}</span><span class=s2>&quot;</span>
<a id=__codelineno-1-24 name=__codelineno-1-24 href=#__codelineno-1-24></a><span class=w> </span><span class=k>fi</span>
<a id=__codelineno-1-25 name=__codelineno-1-25 href=#__codelineno-1-25></a><span class=w> </span><span class=k>fi</span>
</code></pre></div> </div> <p>The remaining examples don't use quite the same tricks, which will hopefully be explained elsewhere eventually. See <a href=../../commands/builtin/unset/#scope>unset</a> for why doing assignments in this way works well.</p> <p>This next example is a variation on <a href=../print_horizontal_line/ >print_horizontal_line</a>. We\'re using the printf field width specifier to truncate the values of a <code>sequence expansion</code> to one character.</p> <div class=highlight><pre><span></span><code><a id=__codelineno-2-1 name=__codelineno-2-1 href=#__codelineno-2-1></a><span class=nv>a</span><span class=o>=({</span>a..z<span class=o>}</span><span class=w> </span><span class=o>{</span>A..Z<span class=o>}</span><span class=w> </span><span class=o>{</span><span class=m>0</span>..9<span class=o>})</span>
<a id=__codelineno-2-2 name=__codelineno-2-2 href=#__codelineno-2-2></a><span class=nb>printf</span><span class=w> </span><span class=s1>&#39;%.1s&#39;</span><span class=w> </span><span class=s2>&quot;</span><span class=si>${</span><span class=nv>a</span><span class=p>[RANDOM%</span><span class=si>${#</span><span class=nv>a</span><span class=p>[@]</span><span class=si>}</span><span class=p>]</span><span class=si>}</span><span class=s2>&quot;</span><span class=o>{</span><span class=m>0</span>..9<span class=o>}</span><span class=w> </span><span class=s1>$&#39;\n&#39;</span>
</code></pre></div> <p>The extra detail that makes this work is to notice that in Bash, <a href=../../syntax/expansion/brace/ >brace expansion</a> is usually the very first type of expansion to be processed, always before parameter expansion. Bash is unique in this respect -- all other shells with a brace expansion feature perform it almost last, just before pathname expansion. First the sequence expansion generates ten parameters, then the parameters are expanded left-to-right causing the <a href=../../syntax/arith_expr/ >arithmetic</a> for each to be evaluated individually, resulting in independent selection of random element of <code>a</code>. To get ten of the same element, put the array selection inside the format string where it will only be evaluated once, just like the dashed-line trick:</p> <div class=highlight><pre><span></span><code><a id=__codelineno-3-1 name=__codelineno-3-1 href=#__codelineno-3-1></a><span class=nb>printf</span><span class=w> </span><span class=s2>&quot;%.s</span><span class=si>${</span><span class=nv>a</span><span class=p>[RANDOM%</span><span class=si>${#</span><span class=nv>a</span><span class=p>[@]</span><span class=si>}</span><span class=p>]</span><span class=si>}</span><span class=s2>&quot;</span><span class=w> </span><span class=o>{</span><span class=m>0</span>..9<span class=o>}</span><span class=w> </span>
</code></pre></div> <p>Selecting random elements whose lengths are not fixed is harder.</p> <div class=highlight><pre><span></span><code><a id=__codelineno-4-1 name=__codelineno-4-1 href=#__codelineno-4-1></a><span class=nv>a</span><span class=o>=(</span>one<span class=w> </span>two<span class=w> </span>three<span class=w> </span>four<span class=w> </span>five<span class=w> </span>six<span class=w> </span>seven<span class=w> </span>eight<span class=w> </span>nine<span class=w> </span>ten<span class=o>)</span>
<a id=__codelineno-4-2 name=__codelineno-4-2 href=#__codelineno-4-2></a><span class=nb>printf</span><span class=w> </span><span class=s1>&#39;%.*s &#39;</span><span class=w> </span><span class=k>$(</span><span class=nb>printf</span><span class=w> </span><span class=s1>&#39;%s &#39;</span><span class=w> </span><span class=s2>&quot;</span><span class=si>${#</span><span class=nv>a</span><span class=p>[x=RANDOM%</span><span class=si>${#</span><span class=nv>a</span><span class=p>[@]</span><span class=si>}</span><span class=p>]</span><span class=si>}</span><span class=s2> </span><span class=si>${</span><span class=nv>a</span><span class=p>[x]</span><span class=si>}</span><span class=s2>&quot;</span><span class=o>{</span><span class=m>1</span>..10<span class=o>}</span><span class=k>)</span>
</code></pre></div> <p>This generates each parameter and it's length in pairs. The \'*\' modifier instructs printf to use the value preceding each parameter as the field width. Note the space between the parameters. This example unfortunately relies upon the unquoted command substitution to perform unsafe wordsplitting so that the outer printf gets each argument. Values in the array can't contain characters in IFS, or anything that might be interpreted as a pattern without using <code>set -f</code>.</p> <p>Lastly, empty brace expansions can be used which don't generate any output that would need to be filtered. The disadvantage of course is that you must construct the brace expansion syntax to add up to the number of arguments to be generated, where the most optimal solution is its set of prime factors.</p> <div class=highlight><pre><span></span><code><a id=__codelineno-5-1 name=__codelineno-5-1 href=#__codelineno-5-1></a><span class=nv>a</span><span class=o>=(</span>one<span class=w> </span>two<span class=w> </span>three<span class=o>)</span>
<a id=__codelineno-5-2 name=__codelineno-5-2 href=#__codelineno-5-2></a><span class=nb>echo</span><span class=w> </span><span class=s2>&quot;</span><span class=si>${</span><span class=nv>a</span><span class=p>[RANDOM%</span><span class=si>${#</span><span class=nv>a</span><span class=p>[@]</span><span class=si>}</span><span class=p>]</span><span class=si>}</span><span class=s2>&quot;</span><span class=o>{</span>,<span class=o>}{</span>,,,,<span class=o>}</span>
</code></pre></div> <aside class=md-source-file> <span class=md-source-file__fact> <span class=md-icon title="Last update"> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M21 13.1c-.1 0-.3.1-.4.2l-1 1 2.1 2.1 1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8-6.1 6V23h2.1l6.1-6.1zM12.5 7v5.2l4 2.4-1 1L11 13V7zM11 21.9c-5.1-.5-9-4.8-9-9.9C2 6.5 6.5 2 12 2c5.3 0 9.6 4.1 10 9.3-.3-.1-.6-.2-1-.2s-.7.1-1 .2C19.6 7.2 16.2 4 12 4c-4.4 0-8 3.6-8 8 0 4.1 3.1 7.5 7.1 7.9l-.1.2z"/></svg> </span> <span class="git-revision-date-localized-plugin git-revision-date-localized-plugin-date">November 7, 2024</span> </span> <span class=md-source-file__fact> <span class=md-icon title=Created> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M14.47 15.08 11 13V7h1.5v5.25l3.08 1.83c-.41.28-.79.62-1.11 1m-1.39 4.84c-.36.05-.71.08-1.08.08-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8c0 .37-.03.72-.08 1.08.69.1 1.33.32 1.92.64.1-.56.16-1.13.16-1.72 0-5.5-4.5-10-10-10S2 6.5 2 12s4.47 10 10 10c.59 0 1.16-.06 1.72-.16-.32-.59-.54-1.23-.64-1.92M18 15v3h-3v2h3v3h2v-3h3v-2h-3v-3z"/></svg> </span> <span class="git-revision-date-localized-plugin git-revision-date-localized-plugin-date">November 7, 2024</span> </span> </aside> <h2 id=__comments>Comments</h2> <script src=https://giscus.app/client.js data-repo=flokoe/bash-hackers-wiki data-repo-id=R_kgDOJ3Nr6Q data-category="Giscus Page Comments" data-category-id=DIC_kwDOJ3Nr6c4CXq9t data-mapping=pathname data-strict=1 data-reactions-enabled=1 data-emit-metadata=0 data-input-position=top data-theme=preferred_color_scheme data-lang=en data-loading=lazy crossorigin=anonymous async>
</script> <script>
var giscus = document.querySelector("script[src*=giscus]")
/* Set palette on initial load */
var palette = __md_get("__palette")
if (palette && typeof palette.color === "object") {
var theme = palette.color.scheme === "slate" ? "dark" : "light"
giscus.setAttribute("data-theme", theme)
}
/* Register event handlers after documented loaded */
document.addEventListener("DOMContentLoaded", function() {
var ref = document.querySelector("[data-md-component=palette]")
ref.addEventListener("change", function() {
var palette = __md_get("__palette")
if (palette && typeof palette.color === "object") {
var theme = palette.color.scheme === "slate" ? "dark" : "light"
/* Instruct Giscus to change theme */
var frame = document.querySelector(".giscus-frame")
frame.contentWindow.postMessage(
{ giscus: { setConfig: { theme } } },
"https://giscus.app"
)
}
})
})
</script> </article> </div> <script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script> </div> <button type=button class="md-top md-icon" data-md-component=top hidden> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z"/></svg> Back to top </button> </main> <footer class=md-footer> <div class="md-footer-meta md-typeset"> <div class="md-footer-meta__inner md-grid"> <div class=md-copyright> Made with <a href=https://squidfunk.github.io/mkdocs-material/ target=_blank rel=noopener> Material for MkDocs </a> </div> </div> </div> </footer> </div> <div class=md-dialog data-md-component=dialog> <div class="md-dialog__inner md-typeset"></div> </div> <script id=__config type=application/json>{"base": "../..", "features": ["navigation.instant", "navigation.tracking", "navigation.tabs", "navigation.sections", "navigation.top", "content.action.view", "content.action.edit", "search.suggest", "search.highlight", "content.code.copy"], "search": "../../assets/javascripts/workers/search.6ce7567c.min.js", "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}}</script> <script src=../../assets/javascripts/bundle.83f73b43.min.js></script> </body> </html>