<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Nohup on blog.iankulin.com</title><link>https://blog.iankulin.com/tags/nohup/</link><description>Recent content in Nohup on blog.iankulin.com</description><generator>Hugo</generator><language>en-AU</language><lastBuildDate>Mon, 03 Feb 2025 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.iankulin.com/tags/nohup/index.xml" rel="self" type="application/rss+xml"/><item><title>Command chaining with NTFY for long running commands</title><link>https://blog.iankulin.com/command-chaining-with-ntfy-for-long-running-commands/</link><pubDate>Mon, 03 Feb 2025 00:00:00 +0000</pubDate><guid>https://blog.iankulin.com/command-chaining-with-ntfy-for-long-running-commands/</guid><description>&lt;p&gt;&lt;a href="https://ntfy.sh/"&gt;NTFY&lt;/a&gt; is a great open-source push notification service that&amp;rsquo;s self-hostable or free to use (although I suggest you &lt;a href="https://liberapay.com/ntfy"&gt;pay for it&lt;/a&gt; as I do). I&amp;rsquo;ve written before how I use it with &lt;a href="https://blog.iankulin.com/uptime-kuma-nfty/"&gt;UptimeKuma&lt;/a&gt; for my uptime monitoring, but another common use is just when I&amp;rsquo;m initiating long-running commands and backgrounding them.&lt;/p&gt;
&lt;p&gt;This magic is possible since we can just &lt;code&gt;curl&lt;/code&gt; to send a NTFY notification. For example:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;curl -d &amp;#34;😀 demo push message via NTFY&amp;#34; ntfy.sh/blog_demo
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Since I&amp;rsquo;m subscribed to the &amp;ldquo;blog_demo&amp;rdquo; topic in NTFY, this message will be pushed to my phone and watch:&lt;/p&gt;
&lt;img src="https://blog.iankulin.com/images/img_0056.png" width="640" alt=""&gt;
&lt;p&gt;How I use this is with &amp;lsquo;command chaining&amp;rsquo;. In Linux, you can stack commands together with the &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; characters like this:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;mkdir test_dir &amp;amp;&amp;amp; echo &amp;#34;success&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This will create the directory, then print &amp;ldquo;success&amp;rdquo; to the shell. I could use it like this:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;nohup rsync -rvits --bwlimit=20 &amp;#34;/volume1/media/video/Movies/Night of the Living Dead (1968)/&amp;#34; ds1_admin@100.78.2.105:&amp;#34;/volume1/media/video/Movies/Night of the Living Dead (1968)&amp;#34; &amp;gt; output.log 2&amp;gt;&amp;amp;1 &amp;amp;&amp;amp; curl -d &amp;#34;💾 upload to vm500-kr complete&amp;#34; ntfy.sh/blog_demo &amp;amp;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Both commands will run in the background, and the output of the first command is directed into the &amp;lsquo;output.log&amp;rsquo; file. If the rsync file transfer (that is going to take all night) finishes successfully, then the message saying it&amp;rsquo;s complete will be sent.&lt;/p&gt;
&lt;p&gt;What about if it fails? Well, posix has you covered here too. There&amp;rsquo;s a &lt;code&gt;||&lt;/code&gt; chaining operator that only runs if a command fails.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;mkdir invalid/name &amp;amp;&amp;amp; (echo &amp;#34;Directory created successfully.&amp;#34;) || (echo &amp;#34;Failed to create directory.&amp;#34;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In the command above, if we already have a directory called &lt;code&gt;invalid&lt;/code&gt;, the &lt;code&gt;mkdir&lt;/code&gt; will work and we&amp;rsquo;ll get the message &amp;ldquo;Directory created successfully.&amp;rdquo;. If &lt;code&gt;invalid&lt;/code&gt; doesn&amp;rsquo;t exist, the command will fail and we&amp;rsquo;ll get the message &amp;ldquo;Failed to create directory.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Note that I&amp;rsquo;ve added some parenthesis - it makes things clearer for the reader, and the command line parser.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s apply this to our slow file transfer:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;nohup rsync -rvits --bwlimit=20 &amp;#34;/volume1/media/video/Movies/Night of the Living Dead (1968)/&amp;#34; ds1_admin@100.78.2.105:&amp;#34;/volume1/media/video/Movies/Night of the Living Dead (1968)&amp;#34; &amp;gt; output.log 2&amp;gt;&amp;amp;1 &amp;amp;&amp;amp; curl -d &amp;#34;💾 upload to vm500-kr complete&amp;#34; ntfy.sh/blog_demo || curl -d &amp;#34;⚠️ upload to vm500-kr failed!&amp;#34; ntfy.sh/blog_demo &amp;amp;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now we&amp;rsquo;ll get a push message for completion or failure. There is one more little bit of housekeeping to do though. When we curl ntfy like this, it actually returns some JSON:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://blog.iankulin.com/images/screen-shot-2024-12-28-at-11.00.08-am.png"&gt;&lt;img src="https://blog.iankulin.com/images/screen-shot-2024-12-28-at-11.00.08-am.png" width="900" alt=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Since we&amp;rsquo;re running this whole thing backgrounded, we really want that to go to the &lt;code&gt;output.log&lt;/code&gt; file with the other output:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;nohup rsync -rvits --bwlimit=20 &amp;#34;/volume1/media/video/Movies/Night of the Living Dead (1968)/&amp;#34; ds1_admin@100.78.2.105:&amp;#34;/volume1/media/video/Movies/Night of the Living Dead (1968)&amp;#34; &amp;gt; output.log 2&amp;gt;&amp;amp;1 &amp;amp;&amp;amp; curl -d &amp;#34;💾 upload to vm500-kr complete&amp;#34; ntfy.sh/blog_demo &amp;gt;&amp;gt; output.log || curl -d &amp;#34;⚠️ upload to vm500-kr failed!&amp;#34; ntfy.sh/blog_demo &amp;gt;&amp;gt; output.log &amp;amp;
&lt;/code&gt;&lt;/pre&gt;</description></item></channel></rss>