<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Shell on blog.iankulin.com</title><link>https://blog.iankulin.com/tags/shell/</link><description>Recent content in Shell on blog.iankulin.com</description><generator>Hugo</generator><language>en-AU</language><lastBuildDate>Mon, 15 Jul 2024 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.iankulin.com/tags/shell/index.xml" rel="self" type="application/rss+xml"/><item><title>User environment variables are not available in cron</title><link>https://blog.iankulin.com/user-environment-variables-are-not-available-in-cron/</link><pubDate>Mon, 15 Jul 2024 00:00:00 +0000</pubDate><guid>https://blog.iankulin.com/user-environment-variables-are-not-available-in-cron/</guid><description>&lt;p&gt;&lt;img src="https://blog.iankulin.com/images/screen-shot-2024-07-02-at-4.13.13-pm.jpg" alt=""&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m used to using the &lt;code&gt;docker-compose.yaml&lt;/code&gt; or &lt;code&gt;dockerfile&lt;/code&gt; to set environment variables for containers running my apps, but ran into an issue recently where the variable seemed to be set some of the time, but at others it didn&amp;rsquo;t appear to exist.&lt;/p&gt;
&lt;p&gt;I had a script set to run by &lt;code&gt;cron&lt;/code&gt; inside the container, and it turns out that the environment variables set for the container are available in the user space, but not in &lt;code&gt;cron&lt;/code&gt;, even if running with that user&amp;rsquo;s permissions. This is probably old news to established Linux users but it threw me for a while. I&amp;rsquo;d &lt;code&gt;exec&lt;/code&gt; into the container and the script would work perfectly, then wait another minute for &lt;code&gt;cron&lt;/code&gt; to run it and it would fail 🤦‍♀️ It was exasperated by my discovery that I didn&amp;rsquo;t know how to console.log debug from inside a container cron job as well - the subject of an earlier post.&lt;/p&gt;
&lt;p&gt;Once I&amp;rsquo;d narrowed it down to this issue and googleconfirmed it, I didn&amp;rsquo;t really come up with an elegant solution either. You may think &amp;ldquo;buy hey, everything in Linux is a file, it must be in proc somewhere&amp;rdquo;, and you&amp;rsquo;d be right, sort of.&lt;/p&gt;
&lt;p&gt;In Linux, to see your own environment variables, you type in &lt;code&gt;env&lt;/code&gt;. I think this probably works by grabbing them from &lt;code&gt;proc&lt;/code&gt; under &lt;code&gt;/proc/&amp;lt;PID&amp;gt;/environ&lt;/code&gt; where &lt;PID&gt; is the process id of the shell. We can get our own process id with the &lt;code&gt;ps&lt;/code&gt; command. If we&amp;rsquo;re the root user (which I am in my container) we can see &lt;em&gt;someone else&amp;rsquo;s&lt;/em&gt; process ids with &lt;code&gt;ps -u &amp;lt;username&amp;gt;&lt;/code&gt;, get the process id for the shell and look in proc. So I tried that from the cron script - it turns out no.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.iankulin.com/images/screen-shot-2024-07-02-at-6.51.16-pm.png" alt=""&gt;&lt;/p&gt;
&lt;p&gt;I could see them, but it didn&amp;rsquo;t include the environment variable passed in from Docker that was available at the entry point. This is all a bit weird to me - I&amp;rsquo;m not sure why we&amp;rsquo;re the same user, with the same permissions but with a new seperate environment. I guess there is a reason, it&amp;rsquo;s just not apparent to me.&lt;/p&gt;
&lt;h3 id="the-hack"&gt;The Hack&lt;/h3&gt;
&lt;p&gt;To get around this, I now save the environment variable I&amp;rsquo;m interested in to a file in the script that runs at the entry point:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#616e87;font-style:italic"&gt;# Save the environment variable IMAGE_URL into&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#616e87;font-style:italic"&gt;# a file for later use in the cron script&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;env &lt;span style="color:#81a1c1"&gt;|&lt;/span&gt; grep IMAGE_URL &lt;span style="color:#81a1c1"&gt;&amp;gt;&lt;/span&gt; image_url&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;txt
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then in my script that is run by cron, I reconstitute it from the file:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#616e87;font-style:italic"&gt;# Read the file saved by the entry point script&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#616e87;font-style:italic"&gt;# and extract the environment variable&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#81a1c1;font-weight:bold"&gt;while&lt;/span&gt; IFS&lt;span style="color:#81a1c1"&gt;=&lt;/span&gt;&lt;span style="color:#a3be8c"&gt;&amp;#39;=&amp;#39;&lt;/span&gt; read &lt;span style="color:#81a1c1"&gt;-&lt;/span&gt;r key value&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;if&lt;/span&gt; &lt;span style="color:#eceff4"&gt;[[&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;$&lt;/span&gt;key &lt;span style="color:#81a1c1"&gt;==&lt;/span&gt; &lt;span style="color:#a3be8c"&gt;&amp;#34;IMAGE_URL&amp;#34;&lt;/span&gt; &lt;span style="color:#eceff4"&gt;]];&lt;/span&gt; then
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;export&lt;/span&gt; &lt;span style="color:#a3be8c"&gt;&amp;#34;$key=$value&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; fi
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;done &lt;span style="color:#81a1c1"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#a3be8c"&gt;&amp;#34;/image_url.txt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That works fine. Software testers will be looking at this solution thinking &amp;ldquo;What about the case where the environment variable isn&amp;rsquo;t set, but the file from the last run is still there?&amp;rdquo; Worry not, bug finding person. It&amp;rsquo;s a container so everything&amp;rsquo;s ephemeral. The file with the environment variable can only be there on runs when that environment variable has been set.&lt;/p&gt;</description></item><item><title>Oh My Zsh</title><link>https://blog.iankulin.com/oh-my-zsh/</link><pubDate>Sat, 06 Aug 2022 00:00:00 +0000</pubDate><guid>https://blog.iankulin.com/oh-my-zsh/</guid><description>&lt;p&gt;I&amp;rsquo;ve been playing in the zsh shell since I started on the &lt;a href="https://blog.iankulin.com/missing-semester/"&gt;Missing Semester&lt;/a&gt;, and was wondering how to get my git branch name in the prompt. A few googles later, I&amp;rsquo;ve installed Oh My Zsh, and added the git and macos plugins. Pretty.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.iankulin.com/images/screen-shot-2022-08-02-at-7.26.08-pm.jpg" alt=""&gt;&lt;/p&gt;</description></item></channel></rss>