<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Sh on Kiril Vladimirov</title>
    <link>https://vld.bg/tags/sh/</link>
    <description>Recent content in Sh on Kiril Vladimirov</description>
    <generator>Hugo -- 0.168.0</generator>
    <language>en</language>
    <atom:link href="https://vld.bg/tags/sh/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>find tricks</title>
      <link>https://vld.bg/tips/find/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://vld.bg/tips/find/</guid>
      <description>&lt;p&gt;Tasks I tend to forget how to perform with
&lt;a href=&#34;https://linux.die.net/man/1/find&#34; target=&#34;_blank&#34;&gt;find(1)&lt;/a&gt;
.&lt;/p&gt;
&lt;h2 id=&#34;delete-matched-files&#34;&gt;Delete matched files&lt;/h2&gt;
&lt;p&gt;The most trivial one: &lt;code&gt;find &amp;lt;path&amp;gt; [..] -delete&lt;/code&gt; (e.g. &lt;code&gt;find . -name foo -delete&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;However, depending on the OS &lt;code&gt;-delete&lt;/code&gt; might not be available. In that case,
see the next one.&lt;/p&gt;
&lt;h2 id=&#34;execute-command-with-matched-files&#34;&gt;Execute command with matched files&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;find &amp;lt;path&amp;gt; [..]  -exec &amp;lt;cmd&amp;gt; &#39;{}&#39; \;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;cmd&gt; is executed once for each matched file and the relative path to it is
replaces &lt;code&gt;&#39;{}&#39;&lt;/code&gt; and I always forget that &lt;code&gt;\;&lt;/code&gt;, which might be omitted depending
on a bunch of weird shell-isms
(e.g. &lt;code&gt;find . -name foo -exec rm -f &#39;{}&#39; \;&lt;/code&gt;).&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Tasks I tend to forget how to perform with
<a href="https://linux.die.net/man/1/find" target="_blank">find(1)</a>
.</p>
<h2 id="delete-matched-files">Delete matched files</h2>
<p>The most trivial one: <code>find &lt;path&gt; [..] -delete</code> (e.g. <code>find . -name foo -delete</code>).</p>
<p>However, depending on the OS <code>-delete</code> might not be available. In that case,
see the next one.</p>
<h2 id="execute-command-with-matched-files">Execute command with matched files</h2>
<pre><code>find &lt;path&gt; [..]  -exec &lt;cmd&gt; '{}' \;
</code></pre>
<p><cmd> is executed once for each matched file and the relative path to it is
replaces <code>'{}'</code> and I always forget that <code>\;</code>, which might be omitted depending
on a bunch of weird shell-isms
(e.g. <code>find . -name foo -exec rm -f '{}' \;</code>).</p>
<p>If you want to call <code>&lt;cmd&gt;</code> exactly once (with caveats) with all the matched
files passed as argument, add <code>+</code> at the end, but then <code>'{}'</code> should be right
at the end of the command just before the <code>+</code>:
<code>find . -type f -name 'foo*' -exec rm -f '{}' +</code></p>
<h2 id="match-files-by-modification-time">Match files by modification time</h2>
<pre><code>find &lt;path&gt; [..] -mtime [+-]n
</code></pre>
<ul>
<li>
<p>n means modified <strong>precisely</strong> n days ago. This matches all files modified
a week ago:<br><code>find . -mtime 7</code></p>
</li>
<li>
<p>+n means modified <strong>at least</strong> n days ago. This matches all files older than
a week:<br><code>find . -mtime +7</code></p>
</li>
<li>
<p>-n means modified <strong>within the last</strong> n days. This matches all files older than
a week:<br><code>find . -mtime -7</code></p>
</li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>Generate password</title>
      <link>https://vld.bg/tips/passwd/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://vld.bg/tips/passwd/</guid>
      <description>&lt;h2 id=&#34;pwgen-length-count&#34;&gt;pwgen [length] [count]&lt;/h2&gt;
&lt;p&gt;By default it generates a bunch of passwords in columns. However with args it
can be ustructed to generate one fairly long secret (64 characters):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pwgen 64 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It has fairly good number of ways to configure what and how exactly to
generate. The downside of this approach is that
&lt;a href=&#34;https://linux.die.net/man/1/pwgen&#34; target=&#34;_blank&#34;&gt;pwgen(1)&lt;/a&gt;
 is probably not installed by
default on your machine.&lt;/p&gt;
&lt;h2 id=&#34;devurandom&#34;&gt;/dev/urandom&lt;/h2&gt;
&lt;p&gt;Reading directly from /dev/urandom is the way to go on pretty much any UNIX
these days (or fallback to /dev/random, although both are the same except on
Linux) without having to install anything. The only question is how to make it
output plain-text.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<h2 id="pwgen-length-count">pwgen [length] [count]</h2>
<p>By default it generates a bunch of passwords in columns. However with args it
can be ustructed to generate one fairly long secret (64 characters):</p>
<pre><code>pwgen 64 1
</code></pre>
<p>It has fairly good number of ways to configure what and how exactly to
generate. The downside of this approach is that
<a href="https://linux.die.net/man/1/pwgen" target="_blank">pwgen(1)</a>
 is probably not installed by
default on your machine.</p>
<h2 id="devurandom">/dev/urandom</h2>
<p>Reading directly from /dev/urandom is the way to go on pretty much any UNIX
these days (or fallback to /dev/random, although both are the same except on
Linux) without having to install anything. The only question is how to make it
output plain-text.</p>
<h3 id="base641"><a href="https://linux.die.net/man/1/base64" target="_blank">base64(1)</a>
</h3>
<p>Arguably the easiest way if you don&rsquo;t care that the only possible &ldquo;special&rdquo;
characters besides letters and numbers are + and /:</p>
<pre><code>base64 /dev/urandom | head -c64
</code></pre>
<h3 id="tr1"><a href="https://linux.die.net/man/1/tr" target="_blank">tr(1)</a>
</h3>
<p>If you need to define a strict alphabet to use for your secret:</p>
<pre><code>cat /dev/urandom | tr -dc 'a-zA-Z0-9_!@#$%^&amp;*()~+=-' | head -c64
</code></pre>
<h3 id="openssl1"><a href="https://linux.die.net/man/1/openssl" target="_blank">openssl(1)</a>
</h3>
<p>OpenSSL can also do the job with two possible outputs:</p>
<ul>
<li>
<p>hex: <code>openssl rand -hex 42</code></p>
</li>
<li>
<p>base64: <code>openssl rand -base64 42</code> (uses = paddings)</p>
</li>
</ul>
<p>The numeric argument is not characters, though.</p>
<h3 id="gpg1"><a href="https://linux.die.net/man/1/gpg" target="_blank">gpg(1)</a>
</h3>
<p>Because obviously GPG can do everything security related:</p>
<pre><code>gpg --gen-random --armor 1 42
</code></pre>
<p>First number is &ldquo;quality level&rdquo; which is&hellip; complicated as with anything
related to GPG anyways.</p>
]]></content:encoded>
    </item>
    <item>
      <title>nmap</title>
      <link>https://vld.bg/tips/nmap/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://vld.bg/tips/nmap/</guid>
      <description>&lt;h2 id=&#34;find-hosts-in-a-range&#34;&gt;Find hosts in a range&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;nmap -sn 1.2.3.0/24
&lt;/code&gt;&lt;/pre&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;HOST DISCOVERY:
-sL: List Scan - simply list targets to scan
-sn: Ping Scan - disable port scan
-Pn: Treat all hosts as online -- skip host discovery
-PS/PA/PU/PY[portlist]: TCP SYN, TCP ACK, UDP or SCTP discovery to given ports
-PE/PP/PM: ICMP echo, timestamp, and netmask request discovery probes
-PO[protocol list]: IP Protocol Ping
-n/-R: Never do DNS resolution/Always resolve [default: sometimes]
--dns-servers &amp;lt;serv1[,serv2],...&amp;gt;: Specify custom DNS servers
--system-dns: Use OS&amp;#39;s DNS resolver
--traceroute: Trace hop path to each host
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;port-scanning&#34;&gt;Port Scanning&lt;/h2&gt;
&lt;p&gt;Quick TCP SYN scanning (&lt;code&gt;-sS&lt;/code&gt;: requires root), skipping host discovery (&lt;code&gt;-Pn&lt;/code&gt;),
of most popular ports:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<h2 id="find-hosts-in-a-range">Find hosts in a range</h2>
<pre><code>nmap -sn 1.2.3.0/24
</code></pre>
<pre tabindex="0"><code>HOST DISCOVERY:
-sL: List Scan - simply list targets to scan
-sn: Ping Scan - disable port scan
-Pn: Treat all hosts as online -- skip host discovery
-PS/PA/PU/PY[portlist]: TCP SYN, TCP ACK, UDP or SCTP discovery to given ports
-PE/PP/PM: ICMP echo, timestamp, and netmask request discovery probes
-PO[protocol list]: IP Protocol Ping
-n/-R: Never do DNS resolution/Always resolve [default: sometimes]
--dns-servers &lt;serv1[,serv2],...&gt;: Specify custom DNS servers
--system-dns: Use OS&#39;s DNS resolver
--traceroute: Trace hop path to each host
</code></pre><h2 id="port-scanning">Port Scanning</h2>
<p>Quick TCP SYN scanning (<code>-sS</code>: requires root), skipping host discovery (<code>-Pn</code>),
of most popular ports:</p>
<pre><code>nmap -sS -Pn 1.2.3.4
</code></pre>
<p>Port ranges can be given with <code>-p100-1000</code> (from :100 to :1000). All ports is
<code>-p-</code>. Single port is also accepted: <code>-p 22</code></p>
<p>UDP Scanning:</p>
<pre><code>nmap -sU -Pn 1.2.3.4
</code></pre>
<pre tabindex="0"><code>SCAN TECHNIQUES:
 -sS/sT/sA/sW/sM: TCP SYN/Connect()/ACK/Window/Maimon scans
 -sU: UDP Scan
 -sN/sF/sX: TCP Null, FIN, and Xmas scans
 --scanflags &lt;flags&gt;: Customize TCP scan flags
 -sI &lt;zombie host[:probeport]&gt;: Idle scan
 -sY/sZ: SCTP INIT/COOKIE-ECHO scans
 -sO: IP protocol scan
 -b &lt;FTP relay host&gt;: FTP bounce scan

PORT SPECIFICATION AND SCAN ORDER:
 -p &lt;port ranges&gt;: Only scan specified ports
   Ex: -p22; -p1-65535; -p U:53,111,137,T:21-25,80,139,8080,S:9
 --exclude-ports &lt;port ranges&gt;: Exclude the specified ports from scanning
 -F: Fast mode - Scan fewer ports than the default scan
 -r: Scan ports sequentially - don&#39;t randomize
 --top-ports &lt;number&gt;: Scan &lt;number&gt; most common ports
 --port-ratio &lt;ratio&gt;: Scan ports more common than &lt;ratio&gt;
</code></pre><h2 id="misc">Misc:</h2>
<ul>
<li>OS discover: <code>-O</code> (uppercase <code>o</code>, not a zero)</li>
<li>Application discovery: <code>-sV</code></li>
<li>Everything: <code>-A</code> (traceroute, app discovery, OS detecetion, port scanning&hellip;)</li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>rsync</title>
      <link>https://vld.bg/tips/rsync/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://vld.bg/tips/rsync/</guid>
      <description>&lt;pre&gt;&lt;code&gt;rsync -arvzh [host:]/source/path/ [host:]/destination/path
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note the trailing slash in source path: this avoids creating &lt;code&gt;[host:]/destination/path/path&lt;/code&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-a&lt;/code&gt;: archive (i.e. ensures that symlinks, attributes, permissions, owner, etc. are preserved)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-r&lt;/code&gt;: recursive&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-v&lt;/code&gt;: verbose (second &lt;code&gt;v&lt;/code&gt; gives what files are being skipped and some stats at the end)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-z&lt;/code&gt;: compress&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-h&lt;/code&gt;: human-readable format of numbers&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--del | --delete&lt;/code&gt;: delete files on the destination that are not sent from
the source&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;--stats&lt;/code&gt;: file-transfer statistics at the end&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;-m&lt;/code&gt;: prune empty directories from file-list&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;-t&lt;/code&gt;: preserve modification times&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <content:encoded><![CDATA[<pre><code>rsync -arvzh [host:]/source/path/ [host:]/destination/path
</code></pre>
<p>Note the trailing slash in source path: this avoids creating <code>[host:]/destination/path/path</code>.</p>
<ul>
<li><code>-a</code>: archive (i.e. ensures that symlinks, attributes, permissions, owner, etc. are preserved)</li>
<li><code>-r</code>: recursive</li>
<li><code>-v</code>: verbose (second <code>v</code> gives what files are being skipped and some stats at the end)</li>
<li><code>-z</code>: compress</li>
<li><code>-h</code>: human-readable format of numbers</li>
</ul>
<hr>
<ul>
<li>
<p><code>--del | --delete</code>: delete files on the destination that are not sent from
the source</p>
</li>
<li>
<p><code>--stats</code>: file-transfer statistics at the end</p>
</li>
<li>
<p><code>-m</code>: prune empty directories from file-list</p>
</li>
<li>
<p><code>-t</code>: preserve modification times</p>
</li>
</ul>
<hr>
<p>This is how I deploy changes of this site with rsync:</p>
<pre><code>rsync -arvzh --delete public/ vld.bg:www/vld.bg/public_html/ 
</code></pre>
]]></content:encoded>
    </item>
    <item>
      <title>Watch for file changes</title>
      <link>https://vld.bg/tips/inotify/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://vld.bg/tips/inotify/</guid>
      <description>&lt;p&gt;TL;DR: &lt;code&gt;inotifywait -m -e close_write -e delete -e move $(pwd)&lt;/code&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Example output under different conditions:&lt;/p&gt;
&lt;h3 id=&#34;touch-foo--echo---foo&#34;&gt;&lt;code&gt;touch foo&lt;/code&gt; &amp;amp;&amp;amp; &lt;code&gt;echo ... &amp;gt; foo&lt;/code&gt;&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;/path/to/watched/dir/ CLOSE_WRITE,CLOSE foo
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;mv-foo-bar&#34;&gt;&lt;code&gt;mv foo bar&lt;/code&gt;&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;/path/to/watched/dir/ MOVED_FROM foo
/path/to/watched/dir/ MOVED_TO bar
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;rm-bar&#34;&gt;&lt;code&gt;rm bar&lt;/code&gt;&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;/path/to/watched/dir/ DELETE bar
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;text-editors&#34;&gt;Text editors&lt;/h2&gt;
&lt;p&gt;This is where things get interesting&lt;/p&gt;
&lt;h3 id=&#34;vim&#34;&gt;vim&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;/path/to/watched/dir/ CLOSE_WRITE,CLOSE foo
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Boring, right? However, let&amp;rsquo;s do &lt;code&gt;:set backup&lt;/code&gt; and try again:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;/path/to/watched/dir/ CLOSE_WRITE,CLOSE 4913
/path/to/watched/dir/ DELETE 4913
/path/to/watched/dir/ MOVED_FROM foo
/path/to/watched/dir/ CLOSE_WRITE,CLOSE foo
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&#34;https://vld.bg/articles/4913_123/&#34;&gt;wut?&lt;/a&gt;
&lt;/p&gt;
&lt;h3 id=&#34;emacs&#34;&gt;emacs&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;/path/to/watched/dir/ CLOSE_WRITE,CLOSE foo
/path/to/watched/dir/ DELETE .#foo
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;.#foo&lt;/code&gt; is never created, yet deleted.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>TL;DR: <code>inotifywait -m -e close_write -e delete -e move $(pwd)</code></p>
<hr>
<p>Example output under different conditions:</p>
<h3 id="touch-foo--echo---foo"><code>touch foo</code> &amp;&amp; <code>echo ... &gt; foo</code></h3>
<pre tabindex="0"><code>/path/to/watched/dir/ CLOSE_WRITE,CLOSE foo
</code></pre><h3 id="mv-foo-bar"><code>mv foo bar</code></h3>
<pre tabindex="0"><code>/path/to/watched/dir/ MOVED_FROM foo
/path/to/watched/dir/ MOVED_TO bar
</code></pre><h3 id="rm-bar"><code>rm bar</code></h3>
<pre tabindex="0"><code>/path/to/watched/dir/ DELETE bar
</code></pre><h2 id="text-editors">Text editors</h2>
<p>This is where things get interesting</p>
<h3 id="vim">vim</h3>
<pre tabindex="0"><code>/path/to/watched/dir/ CLOSE_WRITE,CLOSE foo
</code></pre><p>Boring, right? However, let&rsquo;s do <code>:set backup</code> and try again:</p>
<pre tabindex="0"><code>/path/to/watched/dir/ CLOSE_WRITE,CLOSE 4913
/path/to/watched/dir/ DELETE 4913
/path/to/watched/dir/ MOVED_FROM foo
/path/to/watched/dir/ CLOSE_WRITE,CLOSE foo
</code></pre><p><a href="/articles/4913_123/">wut?</a>
</p>
<h3 id="emacs">emacs</h3>
<pre tabindex="0"><code>/path/to/watched/dir/ CLOSE_WRITE,CLOSE foo
/path/to/watched/dir/ DELETE .#foo
</code></pre><p><code>.#foo</code> is never created, yet deleted.</p>
<h3 id="vscode">vscode</h3>
<pre tabindex="0"><code>/path/to/watched/dir/ CLOSE_WRITE,CLOSE asdf
/path/to/watched/dir/ CLOSE_WRITE,CLOSE asdf
</code></pre><p>Not sure why it does it twice.</p>
]]></content:encoded>
    </item>
    <item>
      <title>What is my IP?</title>
      <link>https://vld.bg/tips/ip/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://vld.bg/tips/ip/</guid>
      <description>&lt;p&gt;I&amp;rsquo;m using a page setup by Jason A. Donenfeld, which he uses to illustrate
&lt;a href=&#34;https://www.wireguard.com/quickstart/&#34; target=&#34;_blank&#34;&gt;setting up WireGuard&lt;/a&gt;
:
&lt;a href=&#34;https://zx2c4.com/ip&#34; target=&#34;_blank&#34;&gt;https://zx2c4.com/ip&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;Even have it as an alias in my
&lt;a href=&#34;https://github.com/vladimiroff/dotfiles&#34; target=&#34;_blank&#34;&gt;dotfiles&lt;/a&gt;
:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;alias myip=&#39;curl -s https://zx2c4.com/ip | head -n1&#39;
&lt;/code&gt;&lt;/pre&gt;</description>
      <content:encoded><![CDATA[<p>I&rsquo;m using a page setup by Jason A. Donenfeld, which he uses to illustrate
<a href="https://www.wireguard.com/quickstart/" target="_blank">setting up WireGuard</a>
:
<a href="https://zx2c4.com/ip" target="_blank">https://zx2c4.com/ip</a>
</p>
<p>Even have it as an alias in my
<a href="https://github.com/vladimiroff/dotfiles" target="_blank">dotfiles</a>
:</p>
<pre><code>alias myip='curl -s https://zx2c4.com/ip | head -n1'
</code></pre>
]]></content:encoded>
    </item>
  </channel>
</rss>
