<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Anupam Majhi]]></title><description><![CDATA[Tech Lead | DevOps, Cloud, FullStack, Data Science, Machine Learning, AI]]></description><link>https://tech.anupamm.com</link><generator>RSS for Node</generator><lastBuildDate>Wed, 13 May 2026 12:59:51 GMT</lastBuildDate><atom:link href="https://tech.anupamm.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[GITHUB: Actions to show latest Hashnode posts in Github]]></title><description><![CDATA[Hashnode introduced 'headless' and while having a look at it, It really seemed interesting. It's nice to have a way to play with our publications and posts from Hashnode, outside of Hashnode without tedious data scraping.
While reading another blog, ...]]></description><link>https://tech.anupamm.com/github-actions-to-publish-hashnode-posts</link><guid isPermaLink="true">https://tech.anupamm.com/github-actions-to-publish-hashnode-posts</guid><category><![CDATA[Actions]]></category><category><![CDATA[GitHub]]></category><category><![CDATA[Hashnode]]></category><category><![CDATA[HeadlessHashnode]]></category><category><![CDATA[GraphQL]]></category><dc:creator><![CDATA[Anupam Majhi]]></dc:creator><pubDate>Wed, 29 Nov 2023 13:40:44 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1701265406214/835faf19-729c-4eab-adf9-ac2cbb8eb341.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hashnode introduced 'headless' and while having a look at it, It really seemed interesting. It's nice to have a way to play with our publications and posts from Hashnode, outside of Hashnode without tedious data scraping.</p>
<p>While reading another blog, which had some interesting use cases mentioned with some examples, one that talked about updating your static portfolio pages seemed really interesting.</p>
<p>I was really interested in hosting the Hashnode post in two places.</p>
<ol>
<li><p>My <a target="_blank" href="https://github.com/anupammajhi">GitHub profile</a> landing page.</p>
</li>
<li><p>My <a target="_blank" href="https://anupamm.com/">Portfolio Website</a> (static), which is also <a target="_blank" href="https://github.com/anupammajhi/anupammajhi.github.io">hosted via GitHub pages</a>.</p>
</li>
</ol>
<p>Since, both of them are static, and being able to update the latest few blog posts there dynamically would be cool.</p>
<p>So, the initial idea was simple: Write a Github action to run a script that fetches the posts from Hashnode, updates the html, and pushes to the repo. Do the same for the second one too. Too brute. So then I planned to convert them into Github Action steps instead.</p>
<h2 id="heading-action-1-get-latest-hashnode-posts">Action 1: Get Latest Hashnode Posts</h2>
<p>This GitHub Action retrieves posts from a Hashnode publication using GraphQL. The action accepts certain inputs and outputs the resulting posts in JSON format.</p>
<h3 id="heading-inputs">Inputs</h3>
<ul>
<li><p><code>HASHNODE_PUBLICATION_ID</code> (required): The ID of the Hashnode publication.</p>
</li>
<li><p><code>HASHNODE_GQL_ENDPOINT</code> (optional): The GraphQL endpoint for Hashnode. (default is <a target="_blank" href="https://gql.hashnode.com/">https://gql.hashnode.com</a>)</p>
</li>
<li><p><code>MAX_POSTS</code> (optional): Maximum number of posts to retrieve (default is 10).</p>
</li>
</ul>
<h3 id="heading-outputs">Outputs</h3>
<ul>
<li><code>result</code>: JSON string containing the retrieved posts.</li>
</ul>
<h3 id="heading-example-usage">Example Usage</h3>
<pre><code class="lang-yaml"><span class="hljs-attr">name:</span> <span class="hljs-string">Update</span> <span class="hljs-string">Hashnode</span> <span class="hljs-string">Posts</span>
<span class="hljs-attr">on:</span>
  <span class="hljs-attr">workflow_dispatch:</span>
  <span class="hljs-attr">schedule:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">cron:</span> <span class="hljs-string">'0 0 * * *'</span>

<span class="hljs-attr">jobs:</span>
  <span class="hljs-attr">get_posts:</span>
    <span class="hljs-attr">runs-on:</span> <span class="hljs-string">ubuntu-latest</span>
    <span class="hljs-attr">steps:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Checkout</span> <span class="hljs-string">Repository</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/checkout@v2</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Get</span> <span class="hljs-string">Hashnode</span> <span class="hljs-string">Posts</span>
        <span class="hljs-attr">id:</span> <span class="hljs-string">hashnode-posts</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">anupammajhi/githubaction-latest-hashnode-posts@v1.0.0</span>
        <span class="hljs-attr">with:</span>
          <span class="hljs-attr">HASHNODE_PUBLICATION_ID:</span> <span class="hljs-string">${{</span> <span class="hljs-string">secrets.HASHNODE_PUBLICATION_ID</span> <span class="hljs-string">}}</span>
          <span class="hljs-attr">HASHNODE_GQL_ENDPOINT:</span> <span class="hljs-string">'https://gql.hashnode.com'</span> <span class="hljs-comment"># Optional</span>
          <span class="hljs-attr">MAX_POSTS:</span> <span class="hljs-number">8</span>  <span class="hljs-comment"># Optional</span>
</code></pre>
<h2 id="heading-action-2-update-file-in-repo-with-ejs">Action 2: Update File in Repo with EJS</h2>
<p>This GitHub Action allows you to update a file in your repository using an EJS template.</p>
<p>The action is designed to replace content in a specified file between designated start and end comments with the rendered output of an EJS template. It requires five inputs, including the file path, starting comment, ending comment, EJS template path, and the JSON input for the template.</p>
<h3 id="heading-inputs-1">Inputs</h3>
<h4 id="heading-filepath-required"><code>FILE_PATH</code> (required)</h4>
<p>The relative path of the file in the repository that you want to update.</p>
<h4 id="heading-startingcomment-required"><code>STARTING_COMMENT</code> (required)</h4>
<p>The starting comment in the file, marking the beginning of the content to be replaced.</p>
<h4 id="heading-endingcomment-required"><code>ENDING_COMMENT</code> (required)</h4>
<p>The ending comment in the file, marking the end of the content to be replaced.</p>
<h4 id="heading-ejstemplatepath-required"><code>EJS_TEMPLATE_PATH</code> (required)</h4>
<p>The relative path of the EJS template file that will be used for rendering content.</p>
<h4 id="heading-templateinputjson-required"><code>TEMPLATE_INPUT_JSON</code> (required)</h4>
<p>The JSON input that the EJS template will use for variable extraction. Ideally, this should be obtained from another action step.</p>
<h3 id="heading-usage">Usage</h3>
<pre><code class="lang-yaml"><span class="hljs-bullet">-</span> <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/checkout@v4</span>
  <span class="hljs-attr">with:</span>
    <span class="hljs-comment"># The relative path of the file in the repository that you want to update.</span>
    <span class="hljs-attr">FILE_PATH:</span> <span class="hljs-string">''</span>

    <span class="hljs-comment"># The starting comment in the file mentioned in FILE_PATH, marking the beginning of the content to be replaced.</span>
    <span class="hljs-comment"># This usually depends on which file you are trying to update. </span>
    <span class="hljs-comment"># e.g. for html/markdown file you can use '&lt;!-- YOUR_STARTING_COMMENT --&gt;'</span>
    <span class="hljs-comment"># e.g. for js file you can use '// YOUR_STARTING_COMMENT'</span>
    <span class="hljs-attr">STARTING_COMMENT:</span> <span class="hljs-string">''</span>

    <span class="hljs-comment"># The ending comment in the file mentioned in FILE_PATH, marking the end of the content to be replaced.</span>
    <span class="hljs-comment"># This usually depends on which file you are trying to update. </span>
    <span class="hljs-comment"># e.g. for html/markdown file you can use '&lt;!-- YOUR_ENDING_COMMENT --&gt;'</span>
    <span class="hljs-comment"># e.g. for js file you can use '// YOUR_ENDING_COMMENT'</span>
    <span class="hljs-attr">ENDING_COMMENT:</span> <span class="hljs-string">''</span>

    <span class="hljs-comment"># The relative path of the EJS template file that will be used for rendering content.</span>
    <span class="hljs-comment"># [Learn more about EJS templates](https://ejs.co/#docs)</span>
    <span class="hljs-attr">EJS_TEMPLATE_PATH:</span> <span class="hljs-string">''</span>

    <span class="hljs-comment"># The JSON input that the EJS template will use for variable extraction. </span>
    <span class="hljs-comment"># Ideally, this should be obtained from another action step.</span>
    <span class="hljs-attr">TEMPLATE_INPUT_JSON:</span> <span class="hljs-string">''</span>
</code></pre>
<h3 id="heading-example-usage-1">Example Usage</h3>
<pre><code class="lang-yaml"><span class="hljs-attr">name:</span> <span class="hljs-string">Update</span> <span class="hljs-string">Hashnode</span> <span class="hljs-string">Posts</span>
<span class="hljs-attr">on:</span>
  <span class="hljs-attr">workflow_dispatch:</span>
  <span class="hljs-attr">schedule:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">cron:</span> <span class="hljs-string">'0 0 * * *'</span>

<span class="hljs-attr">jobs:</span>
  <span class="hljs-attr">get_posts:</span>
    <span class="hljs-attr">runs-on:</span> <span class="hljs-string">ubuntu-latest</span>
    <span class="hljs-attr">steps:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Checkout</span> <span class="hljs-string">Repository</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/checkout@v2</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Get</span> <span class="hljs-string">Hashnode</span> <span class="hljs-string">Posts</span>
        <span class="hljs-attr">id:</span> <span class="hljs-string">hashnode_posts</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">anupammajhi/githubaction-latest-hashnode-posts@v1.0.0</span>
        <span class="hljs-attr">with:</span>
          <span class="hljs-attr">HASHNODE_PUBLICATION_ID:</span> <span class="hljs-string">${{</span> <span class="hljs-string">secrets.HASHNODE_PUBLICATION_ID</span> <span class="hljs-string">}}</span>
          <span class="hljs-attr">HASHNODE_GQL_ENDPOINT:</span> <span class="hljs-string">'https://gql.hashnode.com'</span> <span class="hljs-comment"># Optional</span>
          <span class="hljs-attr">MAX_POSTS:</span> <span class="hljs-number">8</span>  <span class="hljs-comment"># Optional</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Update</span> <span class="hljs-string">File</span>
        <span class="hljs-attr">id:</span> <span class="hljs-string">update_file</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">anupammajhi/githubaction-update-repo-file@v1.0.1</span>
        <span class="hljs-attr">with:</span>
          <span class="hljs-attr">FILE_PATH:</span> <span class="hljs-string">"README.md"</span>
          <span class="hljs-attr">STARTING_COMMENT:</span> <span class="hljs-string">"&lt;!-- CONTENT_AUTO_START --&gt;"</span>
          <span class="hljs-attr">ENDING_COMMENT:</span> <span class="hljs-string">"&lt;!-- CONTENT_AUTO_END --&gt;"</span>
          <span class="hljs-attr">EJS_TEMPLATE_PATH:</span> <span class="hljs-string">"readmeTemplate.ejs"</span>
          <span class="hljs-attr">TEMPLATE_INPUT_JSON:</span> <span class="hljs-string">${{</span> <span class="hljs-string">steps.hashnode_posts.outputs.result</span> <span class="hljs-string">}}</span>
</code></pre>
<h2 id="heading-create-ejs-template-to-format-posts">Create EJS Template to format posts</h2>
<p>This template is used to make sure that the data is published in our file in the consistent format that we want. EJS is a standard templating tool, and that has been used here. Here is an example.</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">%</span> 
<span class="hljs-attr">let</span> <span class="hljs-attr">count</span> = <span class="hljs-string">0;</span>
<span class="hljs-attr">let</span> <span class="hljs-attr">i</span> = <span class="hljs-string">0;</span>
<span class="hljs-attr">while</span> (<span class="hljs-attr">count</span> &lt; <span class="hljs-attr">4</span> &amp;&amp; <span class="hljs-attr">i</span> &lt; <span class="hljs-attr">10</span>){
    <span class="hljs-attr">if</span>(<span class="hljs-attr">jsonData</span>[<span class="hljs-attr">i</span>]<span class="hljs-attr">.coverImage</span>){
        <span class="hljs-attr">count</span>++;

        <span class="hljs-attr">let</span> <span class="hljs-attr">blogUrl</span> = <span class="hljs-string">jsonData[i].url</span>
        <span class="hljs-attr">let</span> <span class="hljs-attr">imageUrl</span> = <span class="hljs-string">jsonData[i].coverImage.url</span>

        <span class="hljs-attr">const</span> <span class="hljs-attr">replacementUrl</span> = <span class="hljs-string">"tech.anupamm.com"</span>
        <span class="hljs-attr">const</span> <span class="hljs-attr">originalUrlSearchString</span> = <span class="hljs-string">/anupammajhi\.hashnode\.dev/g</span>

        <span class="hljs-attr">blogUrl</span> = <span class="hljs-string">blogUrl.replace(originalUrlSearchString,</span> <span class="hljs-attr">replacementUrl</span>)
        <span class="hljs-attr">imageUrl</span> = <span class="hljs-string">imageUrl.replace(originalUrlSearchString,</span> <span class="hljs-attr">replacementUrl</span>)

        <span class="hljs-attr">let</span> <span class="hljs-attr">date</span> = <span class="hljs-string">new</span> <span class="hljs-attr">Date</span>(<span class="hljs-attr">jsonData</span>[<span class="hljs-attr">i</span>]<span class="hljs-attr">.publishedAt</span>);
        <span class="hljs-attr">let</span> <span class="hljs-attr">formattedDate</span> = <span class="hljs-string">date.toLocaleString(</span>'<span class="hljs-attr">en-US</span>', {
            <span class="hljs-attr">year:</span> '<span class="hljs-attr">numeric</span>',
            <span class="hljs-attr">month:</span> '<span class="hljs-attr">long</span>',
            <span class="hljs-attr">day:</span> '<span class="hljs-attr">numeric</span>'
        });
%&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">td</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"width:30%"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"&lt;%= blogUrl %&gt;"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"&lt;%= imageUrl %&gt;"</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"500"</span> <span class="hljs-attr">height</span>=<span class="hljs-string">"auto"</span> /&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"&lt;%= blogUrl %&gt;"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">b</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">%=</span> <span class="hljs-attr">jsonData</span>[<span class="hljs-attr">i</span>]<span class="hljs-attr">.title</span> %&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">b</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span> /&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">code</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">%=</span> <span class="hljs-attr">formattedDate</span> %&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">code</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span> /&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">%=</span> <span class="hljs-attr">jsonData</span>[<span class="hljs-attr">i</span>]<span class="hljs-attr">.brief</span> %&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">%</span> 
    }
    <span class="hljs-attr">i</span>++;
} 
%&gt;</span>
</code></pre>
<blockquote>
<p>Make sure the file that we are trying to update has the appropriate Starting and Ending Comments in place.</p>
</blockquote>
<p>That's it. Now we have static pages hosted in Github that are updated daily with the posts from Hashnode.</p>
]]></content:encoded></item><item><title><![CDATA[WINDOWS: Red Hat (RHEL9) with WSL2]]></title><description><![CDATA[While trying to get Red Hat (RHEL9) installed in my WSL (Windows Subsystem for Linux) within my Windows 11 laptop, I stumbled upon the same hurdle I did for installing the older RHEL8. The list of available distros published by Microsoft still does n...]]></description><link>https://tech.anupamm.com/windows-red-hat-rhel9-with-wsl2</link><guid isPermaLink="true">https://tech.anupamm.com/windows-red-hat-rhel9-with-wsl2</guid><category><![CDATA[Linux]]></category><category><![CDATA[WSL]]></category><category><![CDATA[redhat]]></category><category><![CDATA[RHEL9]]></category><category><![CDATA[Windows]]></category><category><![CDATA[Docker]]></category><category><![CDATA[distro]]></category><dc:creator><![CDATA[Anupam Majhi]]></dc:creator><pubDate>Sat, 11 Jun 2022 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1700655789491/a719157b-6562-4ee5-8471-de63cb459395.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>While trying to get <strong>Red Hat (RHEL9)</strong> installed in my WSL (Windows Subsystem for Linux) within my Windows 11 laptop, I stumbled upon the same hurdle I did for installing the older RHEL8. The list of available distros published by Microsoft still does not have Red Hat, for whatever reason.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700641017683/fa385b6d-6e6f-49df-a321-2c879b7fcc76.png" alt class="image--center mx-auto" /></p>
<p>However, this extremely helpful <a target="_blank" href="https://wsl.dev/mobyrhel8/">blog post</a> has helped me earlier, I successfully installed RHEL8 in WSL2 about a year back. In this post, I have captured those steps, but for <strong>RHEL9</strong>, so that I can come back to this again when I need it. Along the way, hopefully, this also helps someone looking to do the same.</p>
<h3 id="heading-prerequisites"><strong>Prerequisites:</strong></h3>
<p>Before diving into the installation process, make sure you have the following prerequisites:</p>
<ol>
<li><p><strong>OS:</strong> Windows 10 Pro or above.</p>
</li>
<li><p><strong>Enable WSL2:</strong> Ensure that WSL2 is enabled on your Windows machine. You can follow Microsoft's official documentation for guidance.</p>
</li>
<li><p><strong>Docker:</strong> To get the Red Hat image from the Red Hat registry.</p>
</li>
<li><p><strong>Terminal</strong> [Optional]: Windows Terminal or even Powershell terminal would work.</p>
</li>
<li><p><strong>Red Hat account</strong>: Create a free developer account to be able to connect to the Red Hat registry.</p>
</li>
<li><p>Basic knowledge of creating and editing files in Linux.</p>
</li>
</ol>
<h3 id="heading-prepare-rhel9-image">Prepare RHEL9 Image</h3>
<p>The most straightforward method for establishing a new WSL distro involves importing a container export file. To access Red Hat Enterprise Linux (RHEL) container images, it is necessary to retrieve them from Red Hat's dedicated registry.</p>
<blockquote>
<p>Interestingly, a search for RHEL base images yields only RHEL6 and RHEL7 fully featured images. However, when exploring build images, an RHEL9 image is available, such as the one associated with the Go Toolkit.</p>
</blockquote>
<p>Let's proceed to create a container using the Go RHEL9 image. It's essential to note that we won't execute any commands within the container, causing it to be created and exit immediately. This behavior aligns with our intention, as we plan to export the container to a file.</p>
<p>Open your Powershell Terminal and login to the Red Hat registry with the username and password for Red Hat developer account. Then we will get the image from the registry.</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Login to the Red Hat registry</span>
<span class="hljs-comment"># Enter the Red Hat account username and password</span>
docker login registry.redhat.io

<span class="hljs-comment"># Pull the GO image with the RHEL9 base image</span>
docker run --name rhel9 registry.redhat.io/rhel9/go-toolset
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700643852609/3821212f-bdfe-4c89-a84f-37af93a1a25d.png" alt class="image--center mx-auto" /></p>
<p>Once we create the container, we can now export it as an archive file.</p>
<blockquote>
<p>I am using PowerShell. If you are using another distro within wsl2, then you can use the location as /mnt/c/wslsources instead</p>
</blockquote>
<pre><code class="lang-powershell"><span class="hljs-comment"># Create directory to save the archived image</span>
mkdir C:\wslsources

<span class="hljs-comment"># Export the container to an archive file</span>
<span class="hljs-comment"># Command help:</span>
<span class="hljs-comment"># - base command: docker export</span>
<span class="hljs-comment"># - option to output to a file: -o C:\wslsources\rhel9.tar.gz</span>
<span class="hljs-comment"># - name of the container to be exported: rhel9</span>
docker export <span class="hljs-literal">-o</span> C:\wslsources\rhel9.tar.gz rhel9

<span class="hljs-comment"># Check if the export has been successful</span>
<span class="hljs-built_in">ls</span> <span class="hljs-literal">-l</span> C:\wslsources
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700644430044/b06297af-9d62-4a30-8c5e-4ede65555ea9.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-import-rhel9-to-wsl">Import RHEL9 to WSL</h3>
<p>We can now use this archived image to import it to WSL as a new WSL2 distro.</p>
<pre><code class="lang-powershell"><span class="hljs-comment"># Create a new directory for containing the WSL custom distros, or move into it if already created</span>
mkdir c:\wsldistros
<span class="hljs-built_in">cd</span> c:\wsldistros

<span class="hljs-comment"># Import the container file as a WSL v2 distro</span>
<span class="hljs-comment"># Command help:</span>
<span class="hljs-comment"># - base command: wsl --import</span>
<span class="hljs-comment"># - name of the distro: rhel9</span>
<span class="hljs-comment"># - location of the distro files: ./rhel9</span>
<span class="hljs-comment"># - path of the container file: C:\wslsources\rhel9.tar.gz</span>
wsl -<span class="hljs-literal">-import</span> rhel9 ./rhel9 C:\wslsources\rhel9.tar.gz

<span class="hljs-comment"># Launch the new distro</span>
wsl <span class="hljs-literal">-d</span> rhel9
</code></pre>
<blockquote>
<p><em>Note: the command above assumes that WSL is set to have the v2 versions by default. If there’s an uncertainty about which version is actually setup, the following option can be added to the command:</em> <code>--version 2</code></p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700645162383/ce6ad234-33d6-4610-9e69-010590b0cd56.png" alt class="image--center mx-auto" /></p>
<p>Check the OS release version to be sure that we are in the right distro.</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Check with version is installed</span>
cat /etc/os-release
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700645665547/23b76647-e05d-4c84-b8e1-57c204536577.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-finalizing-rhel9-setup">Finalizing RHEL9 setup</h3>
<p>Once we have RHEL, it’s time to start the configuration. But first, let’s register it.</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Register the system with our Red Hat username and password</span>
subscription-manager register

<span class="hljs-comment"># Set a role to the System</span>
<span class="hljs-comment"># It can be one suggested by Red Hat, or in our case, let's have "some fun", and set it to WSL</span>
subscription-manager role --<span class="hljs-built_in">set</span>=<span class="hljs-string">"Red Hat Enterprise Linux WSL"</span>

<span class="hljs-comment"># Set a support level</span>
<span class="hljs-comment"># In our case, remember we have a free Developer license and the only valid support is "Self-Support"</span>
subscription-manager service-level --<span class="hljs-built_in">set</span>=<span class="hljs-string">"Self-Support"</span>

<span class="hljs-comment"># Set a usage (read: purpose) to the System</span>
<span class="hljs-comment"># We will pick "Development/Test" for this first try</span>
subscription-manager usage --<span class="hljs-built_in">set</span>=<span class="hljs-string">"Development/Test"</span>

<span class="hljs-comment"># Once everything is set, we can attach the system to our Red Hat subscription</span>
subscription-manager attach
</code></pre>
<p><code>Note: If Simple Content Access (SCA) is enabled in your Red Hat developer account, then the 'attach' would be ignored, just like in my case, and that is okay.</code></p>
<p><code>[Optional] We can confirm if the system has been correctly subscribed in the Red Hat Customer Portal by clicking in our Subscription and picking the “Systems” tab</code></p>
<p>Now we can go ahead and update the packages and install additional packages to make is a full fledged RHEL9 setup.</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Update the system</span>
dnf update

<span class="hljs-comment"># Add sudo, zsh and cracklib-dicts</span>
dnf install -y sudo zsh cracklib-dicts
</code></pre>
<p><em>Note:</em> while <code>sudo</code> and <code>zsh</code> are familiar applications among Linux users, <code>cracklib-dicts</code> is a package utilized by the <code>passwd</code> command for password resets. The container image does not inherently include this package. Including <code>cracklib-dicts</code> in the container will prevent the occurrence of a warning message each time a password is changed for any user.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700651603722/b61fea0f-8455-4ba6-b43a-d7649466afc8.png" alt class="image--center mx-auto" /></p>
<p>With packages installed, we can create our main user.</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Create a new user with the desired username</span>
<span class="hljs-comment"># Command help:</span>
<span class="hljs-comment"># base command: useradd</span>
<span class="hljs-comment"># create the home directory: -m</span>
<span class="hljs-comment"># set ZSH as the default shell: -s /bin/zsh</span>
<span class="hljs-comment"># add the user to the group 'wheel' which is defined in the 'sudoers' file: -G wheel</span>
<span class="hljs-comment"># username desired: majhi</span>
useradd -m -s /bin/zsh -G wheel majhi

<span class="hljs-comment"># Set a password for the user created</span>
passwd majhi

<span class="hljs-comment"># Set a password for the 'root' user</span>
passwd
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700651830902/30fde16a-ab33-494e-af85-c920dc47a8d0.png" alt class="image--center mx-auto" /></p>
<p>In the final phase of configuration, attention is directed towards WSL itself. We will craft a configuration file specifically for the 'interoperability' of our newly customized distribution.</p>
<p>This configuration file resides 'on the WSL side', implying that its effects are limited to the distro it is associated with"</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Create the configuration file with a preferred text editor</span>
vi /etc/wsl.conf

<span class="hljs-comment">## This is the file content</span>
<span class="hljs-comment">## Replace the username and hostname as desired</span>
<span class="hljs-comment">## Source for the options: https://docs.microsoft.com/en-us/windows/wsl/wsl-config#configure-per-distro-launch-settings-with-wslconf</span>
[automount]
enabled = <span class="hljs-literal">true</span>
mountfstab = <span class="hljs-literal">true</span>
root = /mnt/
options = metadata,uid=1000,gid=1000,<span class="hljs-built_in">umask</span>=0022,fmask=11,<span class="hljs-keyword">case</span>=off

[network]
generatehosts = <span class="hljs-literal">true</span>
generateresolvconf = <span class="hljs-literal">true</span>
hostname = rhel9

[interop]
enabled = <span class="hljs-literal">true</span>
appendwindowspath = <span class="hljs-literal">true</span>

[user]
default = majhi

<span class="hljs-comment"># [Optional] Check if the file has been correctly created</span>
cat /etc/wsl.conf
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700652223043/e8fed221-9734-4494-b380-2d77760c4046.png" alt class="image--center mx-auto" /></p>
<p>Now open a new PowerShell terminal to reload the rhel9 from wsl, for the settings to take effect.</p>
<pre><code class="lang-powershell"><span class="hljs-comment"># Stop the custom distro only from PowerShell </span>
wsl -<span class="hljs-literal">-terminate</span> rhel9

<span class="hljs-comment"># Start the distro</span>
wsl <span class="hljs-literal">-d</span> rhel9
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700653412777/664dcf34-689a-443e-ab41-db794f8d09eb.png" alt class="image--center mx-auto" /></p>
<p>Now it is logged in as the new main user that we created.</p>
<blockquote>
<p>After this, we can also go ahead and do some cosmetic changes to our zsh shell to make it look pretty and add some theme. I have covered that in another post, the <a target="_blank" href="https://tech.anupamm.com/linux-zsh-theme-i-use">"zsh" Theme I use</a></p>
</blockquote>
<h3 id="heading-systemd-setup">SystemD setup</h3>
<p>When examining the disparities between WSL distros and fully-fledged Linux distributions, one notable absence is the lack of a service manager. This omission is a deliberate result of the customized init process that facilitates broad interoperability.</p>
<p>A new option in the WSL configuration file now enables the execution of a command at the distro's boot time. This modification introduces a significantly cleaner and more efficient method for initiating SystemD.</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Edit the wsl configuration file with a preferred text editor</span>
sudo vi /etc/wsl.conf

<span class="hljs-comment">## Add the new boot section with the command to start SystemD at the end of the file</span>
<span class="hljs-comment">## Source: https://github.com/diddlesnaps/one-script-wsl2-systemd/tree/build-21286%2B</span>
[boot]
<span class="hljs-built_in">command</span> = <span class="hljs-string">"/usr/bin/env -i /usr/bin/unshare --fork --mount-proc --pid -- sh -c 'mount -t binfmt_misc binfmt_misc /proc/sys/fs/binfmt_misc; exec /usr/lib/systemd/systemd --unit=multi-user.target'"</span>

<span class="hljs-comment"># [Optional] Check if the change has been successfully saved</span>
cat /etc/wsl.conf
</code></pre>
<p>Then we will need to create a script to be launched with the distro starts:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Create the script to be launched when the distro starts</span>
sudo vi /etc/profile.d/00-wsl2-systemd.sh

<span class="hljs-comment">## The file should have the following content</span>
<span class="hljs-keyword">if</span> [ <span class="hljs-string">"<span class="hljs-subst">$(ps -c -p 1 -o command=)</span>"</span> != <span class="hljs-string">"systemd"</span> ]; <span class="hljs-keyword">then</span>
        <span class="hljs-keyword">if</span> [ -z <span class="hljs-string">"<span class="hljs-variable">$SUDO_USER</span>"</span> ]; <span class="hljs-keyword">then</span>
                <span class="hljs-built_in">export</span> &gt; <span class="hljs-string">"<span class="hljs-variable">$HOME</span>/.profile-systemd"</span>
        <span class="hljs-keyword">fi</span>

        <span class="hljs-keyword">if</span> [ <span class="hljs-string">"<span class="hljs-variable">$USER</span>"</span> != <span class="hljs-string">"root"</span> ]; <span class="hljs-keyword">then</span>
                <span class="hljs-built_in">exec</span> sudo /bin/sh <span class="hljs-string">"/etc/profile.d/00-wsl2-systemd.sh"</span>
        <span class="hljs-keyword">fi</span>

        <span class="hljs-keyword">if</span> ! grep -q WSL_INTEROP /etc/environment; <span class="hljs-keyword">then</span>
                <span class="hljs-built_in">echo</span> <span class="hljs-string">"WSL_INTEROP='/run/WSL/<span class="hljs-subst">$(ls -r /run/WSL | head -n1)</span>'"</span> &gt;&gt; /etc/environment
        <span class="hljs-keyword">fi</span>

        <span class="hljs-keyword">if</span> ! grep -q DISPLAY /etc/environment; <span class="hljs-keyword">then</span>
                <span class="hljs-built_in">echo</span> <span class="hljs-string">"DISPLAY='<span class="hljs-subst">$(awk '/nameserver/ { print $2<span class="hljs-string">":0"</span> }' /etc/resolv.conf)</span>'"</span> &gt;&gt; /etc/environment
        <span class="hljs-keyword">fi</span>

        <span class="hljs-built_in">exec</span> /usr/bin/nsenter --mount --pid --target <span class="hljs-string">"<span class="hljs-subst">$(ps -C systemd -o pid= | head -n1)</span>"</span> -- su - <span class="hljs-string">"<span class="hljs-variable">$SUDO_USER</span>"</span>
<span class="hljs-keyword">fi</span>

<span class="hljs-keyword">if</span> [ -f <span class="hljs-string">"<span class="hljs-variable">$HOME</span>/.profile-systemd"</span> ]; <span class="hljs-keyword">then</span>
        <span class="hljs-built_in">source</span> <span class="hljs-string">"<span class="hljs-variable">$HOME</span>/.profile-systemd"</span>
<span class="hljs-keyword">fi</span>

<span class="hljs-keyword">if</span> [ -d <span class="hljs-string">"<span class="hljs-variable">$HOME</span>/.wslprofile.d"</span> ]; <span class="hljs-keyword">then</span>
        <span class="hljs-keyword">for</span> script <span class="hljs-keyword">in</span> <span class="hljs-string">"<span class="hljs-variable">$HOME</span>/.wslprofile.d/"</span>*; <span class="hljs-keyword">do</span>
                <span class="hljs-built_in">source</span> <span class="hljs-string">"<span class="hljs-variable">$script</span>"</span>
        <span class="hljs-keyword">done</span>
        <span class="hljs-built_in">unset</span> script
<span class="hljs-keyword">fi</span>

<span class="hljs-comment"># [Optional] Check if the file has been correctly saved</span>
cat /etc/profile.d/00-wsl2-systemd.sh
</code></pre>
<p>Finally, we will need to update the sudoers file so that this can be launched without using a password every time the distro starts.</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Edit the sudoers file</span>
sudo visudo

<span class="hljs-comment">## Add a new value to the environment variables that are kept</span>
Defaults env_keep += <span class="hljs-string">"WSL_INTEROP"</span>

<span class="hljs-comment">## Add the command to run the script without password</span>
%wheel ALL=(root) NOPASSWD: /bin/sh /etc/profile.d/00-wsl2-systemd.sh

<span class="hljs-comment"># [Optional] Check if the sudoers have been correctly updated</span>
sudo grep -i wsl /etc/sudoers
</code></pre>
<p>Then we just reload the distro for the settings to take effect.</p>
<pre><code class="lang-powershell"><span class="hljs-comment"># Stop the custom distro only from PowerShell </span>
wsl -<span class="hljs-literal">-terminate</span> rhel9

<span class="hljs-comment"># Start the distro</span>
wsl <span class="hljs-literal">-d</span> rhel9
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700653412777/664dcf34-689a-443e-ab41-db794f8d09eb.png" alt class="image--center mx-auto" /></p>
<p>To confirm after launching a new session of our distro and check SystemD processes are running, we can check for PID 1:</p>
<pre><code class="lang-bash">ps -ef
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700654587102/e45af9d6-e799-437c-8db2-4975bdb069da.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-setup-docker">Setup Docker</h3>
<p>This RHEL9 setup still doesn't have any docker client or daemon. However, we can use the following steps as per Docker documentation.</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Install the yum-utils package</span>
sudo yum install -y yum-utils

<span class="hljs-comment"># Add the Docker repository</span>
sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700654793638/d1e891ff-8ad3-4fc0-90e9-42f2430d32f5.png" alt class="image--center mx-auto" /></p>
<pre><code class="lang-bash"><span class="hljs-comment"># Install Docker</span>
sudo yum install docker-ce docker-ce-cli containerd.io

<span class="hljs-comment">## We will need approve the import of the Docker GPG key</span>
<span class="hljs-comment">## Just type 'y' and press Enter</span>
</code></pre>
<p>Before initiating Docker, a necessary modification is required in the Docker SystemD file. The challenge arises from the fact that Red Hat no longer utilizes iptables but has transitioned to its successor, nftables.</p>
<p>Fortunately, we can address this by adjusting the Docker start command to eliminate the reliance on searching for iptables.</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Update the Docker SystemD service</span>
sudo vi /usr/lib/systemd/system/docker.service

<span class="hljs-comment">## Locate the ExecStart option and add --iptables=false at the end of the line</span>
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --iptables=<span class="hljs-literal">false</span>

<span class="hljs-comment"># [Optional] Check if the file has been correctly saved</span>
grep ExecStart /usr/lib/systemd/system/docker.service

<span class="hljs-comment"># Reload the SystemD service configuration files</span>
sudo systemctl daemon-reload

<span class="hljs-comment"># Start Docker</span>
sudo systemctl start docker

<span class="hljs-comment"># Check if Docker has been correctly started</span>
sudo systemctl status docker

<span class="hljs-comment"># Enable Docker to be started when the distro starts</span>
sudo systemctl <span class="hljs-built_in">enable</span> docker
</code></pre>
<p>In order for us to use Docker without the <code>sudo</code> command, we need to add our user to the <code>docker</code> group</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Add our user to the docker group</span>
sudo usermod -aG docker <span class="hljs-variable">$USER</span>

<span class="hljs-comment"># Refresh the group docker without launching a new shell</span>
newgrp docker

<span class="hljs-comment"># Check the Docker version</span>
docker version
</code></pre>
<p>That's it! We now have a full-blown RHEL 9 distro running in WSL with necessary WSL interoperability settings.</p>
<p>What an enjoyable journey, and if there's one key takeaway from this blog, it's that WSL2 serves as a robust platform for running Linux. Thanks to</p>
<p>some clever scripting, the experience is steadily approaching that of a virtual machine (VM) or bare-metal setup.</p>
<p>It's crucial to note, however, that achieving official support might not always be feasible, introducing potential limitations and roadblocks. Nevertheless, from a technical standpoint, it was entirely achievable.</p>
]]></content:encoded></item><item><title><![CDATA[GitHub: Manage reviewers at dir/file level]]></title><description><![CDATA[When it comes to collaborative software development, efficiency in communication and planning are critical. GitHub offers a feature called "Code owners" to improve project management and facilitate cooperation. Let's see how this can improve your dev...]]></description><link>https://tech.anupamm.com/github-manage-reviewers-at-dirfile-level</link><guid isPermaLink="true">https://tech.anupamm.com/github-manage-reviewers-at-dirfile-level</guid><category><![CDATA[Codeowners]]></category><category><![CDATA[GitHub]]></category><category><![CDATA[review]]></category><category><![CDATA[pr]]></category><category><![CDATA[Pull Requests]]></category><dc:creator><![CDATA[Anupam Majhi]]></dc:creator><pubDate>Fri, 17 Dec 2021 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1703067926651/a5a67619-a223-42ae-adcd-a3e34c60c23a.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When it comes to collaborative software development, efficiency in communication and planning are critical. GitHub offers a feature called "<strong>Code owners</strong>" to improve project management and facilitate cooperation. Let's see how this can improve your development workflow.</p>
<h3 id="heading-about-codeowners">About CODEOWNERS?</h3>
<p>GitHub released the code owners functionality somewhere around 2017, which allows you to designate who owns the code inside a repository. Teams can use this to assign people or groups to manage particular sections of the codebase. A file called CODEOWNERS, which is found at the repository's root, lists the code owners.</p>
<h3 id="heading-how-does-it-work">How Does it Work?</h3>
<p>Patterns in the CODEOWNERS file correspond to file paths in your repository. Every pattern has one or more GitHub usernames or team names attached to it, which identify the people or groups in charge of checking and updating the code inside that path.</p>
<p>For example, a CODEOWNERS file might look like this:</p>
<pre><code class="lang-plaintext"># Assigning code ownership

*.js @frontend-team

backend/* @backend-team

/docs/* @documentation-team
</code></pre>
<p>In this example, files in the "backend" directory belong to the backend team, files in the "docs" directory to the documentation team, and JavaScript files to the frontend team.</p>
<h3 id="heading-benefits">Benefits</h3>
<p><strong>1. Clear Ownership and Responsibility</strong></p>
<p>Makes it explicit who is responsible for reviewing and maintaining specific parts of the codebase. This ensures that changes are overseen by those with the most knowledge of and responsibility for the affected code.</p>
<p><strong>2. Granular Code Review Process</strong></p>
<p>The code review procedure runs smoothly when there are assigned owners for every piece of the codebase. Pull requests streamline the review process and lessen the possibility of changes being missed by automatically assigning reviewers based on the CODEOWNERS file.</p>
<p><strong>3. Improved Collaboration</strong></p>
<p>This encourages team members to communicate with one another. Developers get to know who to contact for advice or clarification on particular code regions.</p>
<p><strong>4. Reduced Bottlenecks</strong></p>
<p>By distributing ownership, it helps prevent bottlenecks caused by a single individual or team being overloaded with code review requests. This promotes a more balanced and scalable development process.</p>
<h3 id="heading-implementing-codeowners-in-your-project">Implementing CODEOWNERS in Your Project</h3>
<p><strong>1. Create a CODEOWNERS file:</strong></p>
<ul>
<li><p>Create a CODEOWNERS file at the root of your repository.</p>
</li>
<li><p>Specify patterns and assign owners based on your project's structure.</p>
</li>
</ul>
<p><strong>2. Review and Update Regularly:</strong></p>
<ul>
<li>Regularly review and update the CODEOWNERS file to reflect changes in team structure or project organization.</li>
</ul>
<p><strong>3. Integrate with Workflows:</strong></p>
<ul>
<li>Ensure that your team integrates it into their workflows. Utilize features like automatic pull request assignment based on code ownership.</li>
</ul>
<p><strong>4. Documentation:</strong></p>
<ul>
<li>Document your Code Owners conventions and processes to facilitate onboarding for new team members.</li>
</ul>
<p>There you go. Consider implementing CODEOWNERS in your next project to manage code reviewers at the directory/file level and elevate your team's collaboration and code management practices.</p>
]]></content:encoded></item><item><title><![CDATA[WINDOWS: Elevating PowerShell to Admin Mode without UAC prompt]]></title><description><![CDATA[PowerShell is a powerful tool, allowing to perform a myriad of tasks with just a few commands. However, there are times when elevated privileges are required to execute certain commands. This is as easy as right-clicking PowerShell and "Run As Admini...]]></description><link>https://tech.anupamm.com/windows-elevating-powershell-to-admin-mode-without-uac-prompt</link><guid isPermaLink="true">https://tech.anupamm.com/windows-elevating-powershell-to-admin-mode-without-uac-prompt</guid><category><![CDATA[runas]]></category><category><![CDATA[Powershell]]></category><category><![CDATA[admin]]></category><category><![CDATA[Prompt]]></category><category><![CDATA[Windows]]></category><dc:creator><![CDATA[Anupam Majhi]]></dc:creator><pubDate>Wed, 20 Oct 2021 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1702762402950/d85ab544-fd49-4c83-8843-3e0532a44be9.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>PowerShell is a powerful tool, allowing to perform a myriad of tasks with just a few commands. However, there are times when elevated privileges are required to execute certain commands. This is as easy as right-clicking PowerShell and "Run As Administrator" 👎. Not as easy though when you want to launch it entirely from the terminal, without any GUI popup (UAC).</p>
<p>Microsoft provides a not so beautiful but powerful command to do that too. Drumrolls......</p>
<h3 id="heading-the-runas-command">The Runas Command</h3>
<p>The `runas` command in Windows allows users to run a program with different user credentials than the ones currently in use. To open PowerShell in administrator mode with a domain admin user, the following command can be used:</p>
<pre><code class="lang-powershell">runas /user:DOMAIN\adminuser <span class="hljs-string">"powershell.exe -NoProfile -ExecutionPolicy Bypass -Command \"</span><span class="hljs-built_in">Start-Process</span> powershell <span class="hljs-literal">-ArgumentList</span> <span class="hljs-string">'-NoProfile -NoExit'</span> <span class="hljs-literal">-Verb</span> RunAs\<span class="hljs-string">""</span>
</code></pre>
<p><code>NOTE: Remember to replace placeholders like "DOMAIN" and "adminuser" with your actual domain name and admin username.</code></p>
<p>This command will give a command line prompt to enter password.</p>
<p>This command utilizes the `-NoExit` parameter, ensuring that the PowerShell console remains open after execution.</p>
<h3 id="heading-breaking-down-the-command">Breaking Down the Command</h3>
<p>- <code>runas /user:DOMAIN\adminuser</code>: Specifies the domain and admin user for which elevated privileges are required.</p>
<p>- <code>powershell.exe -NoProfile -ExecutionPolicy Bypass</code>: Launches PowerShell with specific settings. The `-NoProfile` flag ensures a minimal profile is used, and `-ExecutionPolicy Bypass` allows the execution of scripts.</p>
<p>- <code>Start-Process powershell</code>: Initiates a new PowerShell process.</p>
<p>- <code>-ArgumentList '-NoProfile -NoExit'</code>: Passes additional arguments to the new PowerShell process. The `-NoExit` parameter prevents the console from closing immediately.</p>
<p>- <code>-Verb RunAs</code>: Requests to run the process with elevated permissions.</p>
<h3 id="heading-use-cases">Use Cases</h3>
<p>- <strong>Script Execution</strong>: Running scripts that require administrative privileges.</p>
<p>- <strong>System Configurations</strong>: Making changes to system settings that necessitate elevated access.</p>
<p>- <strong>Software Installations</strong>: Installing software that requires administrative rights.</p>
]]></content:encoded></item><item><title><![CDATA[LINUX: "zsh" Theme I use]]></title><description><![CDATA[While trying to setup RHEL with WSL 2, I stumbled upon this very helpful blog https://wsl.dev/mobyrhel8/
While doing the setup, I found this zsh theme very nice, and I have been using it since then. The above mentioned blog already has the steps, but...]]></description><link>https://tech.anupamm.com/linux-zsh-theme-i-use</link><guid isPermaLink="true">https://tech.anupamm.com/linux-zsh-theme-i-use</guid><category><![CDATA[zsh]]></category><category><![CDATA[theme]]></category><category><![CDATA[Linux]]></category><category><![CDATA[shell]]></category><category><![CDATA[redhat]]></category><dc:creator><![CDATA[Anupam Majhi]]></dc:creator><pubDate>Tue, 23 Mar 2021 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1700496493427/e755b6f5-25be-4e60-9b7d-28b558ba7f90.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>While trying to setup RHEL with WSL 2, I stumbled upon this very helpful blog <a target="_blank" href="https://wsl.dev/mobyrhel8/">https://wsl.dev/mobyrhel8/</a></p>
<p>While doing the setup, I found this zsh theme very nice, and I have been using it since then. The above mentioned blog already has the steps, but it has a lot of other info about setting up RHEL in WSL2 as well. So here is the extract of setting up the zsh theme (steps are for RHEL8, might differ for other Linux dists).</p>
<h3 id="heading-1-setup-zshell">1. Setup ZShell</h3>
<p>If the zsh is not already installed, then install zsh.</p>
<pre><code class="lang-bash">dnf install -y sudo zsh cracklib-dicts
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700491369801/6926f33d-b7f0-4306-95a7-959133a7c56a.png" alt /></p>
<h3 id="heading-2-install-oh-my-zsh">2. Install "Oh My Zsh"</h3>
<p>Oh My Zsh is the configuration manager being used for this</p>
<pre><code class="lang-bash">sh -c <span class="hljs-string">"<span class="hljs-subst">$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)</span>"</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700491537525/f69f4495-a902-4d65-b3b8-570715ec03d0.png" alt /></p>
<h3 id="heading-3-update-user-to-use-zsh-as-the-default-shell">3. Update user to use zsh as the default shell</h3>
<p>Find the location of zsh installation</p>
<pre><code class="lang-bash">cat /etc/shells
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700494830943/d3af91ea-bbe7-47c0-81b0-7734047b177a.png" alt /></p>
<p>Use vi editor to update the default shell of the user to zsh by replacing the path <code>(example: ec2-user is the user we are working with)</code></p>
<pre><code class="lang-bash">sudo vi /etc/passwd
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700494426183/4ba5557c-1f3d-4be8-a8c7-5848db04cc8c.png" alt /></p>
<h3 id="heading-4-update-zsh-config-file">4. Update zsh config file</h3>
<p>As written in the installation message, we can now change the zsh config file. For now, we will only change the theme to Fino Theme.</p>
<pre><code class="lang-bash">vi <span class="hljs-variable">$HOME</span>/.zshrc
</code></pre>
<p>In the opened vi editor, look for the key ZSH_THEME and update it as below:</p>
<pre><code class="lang-bash">ZSH_THEME=<span class="hljs-string">"fino-time"</span>
</code></pre>
<p>Check if the config file got updated, and then load the new config file.</p>
<pre><code class="lang-bash"><span class="hljs-comment"># [Optional] Check if the theme value has been correctly saved</span>
grep ZSH_THEME <span class="hljs-variable">$HOME</span>/.zshrc

<span class="hljs-comment"># Reload the zsh configuration file</span>
<span class="hljs-built_in">source</span> <span class="hljs-variable">$HOME</span>/.zshrc
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700495262851/38e34af7-1e9c-42c0-a827-64c7e9a412a0.png" alt /></p>
<h3 id="heading-5-update-theme-settings">5. Update theme settings</h3>
<p>Open the theme settings in vi editor</p>
<pre><code class="lang-bash">vi <span class="hljs-variable">$HOME</span>/.oh-my-zsh/themes/fino-time.zsh-theme
</code></pre>
<p>Look for the PROMPT variable and modify it to add the variables</p>
<pre><code class="lang-bash">PROMPT=<span class="hljs-string">"╭─%{<span class="hljs-variable">$FG</span>[040]%}%n%{<span class="hljs-variable">$reset_color</span>%} %{<span class="hljs-variable">$FG</span>[239]%}at%{<span class="hljs-variable">$reset_color</span>%} %{<span class="hljs-variable">$FG</span>[033]%}<span class="hljs-subst">$(box_name)</span> (WSL: <span class="hljs-variable">$WSL_DISTRO_NAME</span> | kernel: <span class="hljs-subst">$(uname -r)</span>)%{<span class="hljs-variable">$reset_color</span>%} %{<span class="hljs-variable">$FG</span>[239]%}in%{<span class="hljs-variable">$reset_color</span>%} %{<span class="hljs-variable">$terminfo</span>[bold]<span class="hljs-variable">$FG</span>[226]%}%~%{<span class="hljs-variable">$reset_color</span>%}\$(git_prompt_info)\$(ruby_prompt_info)
╰─ %* \$(virtualenv_info)\$(prompt_char) "</span>
</code></pre>
<p>Reload the zsh configuration file, it will also reload the oh my zsh theme</p>
<pre><code class="lang-bash"><span class="hljs-built_in">source</span> <span class="hljs-variable">$HOME</span>/.zshrc
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1700495669171/812404c2-f8c7-4bd4-aeb8-33f3e2db7c0f.png" alt class="image--center mx-auto" /></p>
<p>That's it, now we have a nice-looking theme that gives a lot more information without being too overwhelming. It has a nice clock in the prompt too.</p>
]]></content:encoded></item><item><title><![CDATA[WINDOWS: Change Ubuntu hostname running on WSL]]></title><description><![CDATA[If you want to change the Ubuntu hostname running on WSL, you might have already tried updating the /etc/hostname file, only to realize that after a reboot, the host name changes back to the original hostname.
You also might have already figured that...]]></description><link>https://tech.anupamm.com/change-ubuntu-hostname-running-on-wsl</link><guid isPermaLink="true">https://tech.anupamm.com/change-ubuntu-hostname-running-on-wsl</guid><category><![CDATA[WSL]]></category><category><![CDATA[Ubuntu]]></category><category><![CDATA[Windows]]></category><category><![CDATA[hostname]]></category><category><![CDATA[Linux]]></category><dc:creator><![CDATA[Anupam Majhi]]></dc:creator><pubDate>Sun, 14 Mar 2021 22:55:45 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1700656038404/d616b0a2-0b7f-46c3-9a38-1f73889118da.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you want to change the Ubuntu hostname running on WSL, you might have already tried updating the /etc/hostname file, only to realize that after a reboot, the host name changes back to the original hostname.</p>
<p>You also might have already figured that the easiest way to do this is to change the host name of the Windows host on which you are running WSL. That’s probably obvious and not something you are looking for.</p>
<p>So, if you are trying to change the hostname of the Ubuntu distribution running in WSL without changing the host name of the Windows host system, there are few steps to follow.</p>
<h3 id="heading-step-1-note-down-your-ubuntu-hostname">Step 1: Note down your ubuntu hostname</h3>
<p>Make sure you note down your current ubuntu hostname, as we might need this going forward.</p>
<pre><code class="lang-bash">amajhi@ANUPAM-DESKTOP:~$ hostname
ANUPAM-DESKTOP
</code></pre>
<p>In this example ANUPAM-DESKTOP is the hostname which we will be replacing with the new hostname KATANA</p>
<h3 id="heading-step-2-update-the-wslconf-file">Step 2: Update the wsl.conf file</h3>
<p>Next you will need to update (or create if not present) the file /etc/wsl.conf</p>
<pre><code class="lang-bash">amajhi@ANUPAM-DESKTOP:~$ sudo vi /etc/wsl.conf
[sudo] password <span class="hljs-keyword">for</span> amajhi:
</code></pre>
<p>Then add/update the following lines to the file.</p>
<pre><code class="lang-bash">[network]
hostname = KATANA
generateHosts = <span class="hljs-literal">false</span>
</code></pre>
<p>The “generateHosts = false” makes sure that he hostname and hosts files are not replaced back to original on reboot.</p>
<h3 id="heading-step-3-update-the-hosts-file">Step 3: Update the hosts file</h3>
<p>This is an important step to prevent any host resolution issue. If this step is not done, then the system might get confused with what the hostname really is!</p>
<pre><code class="lang-bash">amajhi@KATANA:~$ sudo apt update
sudo: unable to resolve host KATANA: Name or service not known
</code></pre>
<p>Let’s look at the current hosts file and make it right.</p>
<pre><code class="lang-bash">amajhi@KATANA:~$ sudo vi /etc/hosts

<span class="hljs-comment"># This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry to /etc/wsl.conf:</span>
<span class="hljs-comment"># [network]</span>
<span class="hljs-comment"># generateHosts = false</span>
127.0.0.1 localhost
127.0.1.1 ANUPAM-DESKTOP.localdomain ANUPAM-DESKTOP

<span class="hljs-comment"># The following lines are desirable for IPv6 capable hosts</span>
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
</code></pre>
<p>To do the appropriate changes we need to update the /etc/hosts file and replace all occurrences of the old hostname ANUPAM-DESKTOP with the new hostname KATANA.</p>
<pre><code class="lang-bash"><span class="hljs-comment"># This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry to /etc/wsl.conf:</span>
<span class="hljs-comment"># [network]</span>
<span class="hljs-comment"># generateHosts = false</span>
127.0.0.1 localhost
127.0.1.1 KATANA.localdomain KATANA

<span class="hljs-comment"># The following lines are desirable for IPv6 capable hosts</span>
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
</code></pre>
<h3 id="heading-step-4-restart-the-wsl-instance">Step 4: Restart the WSL instance</h3>
<p>To restart the WSL instance we need to shut down the WSL instance and relaunch ubuntu.</p>
<pre><code class="lang-powershell"><span class="hljs-built_in">PS</span> C:\Users\amajhi&gt; wsl -<span class="hljs-literal">-shutdown</span>
</code></pre>
<p>or</p>
<pre><code class="lang-powershell"><span class="hljs-built_in">PS</span> C:\Users\amajhi&gt; wsl <span class="hljs-literal">-t</span> Ubuntu
</code></pre>
<p>Once you launch the ubuntu in WSL again, you should see the updated hostname intact and should be able to resolve host too. Let’s verify the resolution.</p>
<pre><code class="lang-bash">amajhi@KATANA:~$ sudo apt update
[sudo] password <span class="hljs-keyword">for</span> amajhi:
Hit:1 http://archive.ubuntu.com/ubuntu jammy InRelease
Hit:2 http://security.ubuntu.com/ubuntu jammy-security InRelease
Hit:3 http://archive.ubuntu.com/ubuntu jammy-updates InRelease
Hit:4 http://archive.ubuntu.com/ubuntu jammy-backports InRelease
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
64 packages can be upgraded. Run <span class="hljs-string">'apt list --upgradable'</span> to see them.
</code></pre>
<p>That’s it!</p>
]]></content:encoded></item><item><title><![CDATA[KNN — An Introduction]]></title><description><![CDATA[KNN or k-Nearest Neighbors algorithm is quite a classic algorithm to solve classification problems. It is based on a simple assumption that objects in a group (neighbors) or close to the group tend to have similar traits and hence can be classified. ...]]></description><link>https://tech.anupamm.com/knn-an-introduction</link><guid isPermaLink="true">https://tech.anupamm.com/knn-an-introduction</guid><category><![CDATA[algorithms]]></category><category><![CDATA[Data Science]]></category><category><![CDATA[introduction]]></category><category><![CDATA[knn]]></category><dc:creator><![CDATA[Anupam Majhi]]></dc:creator><pubDate>Sun, 28 Jul 2019 08:34:16 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1693157876637/76368d96-a557-4e29-8189-3f46a8ace1b1.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>KNN or k-Nearest Neighbors algorithm is quite a classic algorithm to solve classification problems. It is based on a simple assumption that objects in a group (neighbors) or close to the group tend to have similar traits and hence can be classified. You can already make out that this assumption is actually over-simplified. Let’s see how good or bad can this assumption be.</p>
<h3 id="heading-knn-around-us">KNN around us</h3>
<p>Though this is over-simplified, you would have noticed around yourself that people with similar interests usually have similar traits. Let’s think of a few examples:</p>
<p>People following similar kinds of news headlines and in a similar age group can roughly be classified into the political parties they will most likely vote for. People with similar calorie intake and a similar amount of physical activity can be classified as healthy or not healthy. Emails with similar choices of words and similar formats can be classified as spam or not spam and so on …</p>
<h3 id="heading-how-does-knn-work">How does KNN work?</h3>
<p>The letter k in a kNN is the number of nearest neighbors that it will take into account to decide to which class an object belongs. So, quite simply, if k=10, we check the 10 closest neighbors of the object we want to classify, and if it has more neighbors of type A and fewer neighbors of other types B or C, we say the object belongs to type/class A.</p>
<p>But how do we measure which is closest? The KNN algorithm compares the position of the data point in question with all the training data points (<a target="_blank" href="https://anupamm.com/blog/model-selection-train-validate-test">Check out this blog if you are not sure what training a model is</a>). To find the distance we can use any distance metric, even Euclidian distance. Once the model finds out who are its ‘k’ closest neighbors, it just goes ahead with voting among those members to find out where it belongs.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1693088564177/548075ac-e1c2-4b60-8cc9-fcab11987b14.png" alt class="image--center mx-auto" /></p>
<p>Model trying to find where the yellow star belongs based on 5 nearest neighbors</p>
<p>In the above figure, the model is trying to figure out which category the uncategorized data point (yellow star) belongs to (assuming k=5). We can easily see here that out of 5 nearest neighbors, 4 belong to the red squares category. Hence, the yellow star should also be a red square category data point.</p>
<h3 id="heading-what-is-the-best-value-of-k">What is the best value of ‘k’?</h3>
<p>Firstly, there is no single best universal value of k. Then how do we decide what value of k to use? The answer is it depends. It depends on the data, more precisely the <a target="_blank" href="https://anupamm.com/blog/model-selection-train-validate-test">training and validation</a> data. While training and validating with different k values we have to make sure we get the least error possible, and then it’s up to us to decide which ‘k’ value to use.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1693088565195/732ac8c3-5582-432b-89e6-7da3cae29424.jpeg" alt class="image--center mx-auto" /></p>
<p><code>Example: Validation error for different values of k   image source: AnalyticsVidya</code></p>
<p>In the example image above, the plot between different k values vs. validation error shows that we get the lowest error value somewhere around k=10. Hence, in this case, k=10 should be our choice.</p>
<h3 id="heading-knn-and-curse-of-dimensionality">KNN and Curse of Dimensionality</h3>
<p>Just like any other data science algorithm, KNN faces the curse of dimensionality. The curse of Dimensionality is basically the difficulty/error that a model faces as we keep increasing the number of features/dimensions. For example, a model using a few features (e.g. age, sex, height) would most likely predict results better than a model using a huge number of such features.</p>
<p>To understand better, let’s imagine we are trying to find out the shoe size of a person based on age and height. Here we just have 2 dimensions to check, i.e. age and height, hence there can only be certain kinds of people with a certain amount of differences/individuality/noise. So we can quite accurately predict what the shoe size could be. But what if the data also has additional dimensions like weight, city, and favorite color? The model can still predict well enough, but there are high chances that the prediction wouldn’t be accurate enough. The reason is that two people may live in different cities but still have similar physical features, but in KNN, those two people will not be very close neighbors. Consider ‘favorite color’ as a feature, that will make it even more difficult.</p>
<p>The solution is to remove unnecessary or irrelevant features/dimensions and keep the number of features to a minimum.</p>
<h3 id="heading-knn-regression">KNN — Regression</h3>
<p>I did mention in the beginning that KNN is a classification algorithm. However, KNN is also used for regression models. For the unaware, a regression model is where we try to find out the actual value instead of a category, e.g. trying to predict height, salary, price, etc. The only difference in KNN for Regression compared to KNN for classification is that, instead of voting among closest neighbors, the model takes an average of the actual value (e.g. salary) of all the k nearest neighbors. There can be different ways to calculate the average.</p>
<p>That brings us to the end of this post on KNN introduction.</p>
]]></content:encoded></item><item><title><![CDATA[HADOOP: Basic Architecture (Hadoop 2.x)]]></title><description><![CDATA[Apache Hadoop has earned quite a traction in the recent past. It is a framework for processing of large datasets in a distributed computing environment.  
 All this started back in 2003 when Google released its paper on Google File System. Later the ...]]></description><link>https://tech.anupamm.com/hadoop-basic-architecture-hadoop-2x</link><guid isPermaLink="true">https://tech.anupamm.com/hadoop-basic-architecture-hadoop-2x</guid><category><![CDATA[apache]]></category><category><![CDATA[hadoop]]></category><category><![CDATA[big data]]></category><category><![CDATA[architecture]]></category><category><![CDATA[node]]></category><dc:creator><![CDATA[Anupam Majhi]]></dc:creator><pubDate>Wed, 05 Sep 2018 12:07:35 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1693329485075/e5d7dc91-3e4d-43f4-b7ee-e2f189ebd006.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Apache Hadoop has earned quite a traction in the recent past. It is a framework for processing of large datasets in a distributed computing environment.  </p>
<p> All this started back in 2003 when Google released its paper on Google File System. Later the Hadoop project started taking that as a blueprint and it has reached here today.  </p>
<p> Hadoop 1.x had quite a different structure and had certain limitations, which have been addressed in Hadoop 2.x versions with a different architecture with different components to enable more reliable, distributed, parallel processing of Big Data.  </p>
<p> Hadoop comprises of 2 main core components:  </p>
<ol>
<li>HDFS (Hadoop Distributed File System) — Storage Unit  </li>
<li>YARN (Yet Another Resource Negotiator) — Processing Unit</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1693088558134/8eb1c296-5372-47b4-8181-31b0b0942985.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-hdfs">HDFS</h3>
<p>HDFS comprises of 3 components.</p>
<p><strong>Name Node</strong></p>
<p>The name Node is the ‘master’ component of HDFS system. It stores the metadata of HDFS, which is essentially the directory tree of the files in HDFS, and a track of all the files across the cluster.</p>
<p>The name node does not store the actual data. It knows the list of blocks and locations for any given file.</p>
<p>When the name node is down, the cluster itself is considered down as the cluster becomes inaccessible.</p>
<p>It stores fsimage(snapshot of the filesystem at start-up) and edit logs (sequence of changes made to the filesystem after start-up).</p>
<p><strong>Secondary Name Node</strong>  </p>
<p>The secondary Name node is NOT a backup name node as the name might suggest. It is more of an assistive node.  </p>
<p>It is responsible for taking checkpoints of the file system metadata present in the name node. It does this by checkpointing fsimage. It gets the edit logs from the name node in regular intervals and creates the checkpoint. Then it copies this fsimage back to the name node.  </p>
<p>The name node uses this fsimage in the next start-up so that it reduces start-up time.</p>
<p><strong>Data Node</strong>  </p>
<p>This is where the actual data is stored. The name node keeps track of each block that is stored in these data nodes. It is also known as the ‘slave’.  </p>
<p>When it starts up, it announces its presence to name node and also the data blocks it is responsible for. This is the workhorse of Hadoop HDFS.</p>
<h3 id="heading-yarn">YARN</h3>
<p>YARN comprises of 2 components:  </p>
<p><strong>Resource Manager</strong>  </p>
<p>The resource Manager is responsible for taking inventory of available resources and running critical services, the most critical of which is the Scheduler.  </p>
<p>The scheduler allocates resources. It negotiates the available resources in the cluster and manages the distributed processing. It works along with the Node Manager to attain this.</p>
<p><strong>Node Manager</strong>  </p>
<p>The node manager acts as the ‘slave’ to the Resource Manager.</p>
<p>It keeps track of the tasks and jobs that are being deployed to the data nodes. It helps the Resource manager keep track of available space and processing power. Memory, bandwidth, etc. so that tasks can be distributed to the data nodes.</p>
]]></content:encoded></item><item><title><![CDATA[DOCKER: The ENTRYPOINT and CMD]]></title><description><![CDATA[In a Dockerfile, the use of ENTRYPOINT and CMD is crucial in defining the way a container behaves. However, it does confuse a lot of us regarding the usage, best practices, and key considerations when using these instructions.
ENTRYPOINT vs CMD:
ENTR...]]></description><link>https://tech.anupamm.com/docker-the-entrypoint-and-cmd</link><guid isPermaLink="true">https://tech.anupamm.com/docker-the-entrypoint-and-cmd</guid><category><![CDATA[Docker]]></category><category><![CDATA[entrypoint]]></category><category><![CDATA[cmd]]></category><category><![CDATA[containers]]></category><category><![CDATA[Dockerfile]]></category><dc:creator><![CDATA[Anupam Majhi]]></dc:creator><pubDate>Thu, 17 May 2018 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1701259379999/cda70c79-87d0-42ed-b262-815c3012ceae.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In a Dockerfile, the use of <code>ENTRYPOINT</code> and <code>CMD</code> is crucial in defining the way a container behaves. However, it does confuse a lot of us regarding the usage, best practices, and key considerations when using these instructions.</p>
<h2 id="heading-entrypoint-vs-cmd"><strong>ENTRYPOINT vs CMD:</strong></h2>
<h3 id="heading-entrypoint">ENTRYPOINT:</h3>
<p>The <code>ENTRYPOINT</code> instruction sets the primary command that will executed by the container when it starts. It can be specified with or without an executable and also allows for arguments.</p>
<pre><code class="lang-Dockerfile"><span class="hljs-keyword">ENTRYPOINT</span><span class="bash"> [<span class="hljs-string">"nginx"</span>, <span class="hljs-string">"-g"</span>, <span class="hljs-string">"daemon off;"</span>]</span>
</code></pre>
<p><code>ENTRYPOINT</code> command cannot be overridden by appending a command while executing 'docker run' at runtime. However, the arguments can be appended.</p>
<p>Example Dockerfile:</p>
<pre><code class="lang-dockerfile"><span class="hljs-keyword">FROM</span> ubuntu
<span class="hljs-keyword">ENTRYPOINT</span><span class="bash"> [<span class="hljs-string">"echo"</span>, <span class="hljs-string">"Hello"</span>]</span>
</code></pre>
<p>Run the container with a command:</p>
<pre><code class="lang-bash">docker run my-image Goodbye
</code></pre>
<p>Output:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># output</span>
Hello Goodbye
</code></pre>
<p>If we really want to overwrite the command in <code>ENTRYPOINT</code>, we need to use the '--entrypoint' with docker run:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Example</span>
docker run -it --entrypoint /bin/sh my_custom_image
</code></pre>
<h3 id="heading-cmd">CMD:</h3>
<p>The <code>CMD</code> instruction sets the default command for the container. If used without an <code>ENTRYPOINT</code>, it becomes the default command and arguments that will be used when the container starts. Whereas, when used with an <code>ENTRYPOINT</code>, it provides default arguments for the entry point.</p>
<p>This can be overridden though at runtime by passing a command when running the container using 'docker run'.</p>
<p>Example:</p>
<pre><code class="lang-Dockerfile"><span class="hljs-keyword">CMD</span><span class="bash"> [<span class="hljs-string">"nginx"</span>, <span class="hljs-string">"-g"</span>, <span class="hljs-string">"daemon off;"</span>]</span>
</code></pre>
<p><code>CMD</code> command can be overridden by appending a command while executing 'docker run' at runtime.</p>
<p>Example Dockerfile:</p>
<pre><code class="lang-dockerfile"><span class="hljs-keyword">FROM</span> ubuntu
<span class="hljs-keyword">CMD</span><span class="bash"> [<span class="hljs-string">"echo"</span>, <span class="hljs-string">"Hello"</span>]</span>
</code></pre>
<p>Run the container with a command:</p>
<pre><code class="lang-bash">docker run my-image Goodbye
</code></pre>
<p>Output:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># output</span>
Goodbye
</code></pre>
<h2 id="heading-best-practices"><strong>Best Practices:</strong></h2>
<p>We should prefer the exec form of the <code>ENTRYPOINT</code> and <code>CMD</code> to avoid shell processing.</p>
<p>Example:</p>
<pre><code class="lang-Dockerfile"><span class="hljs-keyword">ENTRYPOINT</span><span class="bash"> [<span class="hljs-string">"echo"</span>, <span class="hljs-string">"Hello, <span class="hljs-variable">$USER</span>"</span>]</span>
</code></pre>
<p>If we use the insecure way of using shell form instead, it might introduce a security vulnerability. The shell form can be abused to perform shell injection. Additionally, the shell form becomes dependent on the particular shell in use and if a different shell is being used in a distribution, it might not be consistent.</p>
<pre><code class="lang-dockerfile"><span class="hljs-comment"># An example where $USER can be used for shell injection vulnerability.</span>
<span class="hljs-comment"># Malicious code can be introduced if the $USER variable is not sanitized.</span>
<span class="hljs-keyword">FROM</span> ubuntu
<span class="hljs-keyword">CMD</span><span class="bash"> <span class="hljs-built_in">echo</span> <span class="hljs-string">"Hello, <span class="hljs-variable">$USER</span>"</span></span>
</code></pre>
<h2 id="heading-choosing-between-cmd-and-entrypoint"><strong>Choosing Between CMD and ENTRYPOINT</strong></h2>
<ul>
<li><p>Use <code>CMD</code> when you want to provide default values for the command and allow them to be easily overridden at runtime.</p>
</li>
<li><p>Use <code>ENTRYPOINT</code> when you want to set a fixed primary command and allow users to append additional arguments.</p>
</li>
</ul>
<p>In many cases, combining both instructions offers a balance of flexibility and definition. Understanding these use cases will empower you to create more versatile and user-friendly Docker images.</p>
<h2 id="heading-entrypoint-as-a-script"><strong>ENTRYPOINT as a Script:</strong></h2>
<p>If we have a scenario where we want to run a script instead of any particular command, and maybe pass a default argument, we can do it seamlessly with ENTRYPOINT and using CMD along with it.</p>
<pre><code class="lang-dockerfile"><span class="hljs-keyword">FROM</span> node

<span class="hljs-comment"># Set the working directory</span>
<span class="hljs-keyword">WORKDIR</span><span class="bash"> /app</span>

<span class="hljs-comment"># Copy the application files</span>
<span class="hljs-keyword">COPY</span><span class="bash"> . .</span>

<span class="hljs-comment"># Set the script as the ENTRYPOINT</span>
<span class="hljs-keyword">ENTRYPOINT</span><span class="bash"> [<span class="hljs-string">"./entrypoint.sh"</span>]</span>

<span class="hljs-comment"># Default argument 'start' to pass to the script if nothing mentioned in run.</span>
<span class="hljs-keyword">CMD</span><span class="bash"> [<span class="hljs-string">"start"</span>]</span>
</code></pre>
<h2 id="heading-conclusion">Conclusion:</h2>
<p>Mastering Dockerfile entry points empowers you to create efficient, modular, and customizable Docker images. Whether you're building a simple web server or a complex microservices architecture, understanding how to leverage <code>ENTRYPOINT</code> and <code>CMD</code> is essential for Dockerfile success.</p>
<p>Happy Dockerizing!</p>
<hr />
]]></content:encoded></item><item><title><![CDATA[SCORCH: Useful Orchestrator SQL Queries]]></title><description><![CDATA[Microsoft’s System Center Orchestrator is quite a useful tool but with limited development and support from Microsoft. Sometimes it becomes quite tough to manage the tool without much ability to fetch information like list of running Runbooks or mayb...]]></description><link>https://tech.anupamm.com/scorch-useful-orchestrator-sql-queries</link><guid isPermaLink="true">https://tech.anupamm.com/scorch-useful-orchestrator-sql-queries</guid><category><![CDATA[SQL]]></category><category><![CDATA[Microsoft]]></category><category><![CDATA[Orchestrator]]></category><category><![CDATA[Scorch]]></category><dc:creator><![CDATA[Anupam Majhi]]></dc:creator><pubDate>Mon, 26 Mar 2018 21:11:27 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1693330162097/cf562f3c-ff30-4473-bcdd-4eaabf2b840d.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Microsoft’s System Center Orchestrator is quite a useful tool but with limited development and support from Microsoft. Sometimes it becomes quite tough to manage the tool without much ability to fetch information like list of running Runbooks or maybe simply to find the location of a runbook by name.</p>
<p>Since there are not many options or tools available in Orchestrator which could help us troubleshoot or analyze the Orchestrator environment, few SQL queries come in handy. It will also be useful if you are trying to generate some kind of report of the environment.</p>
<p>Here are some of those useful queries.</p>
<p><strong>Get Runbook (with date) and Folder Path</strong></p>
<p>This will list all the runbooks Orchestrator along with its location path (folder structure). This also gives you the ‘Last Modified’ date and time for each runbook, just in case it’s important for you to filter out older runbooks.</p>
<pre><code class="lang-sql"><span class="hljs-keyword">use</span> orchestrator;

<span class="hljs-keyword">with</span> RunbookPath <span class="hljs-keyword">as</span>
(
<span class="hljs-keyword">select</span> <span class="hljs-string">'Policies\'</span> + <span class="hljs-keyword">cast</span>(<span class="hljs-keyword">name</span> <span class="hljs-keyword">as</span> <span class="hljs-built_in">varchar</span>(<span class="hljs-keyword">max</span>)) <span class="hljs-keyword">as</span> [<span class="hljs-keyword">path</span>], uniqueid <span class="hljs-keyword">from</span> dbo.folders b
<span class="hljs-keyword">where</span> b.ParentID=<span class="hljs-string">'00000000-0000-0000-0000-000000000000'</span> <span class="hljs-keyword">and</span> disabled = <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> deleted= <span class="hljs-number">0</span>
<span class="hljs-keyword">union</span> <span class="hljs-keyword">all</span>
<span class="hljs-keyword">select</span> <span class="hljs-keyword">cast</span>(c.[<span class="hljs-keyword">path</span>] + <span class="hljs-string">'\'</span> + <span class="hljs-keyword">cast</span>(b.name <span class="hljs-keyword">as</span> <span class="hljs-built_in">varchar</span>(<span class="hljs-keyword">max</span>)) <span class="hljs-keyword">as</span> <span class="hljs-built_in">varchar</span>(<span class="hljs-keyword">max</span>)), b.uniqueid <span class="hljs-keyword">from</span> dbo.FOLDERS b
<span class="hljs-keyword">inner</span> <span class="hljs-keyword">join</span>
RunbookPath c <span class="hljs-keyword">on</span> b.ParentID = c.UniqueID
<span class="hljs-keyword">where</span> b.Disabled = <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> b.Deleted = <span class="hljs-number">0</span>
)

<span class="hljs-keyword">SELECT</span> f.path <span class="hljs-keyword">AS</span> RunbookPath,r.name <span class="hljs-keyword">AS</span> RunbookName, r.LastModified <span class="hljs-keyword">AS</span> <span class="hljs-string">'Runbook Last Modified'</span> <span class="hljs-keyword">from</span> POLICIES <span class="hljs-keyword">as</span> r 
<span class="hljs-keyword">INNER</span> <span class="hljs-keyword">JOIN</span> RunbookPath <span class="hljs-keyword">as</span> f <span class="hljs-keyword">on</span> r.ParentID = f.UniqueID
<span class="hljs-keyword">WHERE</span> r.Deleted = <span class="hljs-number">0</span>
</code></pre>
<p><strong>Get Running Runbooks</strong></p>
<p>This query will help you fetch all the runbooks (along with path as previous) that’s running and has not yet completed. You may use it to understand if any runbook is running that actually should not be running. There is indeed a tool available to do this already, but it does not provide the path of runbook, in such a situation if we have multiple runbooks with same name, it becomes difficult to search.</p>
<pre><code class="lang-sql"><span class="hljs-keyword">use</span> orchestrator;

<span class="hljs-keyword">with</span> RunbookPath <span class="hljs-keyword">as</span>
(
<span class="hljs-keyword">select</span> <span class="hljs-string">'Policies\'</span> + <span class="hljs-keyword">cast</span>(<span class="hljs-keyword">name</span> <span class="hljs-keyword">as</span> <span class="hljs-built_in">varchar</span>(<span class="hljs-keyword">max</span>)) <span class="hljs-keyword">as</span> [<span class="hljs-keyword">path</span>], uniqueid <span class="hljs-keyword">from</span> dbo.folders b
<span class="hljs-keyword">where</span> b.ParentID=<span class="hljs-string">'00000000-0000-0000-0000-000000000000'</span> <span class="hljs-keyword">and</span> disabled = <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> deleted= <span class="hljs-number">0</span>
<span class="hljs-keyword">union</span> <span class="hljs-keyword">all</span>
<span class="hljs-keyword">select</span> <span class="hljs-keyword">cast</span>(c.[<span class="hljs-keyword">path</span>] + <span class="hljs-string">'\'</span> + <span class="hljs-keyword">cast</span>(b.name <span class="hljs-keyword">as</span> <span class="hljs-built_in">varchar</span>(<span class="hljs-keyword">max</span>)) <span class="hljs-keyword">as</span> <span class="hljs-built_in">varchar</span>(<span class="hljs-keyword">max</span>)), b.uniqueid <span class="hljs-keyword">from</span> dbo.FOLDERS b
<span class="hljs-keyword">inner</span> <span class="hljs-keyword">join</span>
RunbookPath c <span class="hljs-keyword">on</span> b.ParentID = c.UniqueID
<span class="hljs-keyword">where</span> b.Disabled = <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> b.Deleted = <span class="hljs-number">0</span>
)

<span class="hljs-keyword">select</span> f.path <span class="hljs-keyword">AS</span> RunbookPath,r.name <span class="hljs-keyword">AS</span> RunbookName,A.[Computer] <span class="hljs-keyword">as</span> RunbookServer <span class="hljs-keyword">from</span> POLICIES <span class="hljs-keyword">as</span> r 
<span class="hljs-keyword">inner</span> <span class="hljs-keyword">join</span> RunbookPath <span class="hljs-keyword">as</span> f <span class="hljs-keyword">on</span> r.ParentID = f.UniqueID
<span class="hljs-keyword">inner</span> <span class="hljs-keyword">join</span> [Microsoft.SystemCenter.Orchestrator.Runtime.Internal].[Jobs] <span class="hljs-keyword">as</span> J <span class="hljs-keyword">on</span> J.RunbookId = r.UniqueID
<span class="hljs-keyword">INNER</span> <span class="hljs-keyword">JOIN</span> [dbo].[ACTIONSERVERS] A <span class="hljs-keyword">ON</span> J.RunbookServerId = A.UniqueID
<span class="hljs-keyword">WHERE</span> r.Deleted = <span class="hljs-number">0</span> <span class="hljs-keyword">AND</span>
J.[StatusId] = <span class="hljs-number">1</span>
</code></pre>
<p><strong>Get Runbooks with ‘Common-Data Log’ and ‘Activity-Specific Log’ Enabled</strong></p>
<p>Ever wondered how to find which Runbooks have the ‘Common-Data Logging’ and ‘Activity-Specific Logging’ enabled under runbook properties?</p>
<p>The following query will help you find that out. Here <strong>‘1’</strong> means enabled/checked and <strong>‘0’</strong> means disabled/unchecked</p>
<pre><code class="lang-sql"><span class="hljs-keyword">use</span> orchestrator;

<span class="hljs-keyword">with</span> RunbookPath <span class="hljs-keyword">as</span>
(
<span class="hljs-keyword">select</span> <span class="hljs-string">'Policies\'</span> + <span class="hljs-keyword">cast</span>(<span class="hljs-keyword">name</span> <span class="hljs-keyword">as</span> <span class="hljs-built_in">varchar</span>(<span class="hljs-keyword">max</span>)) <span class="hljs-keyword">as</span> [<span class="hljs-keyword">path</span>], uniqueid <span class="hljs-keyword">from</span> dbo.folders b
<span class="hljs-keyword">where</span> b.ParentID=<span class="hljs-string">'00000000-0000-0000-0000-000000000000'</span> <span class="hljs-keyword">and</span> disabled = <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> deleted= <span class="hljs-number">0</span>
<span class="hljs-keyword">union</span> <span class="hljs-keyword">all</span>
<span class="hljs-keyword">select</span> <span class="hljs-keyword">cast</span>(c.[<span class="hljs-keyword">path</span>] + <span class="hljs-string">'\'</span> + <span class="hljs-keyword">cast</span>(b.name <span class="hljs-keyword">as</span> <span class="hljs-built_in">varchar</span>(<span class="hljs-keyword">max</span>)) <span class="hljs-keyword">as</span> <span class="hljs-built_in">varchar</span>(<span class="hljs-keyword">max</span>)), b.uniqueid <span class="hljs-keyword">from</span> dbo.FOLDERS b
<span class="hljs-keyword">inner</span> <span class="hljs-keyword">join</span>
RunbookPath c <span class="hljs-keyword">on</span> b.ParentID = c.UniqueID
<span class="hljs-keyword">where</span> b.Disabled = <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> b.Deleted = <span class="hljs-number">0</span>
)

<span class="hljs-keyword">select</span> f.path <span class="hljs-keyword">AS</span> RunbookPath,r.name <span class="hljs-keyword">AS</span> RunbookName,r.LogCommonData, r.LogSpecificData <span class="hljs-keyword">from</span> POLICIES <span class="hljs-keyword">as</span> r 
<span class="hljs-keyword">inner</span> <span class="hljs-keyword">join</span>
RunbookPath <span class="hljs-keyword">as</span> f <span class="hljs-keyword">on</span> r.ParentID = f.UniqueID
<span class="hljs-keyword">where</span> r.Deleted = <span class="hljs-number">0</span> <span class="hljs-keyword">AND</span> (r.LogCommonData = <span class="hljs-number">1</span> <span class="hljs-keyword">OR</span> r.LogSpecificData = <span class="hljs-number">1</span>)
</code></pre>
<p><strong>Get All ‘Powershell / C# /</strong> <a target="_blank" href="http://VB.Net"><strong>VB.Net</strong></a><strong>’ Scripts</strong></p>
<p>This query will list down all the scripts that use the inbuilt activity <strong><em>‘Run .Net Script’</em></strong>.</p>
<p>You may use generate a report of all the scripts. In my work, I have used this query (with small modification) to list down all scripts that use a particular password hard-coded, so that I could fix those to avoid security risk.</p>
<blockquote>
<p><em>Note: This query might take a long time to execute depending on how many scripts you have in the Orchestrator.</em></p>
</blockquote>
<pre><code class="lang-sql"><span class="hljs-keyword">use</span> orchestrator;

<span class="hljs-keyword">with</span> RunbookPath <span class="hljs-keyword">as</span>
(
<span class="hljs-keyword">select</span> <span class="hljs-string">'Policies\'</span> + <span class="hljs-keyword">cast</span>(<span class="hljs-keyword">name</span> <span class="hljs-keyword">as</span> <span class="hljs-built_in">varchar</span>(<span class="hljs-keyword">max</span>)) <span class="hljs-keyword">as</span> [<span class="hljs-keyword">path</span>], uniqueid <span class="hljs-keyword">from</span> dbo.folders b
<span class="hljs-keyword">where</span> b.ParentID=<span class="hljs-string">'00000000-0000-0000-0000-000000000000'</span> <span class="hljs-keyword">and</span> disabled = <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> deleted= <span class="hljs-number">0</span>
<span class="hljs-keyword">union</span> <span class="hljs-keyword">all</span>
<span class="hljs-keyword">select</span> <span class="hljs-keyword">cast</span>(c.[<span class="hljs-keyword">path</span>] + <span class="hljs-string">'\'</span> + <span class="hljs-keyword">cast</span>(b.name <span class="hljs-keyword">as</span> <span class="hljs-built_in">varchar</span>(<span class="hljs-keyword">max</span>)) <span class="hljs-keyword">as</span> <span class="hljs-built_in">varchar</span>(<span class="hljs-keyword">max</span>)), b.uniqueid <span class="hljs-keyword">from</span> dbo.FOLDERS b
<span class="hljs-keyword">inner</span> <span class="hljs-keyword">join</span>
RunbookPath c <span class="hljs-keyword">on</span> b.ParentID = c.UniqueID
<span class="hljs-keyword">where</span> b.Disabled = <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> b.Deleted = <span class="hljs-number">0</span>
)

<span class="hljs-keyword">SELECT</span> F.Path <span class="hljs-keyword">as</span> RunbookPath,RB.Name <span class="hljs-keyword">AS</span> RunBook,ACT.Name <span class="hljs-keyword">AS</span> Activity,PS.ScriptType,PS.ScriptBody,PS.PublishedData,Act.Enabled <span class="hljs-keyword">as</span> ActivityEnabled,RB.LastModified  <span class="hljs-keyword">FROM</span> [Orchestrator].[dbo].[RUNDOTNETSCRIPT] <span class="hljs-keyword">AS</span> PS
<span class="hljs-keyword">INNER</span> <span class="hljs-keyword">JOIN</span> [Orchestrator].[dbo].[OBJECTS] <span class="hljs-keyword">AS</span> Act <span class="hljs-keyword">ON</span> PS.UniqueID = Act.UniqueID
<span class="hljs-keyword">INNER</span> <span class="hljs-keyword">JOIN</span> [Orchestrator].[dbo].[POLICIES] <span class="hljs-keyword">AS</span> RB <span class="hljs-keyword">ON</span> RB.UniqueID = Act.ParentID 
<span class="hljs-keyword">INNER</span> <span class="hljs-keyword">JOIN</span> RunbookPath <span class="hljs-keyword">AS</span> F <span class="hljs-keyword">ON</span> F.UniqueID = RB.ParentID
<span class="hljs-keyword">where</span> PS.Scriptbody <span class="hljs-keyword">is</span> <span class="hljs-keyword">not</span> <span class="hljs-literal">Null</span>
<span class="hljs-keyword">AND</span> Act.Deleted = <span class="hljs-number">0</span> <span class="hljs-keyword">AND</span> RB.Deleted = <span class="hljs-number">0</span>
<span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span> RB.LastModified,F.Path
</code></pre>
<p><strong>Get All Activities Objects</strong></p>
<p>If you want to list down all the runbook activities, this query will be very useful.</p>
<blockquote>
<p><em>Pro Tip: You can use the ‘ObjectType’ column to filter the activities by type of activity.</em></p>
</blockquote>
<pre><code class="lang-sql"><span class="hljs-keyword">use</span> orchestrator;

<span class="hljs-keyword">with</span> RunbookPath <span class="hljs-keyword">as</span>
(
<span class="hljs-keyword">select</span> <span class="hljs-string">'Policies\'</span> + <span class="hljs-keyword">cast</span>(<span class="hljs-keyword">name</span> <span class="hljs-keyword">as</span> <span class="hljs-built_in">varchar</span>(<span class="hljs-keyword">max</span>)) <span class="hljs-keyword">as</span> [<span class="hljs-keyword">path</span>], uniqueid <span class="hljs-keyword">from</span> dbo.folders b
<span class="hljs-keyword">where</span> b.ParentID=<span class="hljs-string">'00000000-0000-0000-0000-000000000000'</span> <span class="hljs-keyword">and</span> disabled = <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> deleted= <span class="hljs-number">0</span>
<span class="hljs-keyword">union</span> <span class="hljs-keyword">all</span>
<span class="hljs-keyword">select</span> <span class="hljs-keyword">cast</span>(c.[<span class="hljs-keyword">path</span>] + <span class="hljs-string">'\'</span> + <span class="hljs-keyword">cast</span>(b.name <span class="hljs-keyword">as</span> <span class="hljs-built_in">varchar</span>(<span class="hljs-keyword">max</span>)) <span class="hljs-keyword">as</span> <span class="hljs-built_in">varchar</span>(<span class="hljs-keyword">max</span>)), b.uniqueid <span class="hljs-keyword">from</span> dbo.FOLDERS b
<span class="hljs-keyword">inner</span> <span class="hljs-keyword">join</span>
RunbookPath c <span class="hljs-keyword">on</span> b.ParentID = c.UniqueID
<span class="hljs-keyword">where</span> b.Disabled = <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> b.Deleted = <span class="hljs-number">0</span>
)


<span class="hljs-comment">/** 7A65BD17-9532-4D07-A6DA-E0F89FA0203E is the code for Link Objects, Remove the condition (AND Act.ObjectType &lt;&gt; '7A65BD17-9532-4D07-A6DA-E0F89FA0203E') if you want LINK objects too **/</span>

<span class="hljs-keyword">SELECT</span> F.Path,RB.Name <span class="hljs-keyword">AS</span> RunBook,ACT.Name <span class="hljs-keyword">AS</span> Activity, RB.LastModified <span class="hljs-keyword">AS</span> <span class="hljs-string">'Runbook Last Modified'</span>  
<span class="hljs-keyword">FROM</span> [Orchestrator].[dbo].[OBJECTS] <span class="hljs-keyword">AS</span> Act
<span class="hljs-keyword">INNER</span> <span class="hljs-keyword">JOIN</span> [Orchestrator].[dbo].[POLICIES] <span class="hljs-keyword">AS</span> RB <span class="hljs-keyword">ON</span> RB.UniqueID = Act.ParentID 
<span class="hljs-keyword">INNER</span> <span class="hljs-keyword">JOIN</span> RunbookPath <span class="hljs-keyword">AS</span> F <span class="hljs-keyword">ON</span> F.UniqueID = RB.ParentID
<span class="hljs-keyword">where</span> Act.Deleted = <span class="hljs-number">0</span> <span class="hljs-keyword">AND</span> rb.Deleted = <span class="hljs-number">0</span> <span class="hljs-keyword">AND</span> Act.ObjectType &lt;&gt; <span class="hljs-string">'7A65BD17-9532-4D07-A6DA-E0F89FA0203E'</span>
<span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span> F.Path, RB.Name , Act.Name
</code></pre>
<p><strong>Get Checked Out Runbooks</strong></p>
<p>Sometimes we check-out the runbooks to edit or maybe for some other reason and forget to check-in; Or maybe someone else has checked-out to work on it. And when we run the runbook it either fails or uses the older version of the runbook.</p>
<p>So, it becomes essential to find out if there is any runbook that has been checked out and who has checked it out. The following query might be useful for you in such scenarios.</p>
<pre><code class="lang-sql"><span class="hljs-keyword">use</span> orchestrator;

<span class="hljs-keyword">with</span> RunbookPath <span class="hljs-keyword">as</span>
(
<span class="hljs-keyword">select</span> <span class="hljs-string">'Policies\'</span> + <span class="hljs-keyword">cast</span>(<span class="hljs-keyword">name</span> <span class="hljs-keyword">as</span> <span class="hljs-built_in">varchar</span>(<span class="hljs-keyword">max</span>)) <span class="hljs-keyword">as</span> [<span class="hljs-keyword">path</span>], uniqueid <span class="hljs-keyword">from</span> dbo.folders b
<span class="hljs-keyword">where</span> b.ParentID=<span class="hljs-string">'00000000-0000-0000-0000-000000000000'</span> <span class="hljs-keyword">and</span> disabled = <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> deleted= <span class="hljs-number">0</span>
<span class="hljs-keyword">union</span> <span class="hljs-keyword">all</span>
<span class="hljs-keyword">select</span> <span class="hljs-keyword">cast</span>(c.[<span class="hljs-keyword">path</span>] + <span class="hljs-string">'\'</span> + <span class="hljs-keyword">cast</span>(b.name <span class="hljs-keyword">as</span> <span class="hljs-built_in">varchar</span>(<span class="hljs-keyword">max</span>)) <span class="hljs-keyword">as</span> <span class="hljs-built_in">varchar</span>(<span class="hljs-keyword">max</span>)), b.uniqueid <span class="hljs-keyword">from</span> dbo.FOLDERS b
<span class="hljs-keyword">inner</span> <span class="hljs-keyword">join</span>
RunbookPath c <span class="hljs-keyword">on</span> b.ParentID = c.UniqueID
<span class="hljs-keyword">where</span> b.Disabled = <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> b.Deleted = <span class="hljs-number">0</span>
)


<span class="hljs-comment">/** 7A65BD17-9532-4D07-A6DA-E0F89FA0203E is the code for Link Objects, Remove the condition (AND Act.ObjectType &lt;&gt; '7A65BD17-9532-4D07-A6DA-E0F89FA0203E') if you want LINK objects too **/</span>

<span class="hljs-keyword">SELECT</span> F.Path,RB.Name <span class="hljs-keyword">AS</span> RunBook,ACT.Name <span class="hljs-keyword">AS</span> Activity, RB.LastModified <span class="hljs-keyword">AS</span> <span class="hljs-string">'Runbook Last Modified'</span>  
<span class="hljs-keyword">FROM</span> [Orchestrator].[dbo].[OBJECTS] <span class="hljs-keyword">AS</span> Act
<span class="hljs-keyword">INNER</span> <span class="hljs-keyword">JOIN</span> [Orchestrator].[dbo].[POLICIES] <span class="hljs-keyword">AS</span> RB <span class="hljs-keyword">ON</span> RB.UniqueID = Act.ParentID 
<span class="hljs-keyword">INNER</span> <span class="hljs-keyword">JOIN</span> RunbookPath <span class="hljs-keyword">AS</span> F <span class="hljs-keyword">ON</span> F.UniqueID = RB.ParentID
<span class="hljs-keyword">where</span> Act.Deleted = <span class="hljs-number">0</span> <span class="hljs-keyword">AND</span> rb.Deleted = <span class="hljs-number">0</span> <span class="hljs-keyword">AND</span> Act.ObjectType &lt;&gt; <span class="hljs-string">'7A65BD17-9532-4D07-A6DA-E0F89FA0203E'</span>
<span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span> F.Path, RB.Name , Act.Name
</code></pre>
<p><strong>Get SQL Query Passwords (Encrypted)</strong></p>
<p>This query will get the ‘Query Database’ activities along with the encrypted passwords that is used in the activity.</p>
<p>Note that the password is encrypted and has a specific 3-part (actually 4-part) format. I will leave that to you to analyze. You can use the queries coming-up later in this article to even de-crypt those passwords.</p>
<pre><code class="lang-sql"><span class="hljs-keyword">use</span> orchestrator;

<span class="hljs-keyword">with</span> RunbookPath <span class="hljs-keyword">as</span>
(
<span class="hljs-keyword">select</span> <span class="hljs-string">'Policies\'</span> + <span class="hljs-keyword">cast</span>(<span class="hljs-keyword">name</span> <span class="hljs-keyword">as</span> <span class="hljs-built_in">varchar</span>(<span class="hljs-keyword">max</span>)) <span class="hljs-keyword">as</span> [<span class="hljs-keyword">path</span>], uniqueid <span class="hljs-keyword">from</span> dbo.folders b
<span class="hljs-keyword">where</span> b.ParentID=<span class="hljs-string">'00000000-0000-0000-0000-000000000000'</span> <span class="hljs-keyword">and</span> disabled = <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> deleted= <span class="hljs-number">0</span>
<span class="hljs-keyword">union</span> <span class="hljs-keyword">all</span>
<span class="hljs-keyword">select</span> <span class="hljs-keyword">cast</span>(c.[<span class="hljs-keyword">path</span>] + <span class="hljs-string">'\'</span> + <span class="hljs-keyword">cast</span>(b.name <span class="hljs-keyword">as</span> <span class="hljs-built_in">varchar</span>(<span class="hljs-keyword">max</span>)) <span class="hljs-keyword">as</span> <span class="hljs-built_in">varchar</span>(<span class="hljs-keyword">max</span>)), b.uniqueid <span class="hljs-keyword">from</span> dbo.FOLDERS b
<span class="hljs-keyword">inner</span> <span class="hljs-keyword">join</span>
RunbookPath c <span class="hljs-keyword">on</span> b.ParentID = c.UniqueID
<span class="hljs-keyword">where</span> b.Disabled = <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> b.Deleted = <span class="hljs-number">0</span>
)

<span class="hljs-keyword">select</span> f.path,r.name,Act.Name <span class="hljs-keyword">as</span> Activity, s.password <span class="hljs-keyword">from</span> POLICIES <span class="hljs-keyword">as</span> r 
<span class="hljs-keyword">inner</span> <span class="hljs-keyword">join</span> RunbookPath <span class="hljs-keyword">as</span> f <span class="hljs-keyword">on</span> r.ParentID = f.UniqueID
<span class="hljs-keyword">INNER</span> <span class="hljs-keyword">JOIN</span> [Orchestrator].[dbo].[OBJECTS] <span class="hljs-keyword">AS</span> Act <span class="hljs-keyword">ON</span> Act.ParentID = r.UniqueID
<span class="hljs-keyword">INNER</span> <span class="hljs-keyword">JOIN</span> [Orchestrator].[dbo].[TASK_QUERYDATABASE] <span class="hljs-keyword">as</span> S <span class="hljs-keyword">on</span> s.UniqueID = Act.UniqueID
<span class="hljs-keyword">where</span> r.Deleted = <span class="hljs-number">0</span> <span class="hljs-keyword">AND</span> Act.Deleted = <span class="hljs-number">0</span>
<span class="hljs-comment">-- AND s.Password &lt;&gt; '\`d.T.~Ec/\`d.T.~De/\`d.T.~De/' /** Use this condition if you want filter-out the ones that use system password **/</span>
</code></pre>
<p><strong>Decrypt Single Orchestrator Encrypted Value</strong></p>
<p>In case you come around an encrypted variable or value that you want to decrypt and find out, here is the query for that.</p>
<pre><code class="lang-sql"><span class="hljs-keyword">use</span> orchestrator;

<span class="hljs-keyword">DECLARE</span> @EncryptedPass <span class="hljs-keyword">nvarchar</span>(<span class="hljs-number">255</span>);
<span class="hljs-comment">/** Set the value of @EncryptedPass as the encrypted value that you want to decrypt. Note that it is the Alphanumeric part of the Encrypted text. **/</span>
<span class="hljs-keyword">SET</span> @EncryptedPass = <span class="hljs-string">'00224EAFD0B0FC41DA40650F2F11F68801000000B60FCDF1618F1A37701C4B6D292DB444F1B1507B7EE82D5DAB8107CE1C54DD43E19DF7CC9AD6DDE6AFA0E4E834256955'</span>;

OPEN SYMMETRIC KEY ORCHESTRATOR_SYM_KEY DECRYPTION BY ASYMMETRIC KEY ORCHESTRATOR_ASYM_KEY;

<span class="hljs-keyword">with</span> EncryptedPass <span class="hljs-keyword">AS</span>
(
<span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">CONVERT</span>(VARBINARY(<span class="hljs-keyword">MAX</span>), @EncryptedPass , <span class="hljs-number">2</span>) <span class="hljs-keyword">as</span> TheHexPass
)

<span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">convert</span>(<span class="hljs-keyword">nvarchar</span>, decryptbykey(TheHexPass)) <span class="hljs-keyword">AS</span> <span class="hljs-keyword">Password</span> <span class="hljs-keyword">FROM</span> EncryptedPass;
</code></pre>
<p><strong>Decrypt All Stored SCO Variables</strong></p>
<p>It might happen that you or someone in your team has stored some variable under Orchestrator Variables as an encrypted variable. And for some reason you want to see the value stored in it now. Once it is encrypted, you cannot remove the check and see the original password. It just shows blank.</p>
<p>In such scenarios the following query might help you find out the decrypted values from the Orchestrator Variables.</p>
<pre><code class="lang-sql"><span class="hljs-keyword">use</span> orchestrator;

OPEN SYMMETRIC KEY ORCHESTRATOR_SYM_KEY DECRYPTION BY ASYMMETRIC KEY ORCHESTRATOR_ASYM_KEY;

<span class="hljs-keyword">WITH</span> TheVariables <span class="hljs-keyword">AS</span>
(
<span class="hljs-keyword">SELECT</span> Act.Name, 
        v.Value <span class="hljs-keyword">AS</span> Encrypted, 
        <span class="hljs-keyword">CASE</span> <span class="hljs-keyword">WHEN</span> v.Value <span class="hljs-keyword">like</span> <span class="hljs-string">'\`d.%'</span> <span class="hljs-keyword">THEN</span>
        <span class="hljs-keyword">convert</span>(<span class="hljs-keyword">nvarchar</span>, decryptbykey(<span class="hljs-keyword">CONVERT</span>(VARBINARY(<span class="hljs-keyword">MAX</span>), <span class="hljs-keyword">SUBSTRING</span>(v.Value, <span class="hljs-keyword">CHARINDEX</span>(<span class="hljs-string">'/'</span>,v.Value) + <span class="hljs-number">1</span>, <span class="hljs-keyword">LEN</span>(v.Value) - (<span class="hljs-number">2</span> * <span class="hljs-keyword">CHARINDEX</span>(<span class="hljs-string">'/'</span>,v.Value))) , <span class="hljs-number">2</span>))) 
        <span class="hljs-keyword">ELSE</span>
        v.Value
        <span class="hljs-keyword">END</span> <span class="hljs-keyword">AS</span> Decrypted, Act.UniqueID
        <span class="hljs-keyword">FROM</span> [Orchestrator].[dbo].[<span class="hljs-keyword">VARIABLES</span>] v
<span class="hljs-keyword">INNER</span> <span class="hljs-keyword">JOIN</span> [Orchestrator].[dbo].[OBJECTS] <span class="hljs-keyword">AS</span> Act <span class="hljs-keyword">ON</span> Act.UniqueID = v.UniqueID
<span class="hljs-keyword">where</span> Act.Deleted = <span class="hljs-number">0</span>
),
 RunbookPath <span class="hljs-keyword">as</span>
(
<span class="hljs-keyword">select</span> <span class="hljs-string">'Variables\'</span> + <span class="hljs-keyword">cast</span>(<span class="hljs-keyword">name</span> <span class="hljs-keyword">as</span> <span class="hljs-built_in">varchar</span>(<span class="hljs-keyword">max</span>)) <span class="hljs-keyword">as</span> [<span class="hljs-keyword">path</span>], uniqueid <span class="hljs-keyword">from</span> dbo.folders b
<span class="hljs-keyword">where</span> b.ParentID=<span class="hljs-string">'00000000-0000-0000-0000-000000000005'</span> <span class="hljs-keyword">and</span> disabled = <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> deleted= <span class="hljs-number">0</span>
<span class="hljs-keyword">union</span> <span class="hljs-keyword">all</span>
<span class="hljs-keyword">select</span> <span class="hljs-keyword">cast</span>(c.[<span class="hljs-keyword">path</span>] + <span class="hljs-string">'\'</span> + <span class="hljs-keyword">cast</span>(b.name <span class="hljs-keyword">as</span> <span class="hljs-built_in">varchar</span>(<span class="hljs-keyword">max</span>)) <span class="hljs-keyword">as</span> <span class="hljs-built_in">varchar</span>(<span class="hljs-keyword">max</span>)), b.uniqueid <span class="hljs-keyword">from</span> dbo.FOLDERS b
<span class="hljs-keyword">inner</span> <span class="hljs-keyword">join</span>
RunbookPath c <span class="hljs-keyword">on</span> b.ParentID = c.UniqueID
<span class="hljs-keyword">where</span> b.Disabled = <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> b.Deleted = <span class="hljs-number">0</span>
)

<span class="hljs-keyword">SELECT</span> F.Path, V.Name <span class="hljs-keyword">as</span> VariableName, V.Encrypted, V.Decrypted  
<span class="hljs-keyword">FROM</span> [Orchestrator].[dbo].[OBJECTS] <span class="hljs-keyword">AS</span> Act
<span class="hljs-keyword">INNER</span> <span class="hljs-keyword">JOIN</span> RunbookPath <span class="hljs-keyword">AS</span> F <span class="hljs-keyword">ON</span> F.UniqueID = Act.ParentID
<span class="hljs-keyword">INNER</span> <span class="hljs-keyword">JOIN</span> TheVariables <span class="hljs-keyword">AS</span> V <span class="hljs-keyword">ON</span> Act.UniqueID = V.UniqueID
<span class="hljs-keyword">where</span> Act.Deleted = <span class="hljs-number">0</span>
<span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span> F.Path, V.Name
</code></pre>
]]></content:encoded></item><item><title><![CDATA[LINUX: Shell Scripting Exercises]]></title><description><![CDATA[Note : These exercises are from “Linux Training Academy’s” Shell Scripting course.

Exercise 1: Write a shell script that prints “Hello World!” to the screen.
Hint 1: Remember to make the shell script executable with the chmod command.Hint 2: Remembe...]]></description><link>https://tech.anupamm.com/linux-shell-scripting-exercises</link><guid isPermaLink="true">https://tech.anupamm.com/linux-shell-scripting-exercises</guid><category><![CDATA[Linux]]></category><category><![CDATA[shell]]></category><category><![CDATA[Scripting]]></category><category><![CDATA[practice]]></category><category><![CDATA[Exercise]]></category><dc:creator><![CDATA[Anupam Majhi]]></dc:creator><pubDate>Thu, 22 Mar 2018 20:46:36 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1693328197578/65da373c-67dc-4fd4-a922-50849d12bd46.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p><em>Note : These exercises are from “Linux Training Academy’s” Shell Scripting course.</em></p>
</blockquote>
<p><strong>Exercise 1:</strong> Write a shell script that prints “Hello World!” to the screen.</p>
<p>Hint 1: Remember to make the shell script executable with the chmod command.<br />Hint 2: Remember to start your script with a shebang!</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"Hello World!"</span>
</code></pre>
<p><strong>Exercise 2:</strong> Modify the shell script from exercise 1 to include a variable. The variable will hold the contents of the message “Hello World!”.</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>
THE_MESSAGE=<span class="hljs-string">"Hello World!"</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$THE_MESSAGE</span>"</span>
</code></pre>
<p><strong>Exercise 3</strong>: Store the output of the command “hostname” in a variable. Display “This script is running on <em>.” where “</em> “ is the output of the “hostname” command.</p>
<p>Hint: It’s a best practice to use the ${VARIABLE} syntax if there is text or characters that directly precede or follow the variable.</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>
THE_HOSTNAME=$(hostname)
<span class="hljs-built_in">echo</span> <span class="hljs-string">"The script is running on <span class="hljs-variable">$THE_HOSTNAME</span>"</span>
</code></pre>
<p><strong>Exercise 4</strong>: Write a shell script to check to see if the file “/etc/shadow” exists. If it does exist, display “Shadow passwords are enabled.” Next, check to see if ou can write to the file. If you can, display “You have permissions to edit /etc/shadow.” If you cannot, display “You do NOT have permissions to edit /etc/shadow.”</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

THE_PATH=<span class="hljs-string">"/etc/shadow"</span>

<span class="hljs-keyword">if</span> [ -e <span class="hljs-variable">$THE_PATH</span> ]
<span class="hljs-keyword">then</span>
     <span class="hljs-built_in">echo</span> <span class="hljs-string">"Shadow Passwords are enabled"</span>

     <span class="hljs-keyword">if</span> [ -w <span class="hljs-variable">$THE_PATH</span> ]
     <span class="hljs-keyword">then</span>
          <span class="hljs-built_in">echo</span> <span class="hljs-string">"You have permission to edit <span class="hljs-variable">$THE_PATH</span>"</span>
     <span class="hljs-keyword">else</span>
          <span class="hljs-built_in">echo</span> <span class="hljs-string">"Tou do NOT have permission to edit <span class="hljs-variable">$THE_PATH</span>"</span>
     <span class="hljs-keyword">fi</span>
<span class="hljs-keyword">else</span>
     <span class="hljs-built_in">echo</span> <span class="hljs-string">"Shadow Passowrds not enabled"</span>
<span class="hljs-keyword">fi</span>
</code></pre>
<p><strong>Exercise 5</strong>: Write a shell script that displays “man”, “bear”, “pig”, “dog”, “cat”, and sheep to the screen with each appearing on a separate line. Try to do this in as few lines as possible. Hint: Loops can be used to perform repetitive tasks.</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

ANIMALS=<span class="hljs-string">"man bear pig dog cat sheep"</span>

<span class="hljs-keyword">for</span> ANIMAL <span class="hljs-keyword">in</span> <span class="hljs-variable">$ANIMALS</span>
<span class="hljs-keyword">do</span>
        <span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$ANIMAL</span>"</span>
<span class="hljs-keyword">done</span>
</code></pre>
<p><strong>Exercise 6</strong>: Write a shell script that prompts the user for a name of a file or directory and reports if it is a regular file, a directory, or other type of file. Also perform an ls command against the file or directory with the long listing option.</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

<span class="hljs-built_in">read</span> -p <span class="hljs-string">"Enter a path for file/folder : "</span> THE_PATH

<span class="hljs-keyword">if</span> [ -d <span class="hljs-variable">$THE_PATH</span> ]
<span class="hljs-keyword">then</span>
        <span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$THE_PATH</span> is a directory"</span>
<span class="hljs-keyword">elif</span> [ -f <span class="hljs-variable">$THE_PATH</span> ]
<span class="hljs-keyword">then</span>
        <span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$THE_PATH</span> is a simple file"</span>
<span class="hljs-keyword">elif</span> [ -e <span class="hljs-variable">$THE_PATH</span> ]
<span class="hljs-keyword">then</span>
        <span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$THE_PATH</span> is not a simple file"</span>
<span class="hljs-keyword">else</span>
        <span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$THE_PATH</span> does NOT exist!!"</span>
<span class="hljs-keyword">fi</span>

<span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-subst">$(ls -l $THE_PATH)</span>"</span>
</code></pre>
<p><strong>Exercise 7</strong>: Modify the previous script so that it accepts the file or directory name as an argument instead of prompting the user to enter it.</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

THE_PATH=<span class="hljs-variable">$1</span>

<span class="hljs-keyword">if</span> [ -d <span class="hljs-variable">$THE_PATH</span> ]
<span class="hljs-keyword">then</span>
        <span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$THE_PATH</span> is a directory"</span>
<span class="hljs-keyword">elif</span> [ -f <span class="hljs-variable">$THE_PATH</span> ]
<span class="hljs-keyword">then</span>
        <span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$THE_PATH</span> is a simple file"</span>
<span class="hljs-keyword">elif</span> [ -e <span class="hljs-variable">$THE_PATH</span> ]
<span class="hljs-keyword">then</span>
        <span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$THE_PATH</span> is not a simple file"</span>
<span class="hljs-keyword">else</span>
        <span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$THE_PATH</span> does NOT exist!!"</span>
<span class="hljs-keyword">fi</span>

<span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-subst">$(ls -l $THE_PATH)</span>"</span>
</code></pre>
<p><strong>Exercise 8</strong>: Modify the previous script to accept an unlimited number of files and directories as arguments. Hint: You’ll want to use a special variable.</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

<span class="hljs-keyword">for</span> THE_PATH <span class="hljs-keyword">in</span> <span class="hljs-variable">$@</span>
<span class="hljs-keyword">do</span>
<span class="hljs-keyword">if</span> [ -d <span class="hljs-variable">$THE_PATH</span> ]
<span class="hljs-keyword">then</span>
        <span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$THE_PATH</span> is a directory"</span>
<span class="hljs-keyword">elif</span> [ -f <span class="hljs-variable">$THE_PATH</span> ]
<span class="hljs-keyword">then</span>
        <span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$THE_PATH</span> is a simple file"</span>
<span class="hljs-keyword">elif</span> [ -e <span class="hljs-variable">$THE_PATH</span> ]
<span class="hljs-keyword">then</span>
        <span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$THE_PATH</span> is not a simple file"</span>
<span class="hljs-keyword">else</span>
        <span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$THE_PATH</span> does NOT exist!!"</span>
<span class="hljs-keyword">fi</span>

<span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-subst">$(ls -l $THE_PATH)</span>"</span>

<span class="hljs-keyword">done</span>
</code></pre>
]]></content:encoded></item><item><title><![CDATA[HIVE: Basic Architecture and Components]]></title><description><![CDATA[Hive Architecture

The Hive Architecture comprises 3 main components:

Hive Client  This is where the applications get an interface to interact with hive.

Hive Services  Hive services enable the hive interactions by passing them through the hive dri...]]></description><link>https://tech.anupamm.com/hive-basic-architecture-and-components</link><guid isPermaLink="true">https://tech.anupamm.com/hive-basic-architecture-and-components</guid><category><![CDATA[hive]]></category><category><![CDATA[basics]]></category><category><![CDATA[architecture]]></category><category><![CDATA[components]]></category><category><![CDATA[big data]]></category><dc:creator><![CDATA[Anupam Majhi]]></dc:creator><pubDate>Wed, 19 Jul 2017 18:55:44 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1693088551585/7313a92a-58b8-435a-9edd-43f4c179b07a.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-hive-architecture">Hive Architecture</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1693088549570/6a60d389-644e-4ef2-9c78-bfcc1d42a98b.jpeg" alt class="image--center mx-auto" /></p>
<p>The Hive Architecture comprises 3 main components:</p>
<ol>
<li><p><strong>Hive Client</strong><br />  This is where the applications get an interface to interact with hive.</p>
</li>
<li><p><strong>Hive Services</strong><br />  Hive services enable the hive interactions by passing them through the hive driver which in turn uses MapReduce.</p>
</li>
<li><p><strong>Compute and Storage</strong><br />  This is the workhorse of the Hive ecosystem which includes the Metastore DB and HDFS storage.</p>
</li>
</ol>
<h3 id="heading-about-the-components">About the Components</h3>
<p><strong>Hive Client</strong></p>
<p>Hive client is the interface for different applications and clients which makes it possible for different applications to communicate with Hive.</p>
<p>Hive client comprises Thrift Client, JDBC Client and ODBC Client.</p>
<p>Thrift Client enables Thrift based applications to communicate with Hive. JDBC and ODBC enable several applications and languages to make connections and process with hive.</p>
<p>These clients in turn connect to the Hive Server to make this possible.</p>
<p><strong>Hive Services</strong></p>
<p>Client interactions are made possible by Hive services.</p>
<p>CLI service enables us to interact with Hive via command line.</p>
<p>Web based service makes it possible to have a web based interaction with Hive.</p>
<p>The Hive server service is one of the most important and most used service which most of the Client services connect to.</p>
<p><strong>Hive Storage and Compute</strong></p>
<p>Hive storage used MapReduce in the background which makes it possible for hive to process Big Data.</p>
<p>Hive stores meta information in the Hive Metastore which is the backbone of Hive.</p>
<p>By default, Hive uses Derby DB for storing metadata, but any other RDBMS can be used for this purpose.</p>
<p>However, the data resides on either Local storage or HDFS.</p>
]]></content:encoded></item><item><title><![CDATA[R: Introduction to R]]></title><description><![CDATA[R is one of the most popular languages used for Statistical Computing today. It is widely used for Data Analysis and Visualization by statisticians and data miners. Its application includes a range of purposes from data preprocessing, cleaning, web s...]]></description><link>https://tech.anupamm.com/introduction-to-r</link><guid isPermaLink="true">https://tech.anupamm.com/introduction-to-r</guid><category><![CDATA[R Language]]></category><category><![CDATA[introduction]]></category><category><![CDATA[Machine Learning]]></category><category><![CDATA[Data Science]]></category><category><![CDATA[statistics]]></category><dc:creator><![CDATA[Anupam Majhi]]></dc:creator><pubDate>Mon, 03 Jul 2017 20:30:09 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1693088546106/c487d3b3-dc16-4bc9-a321-0acb440cb763.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>R is one of the most popular languages used for Statistical Computing today. It is widely used for Data Analysis and Visualization by statisticians and data miners. Its application includes a range of purposes from data preprocessing, cleaning, web scraping, and visualization to a wide range of analytical tasks such as computational statistics, econometrics, optimization, and natural language processing.</p>
<p>R is in itself a command-line-based scripting language and is a dynamic language (compiled at runtime). Though you can use any text editor to write R scripts, it is way more convenient and useful to use R Studio. In fact, you will almost always use R with R Studio.</p>
<p>R is an open-source. popular and user-friendly (even if you have never done any computer programming) language is used by organizations like Google, Facebook, US DoD, Twitter, TechCrunch, Microsoft, etc.</p>
<p>But, why use R?</p>
<h3 id="heading-programming-and-statistical-features">Programming and Statistical Features</h3>
<p>R is an open-source software created over 20 years ago by Ross Ihaka and Robert Gentleman at the University of Auckland, New Zealand. However, its history is even longer as has derived its features from the S programming language created by John Chambers out of Bell Labs back in the 1970s. S was widely accepted in the world of statisticians. R is actually a combination of S with lexical scoping semantics inspired by Scheme.</p>
<p>R and its libraries implement a wide variety of statistical and graphical techniques, including linear and nonlinear modeling, classical statistical tests, time-series analysis, classification, clustering, and others.</p>
<h3 id="heading-interfaces">Interfaces</h3>
<p>R Studio is the most used interface for R scripting which gives you great flexibility and visual representation of the data you are working with. There are other interfaces available too, including R Tools for Visual Studio by Microsoft and also Rattle GUI, and R Commander. You can even access R functionality from within other programming languages like Python, Ruby, Java, etc.</p>
<h3 id="heading-flexibility-and-community">Flexibility and Community</h3>
<p>The functionalities and features of R can be extended with the usage of packages that are very easily available online, developed, and maintained by the community. These packages allow specialized statistical techniques, data handling, data cleaning, graphical devices, import/export capabilities, reporting tools, etc.</p>
<p>These packages are developed by people from different walks of life and knowledge, which include researchers, analysts, scientists, statisticians, and more. The R community is fantastically diverse and engaged. On a daily basis, the R community generates opportunities and resources for learning about R. These cover the full spectrum of training — books, online courses, R user groups, workshops, conferences, etc. And with over 2 million users and developers, finding help and technical expertise is only a simple click away. Support is available through <a target="_blank" href="https://www.r-project.org/mail.html">R mailing lists</a>, Q&amp;A websites, social media networks, and <a target="_blank" href="http://www.r-bloggers.com/">numerous blogs</a>.</p>
]]></content:encoded></item><item><title><![CDATA[LINUX: Command Line Cheat Sheet]]></title><description><![CDATA[There are literally thousands of commands in Linux and I am not even talking about the custom ones developed by the community for some awesome stuff. I accept that it is impossible (at least for me) to remember all of them. Today I came across this a...]]></description><link>https://tech.anupamm.com/linux-command-line-cheat-sheet</link><guid isPermaLink="true">https://tech.anupamm.com/linux-command-line-cheat-sheet</guid><category><![CDATA[Linux]]></category><category><![CDATA[cheatsheet]]></category><category><![CDATA[command line]]></category><category><![CDATA[Bash]]></category><category><![CDATA[Script]]></category><dc:creator><![CDATA[Anupam Majhi]]></dc:creator><pubDate>Thu, 22 Jun 2017 14:16:23 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1693088542500/3aa8bca5-4fe1-4095-9f33-92b44171676e.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>There are literally thousands of commands in Linux and I am not even talking about the custom ones developed by the community for some awesome stuff. I accept that it is impossible (at least for me) to remember all of them. Today I came across this awesome “Linux Cheat Sheet” with all the important command-line Linux commands.</p>
<p>But the question is, do we really need so many commands when we are talking to Tux the Penguin? The answer is of course No.</p>
<p>So which are the commands that I really need to know about to become a Linux Ninja? Today I came across this awesome “Linux Cheat Sheet” with all the important command-line Linux commands (<a target="_blank" href="https://www.LinuxTrainingAcademy.com">courtesy: Linux Training Academy</a>).</p>
<p><a target="_blank" href="https://github.com/anupammajhi/projectList/raw/main/CheatSheets/linuxcommandlinecheatsheet.pdf"><strong>Download</strong></a></p>
]]></content:encoded></item><item><title><![CDATA[JS: Decimal and Hexadecimal]]></title><description><![CDATA[This is pretty interesting how you can convert not just standard decimal or hexadecimal numbers but any number with a base between 2 and 32. Here’s how:
var myDecimalNum = 10; 
myDecimalNum.toString(16); 

// result : a

var myHexNum = "a"; 
parseInt...]]></description><link>https://tech.anupamm.com/js-decimal-and-hexadecimal</link><guid isPermaLink="true">https://tech.anupamm.com/js-decimal-and-hexadecimal</guid><category><![CDATA[js]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[hexadecimal]]></category><category><![CDATA[decimal]]></category><category><![CDATA[conversion]]></category><dc:creator><![CDATA[Anupam Majhi]]></dc:creator><pubDate>Fri, 22 Jul 2016 16:47:33 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1693088539139/8c5e18fc-d9de-406d-9564-e5896f587bb6.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This is pretty interesting how you can convert not just standard decimal or hexadecimal numbers but any number with a base between 2 and 32. Here’s how:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> myDecimalNum = <span class="hljs-number">10</span>; 
myDecimalNum.toString(<span class="hljs-number">16</span>); 

<span class="hljs-comment">// result : a</span>
</code></pre>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> myHexNum = <span class="hljs-string">"a"</span>; 
<span class="hljs-built_in">parseInt</span>(myHexNum,<span class="hljs-number">16</span>); 

<span class="hljs-comment">// result : 10</span>
</code></pre>
<p>And not just base 16 (hex), you can do it for any base. Try different bases and have fun.</p>
]]></content:encoded></item><item><title><![CDATA[R: Useful Built-in Functions]]></title><description><![CDATA[General
builtins() # List all built-in functions
options()  # Set options to control how R computes & displays results

?NA        # Help page on handling of missing data values
abs(x)     # The absolute value of "x"
append()   # Add elements to a ve...]]></description><link>https://tech.anupamm.com/r-useful-built-in-functions</link><guid isPermaLink="true">https://tech.anupamm.com/r-useful-built-in-functions</guid><category><![CDATA[R Language]]></category><category><![CDATA[built in functions]]></category><category><![CDATA[Methods]]></category><category><![CDATA[Data Science]]></category><category><![CDATA[Script]]></category><dc:creator><![CDATA[Anupam Majhi]]></dc:creator><pubDate>Fri, 10 Jun 2016 05:43:33 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1693328257146/7c228d41-bad8-4b21-b50a-e79e7ceb60bd.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-general"><strong>General</strong></h1>
<pre><code class="lang-r">builtins() <span class="hljs-comment"># List all built-in functions</span>
options()  <span class="hljs-comment"># Set options to control how R computes &amp; displays results</span>

?<span class="hljs-literal">NA</span>        <span class="hljs-comment"># Help page on handling of missing data values</span>
abs(x)     <span class="hljs-comment"># The absolute value of "x"</span>
append()   <span class="hljs-comment"># Add elements to a vector</span>
c(x)       <span class="hljs-comment"># A generic function which combines its arguments</span>
cat(x)     <span class="hljs-comment"># Prints the arguments</span>
cbind()    <span class="hljs-comment"># Combine vectors by row/column (cf. "paste" in Unix)</span>
diff(x)    <span class="hljs-comment"># Returns suitably lagged and iterated differences</span>
gl()       <span class="hljs-comment"># Generate factors with the pattern of their levels</span>
grep()     <span class="hljs-comment"># Pattern matching</span>
identical()  <span class="hljs-comment"># Test if 2 objects are *exactly* equal</span>
jitter()     <span class="hljs-comment"># Add a small amount of noise to a numeric vector</span>
julian()     <span class="hljs-comment"># Return Julian date</span>
length(x)    <span class="hljs-comment"># Return no. of elements in vector x</span>
ls()         <span class="hljs-comment"># List objects in current environment</span>
mat.or.vec() <span class="hljs-comment"># Create a matrix or vector</span>
paste(x)     <span class="hljs-comment"># Concatenate vectors after converting to character</span>
range(x)     <span class="hljs-comment"># Returns the minimum and maximum of x</span>
rep(<span class="hljs-number">1</span>,<span class="hljs-number">5</span>)     <span class="hljs-comment"># Repeat the number 1 five times</span>
rev(x)       <span class="hljs-comment"># List the elements of "x" in reverse order</span>
seq(<span class="hljs-number">1</span>,<span class="hljs-number">10</span>,<span class="hljs-number">0.4</span>)  <span class="hljs-comment"># Generate a sequence (1 -&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; 10, spaced by 0.4)</span>
sequence()     <span class="hljs-comment"># Create a vector of sequences</span>
sign(x)        <span class="hljs-comment"># Returns the signs of the elements of x</span>
sort(x)        <span class="hljs-comment"># Sort the vector x</span>
order(x)       <span class="hljs-comment"># list sorted element numbers of x</span>
tolower(),toupper()  <span class="hljs-comment"># Convert string to lower/upper case letters</span>
unique(x)      <span class="hljs-comment"># Remove duplicate entries from vector</span>
system(<span class="hljs-string">"cmd"</span>)  <span class="hljs-comment"># Execute "cmd" in operating system (outside of R)</span>
vector()       <span class="hljs-comment"># Produces a vector of given length and mode</span>

formatC(x)     <span class="hljs-comment"># Format x using 'C' style formatting specifications</span>
floor(x), ceiling(x), round(x), signif(x), trunc(x)   <span class="hljs-comment"># rounding functions</span>

Sys.getenv(x)  <span class="hljs-comment"># Get the value of the environment variable "x"</span>
Sys.putenv(x)  <span class="hljs-comment"># Set the value of the environment variable "x"</span>
Sys.time()     <span class="hljs-comment"># Return system time</span>
Sys.Date()     <span class="hljs-comment"># Return system date</span>
getwd()        <span class="hljs-comment"># Return working directory</span>
setwd()        <span class="hljs-comment"># Set working directory</span>
?files         <span class="hljs-comment"># Help on low-level interface to file system</span>
list.files()   <span class="hljs-comment"># List files in a give directory</span>
file.info()    <span class="hljs-comment"># Get information about files</span>

<span class="hljs-comment"># Built-in constants:</span>
pi,letters,LETTERS   <span class="hljs-comment"># Pi, lower &amp; uppercase letters, e.g. letters[7] = "g"</span>
month.abb,month.name <span class="hljs-comment"># Abbreviated &amp; full names for months</span>
</code></pre>
<h1 id="heading-maths"><strong>Maths</strong></h1>
<pre><code class="lang-r">log(x),logb(),log10(),log2(),exp(),expm1(),log1p(),sqrt() <span class="hljs-comment"># Fairly obvious </span>
cos(),sin(),tan(),acos(),asin(),atan(),atan2() <span class="hljs-comment"># Usual stuff </span>
cosh(),sinh(),tanh(),acosh(),asinh(),atanh() <span class="hljs-comment"># Hyperbolic functions </span>
union(),intersect(),setdiff(),setequal() <span class="hljs-comment"># Set operations </span>
+,-,*,/,^,%%,%/% <span class="hljs-comment"># Arithmetic operators </span>
&lt;,&gt;,=,==,!= <span class="hljs-comment"># Comparison operators </span>
eigen() <span class="hljs-comment"># Computes eigenvalues and eigenvectors </span>
deriv() <span class="hljs-comment"># Symbolic and algorithmic derivatives of simple expressions </span>
integrate() <span class="hljs-comment"># Adaptive quadrature over a finite or infinite interval. </span>
sqrt(),sum() 

?Control <span class="hljs-comment"># Help on control flow statements (e.g. if, for, while) </span>
?Extract <span class="hljs-comment"># Help on operators acting to extract or replace subsets of vectors </span>
?Logic <span class="hljs-comment"># Help on logical operators </span>
?Mod <span class="hljs-comment"># Help on functions which support complex arithmetic in R </span>
?Paren <span class="hljs-comment"># Help on parentheses </span>
?regex <span class="hljs-comment"># Help on regular expressions used in R </span>
?Syntax <span class="hljs-comment"># Help on R syntax and giving the precedence of operators </span>
?Special <span class="hljs-comment"># Help on special functions related to beta and gamma functions</span>
</code></pre>
<h1 id="heading-graphical"><strong>Graphical</strong></h1>
<pre><code class="lang-r">log(x),logb(),log10(),log2(),exp(),expm1(),log1p(),sqrt() <span class="hljs-comment"># Fairly obvious </span>
cos(),sin(),tan(),acos(),asin(),atan(),atan2() <span class="hljs-comment"># Usual stuff </span>
cosh(),sinh(),tanh(),acosh(),asinh(),atanh() <span class="hljs-comment"># Hyperbolic functions </span>
union(),intersect(),setdiff(),setequal() <span class="hljs-comment"># Set operations </span>
+,-,*,/,^,%%,%/% <span class="hljs-comment"># Arithmetic operators </span>
&lt;,&gt;,=,==,!= <span class="hljs-comment"># Comparison operators </span>
eigen() <span class="hljs-comment"># Computes eigenvalues and eigenvectors </span>
deriv() <span class="hljs-comment"># Symbolic and algorithmic derivatives of simple expressions </span>
integrate() <span class="hljs-comment"># Adaptive quadrature over a finite or infinite interval. </span>
sqrt(),sum() 

?Control <span class="hljs-comment"># Help on control flow statements (e.g. if, for, while) </span>
?Extract <span class="hljs-comment"># Help on operators acting to extract or replace subsets of vectors </span>
?Logic <span class="hljs-comment"># Help on logical operators </span>
?Mod <span class="hljs-comment"># Help on functions which support complex arithmetic in R </span>
?Paren <span class="hljs-comment"># Help on parentheses </span>
?regex <span class="hljs-comment"># Help on regular expressions used in R </span>
?Syntax <span class="hljs-comment"># Help on R syntax and giving the precedence of operators </span>
?Special <span class="hljs-comment"># Help on special functions related to beta and gamma functions</span>
</code></pre>
<h1 id="heading-fitting-regression-optimisation"><strong>Fitting / regression / optimisation</strong></h1>
<pre><code class="lang-r">lm <span class="hljs-comment"># Fit liner model </span>
glm <span class="hljs-comment"># Fit generalised linear model </span>
nls <span class="hljs-comment"># non-linear (weighted) least-squares fitting </span>
lqs <span class="hljs-comment"># "library(MASS)" resistant regression </span>
optim <span class="hljs-comment"># general-purpose optimisation </span>
optimize <span class="hljs-comment"># 1-dimensional optimisation </span>
constrOptim <span class="hljs-comment"># Constrained optimisation </span>
nlm <span class="hljs-comment"># Non-linear minimisation </span>
nlminb <span class="hljs-comment"># More robust (non-)constrained non-linear minimisationR</span>
</code></pre>
<h1 id="heading-statistical"><strong>Statistical</strong></h1>
<pre><code class="lang-r">help(package=stats) <span class="hljs-comment"># List all stats functions </span>
?Chisquare <span class="hljs-comment"># Help on chi-squared distribution functions </span>
?Poisson <span class="hljs-comment"># Help on Poisson distribution functions </span>
help(package=survival) <span class="hljs-comment"># Survival analysis </span>
cor.test() <span class="hljs-comment"># Perform correlation test </span>
cumsum(); cumprod(); cummin(); cummax() <span class="hljs-comment"># Cumuluative functions for vectors </span>
density(x) <span class="hljs-comment"># Compute kernel density estimates </span>
ks.test() <span class="hljs-comment"># Performs one or two sample Kolmogorov-Smirnov tests </span>
loess(), lowess() <span class="hljs-comment"># Scatter plot smoothing </span>
mad() <span class="hljs-comment"># Calculate median absolute deviation </span>
mean(x), weighted.mean(x), median(x), min(x), max(x), quantile(x) 
rnorm(), runif() <span class="hljs-comment"># Generate random data with Gaussian/uniform distribution </span>
splinefun() <span class="hljs-comment"># Perform spline interpolation </span>
smooth.spline() <span class="hljs-comment"># Fits a cubic smoothing spline </span>
sd() <span class="hljs-comment"># Calculate standard deviation </span>
summary(x) <span class="hljs-comment"># Returns a summary of x: mean, min, max etc. </span>
t.test() <span class="hljs-comment"># Student's t-test </span>
var() <span class="hljs-comment"># Calculate variance </span>
sample() <span class="hljs-comment"># Random samples &amp; permutations </span>
ecdf() <span class="hljs-comment"># Empirical Cumulative Distribution Function </span>
qqplot() <span class="hljs-comment"># quantile-quantile plot</span>
</code></pre>
<h1 id="heading-other-useful-links"><strong>Other Useful Links :</strong></h1>
<p><a target="_blank" href="HTTP://WWW.SR.BHAM.AC.UK/~AJRS/R/R-FUNCTION_LIST.HTML">HTTP://WWW.SR.BHAM.AC.UK/~AJRS/R/R-FUNCTION_LIST.HTML</a></p>
<p><a target="_blank" href="http://www.columbia.edu/~cjd11/charles_dimaggio/DIRE/resources/R/rFunctionsList.pdf">http://www.columbia.edu/~cjd11/charles_dimaggio/DIRE/resources/R/rFunctionsList.pdf</a> <a target="_blank" href="https://www.statmethods.net/management/functions.html">https://www.statmethods.net/management/functions.html</a></p>
]]></content:encoded></item><item><title><![CDATA[LINUX: chmod & chown — The File & Folder Access Control]]></title><description><![CDATA[chmod and chown are among those popular Linux commands.
chmod: To modify access to files and folders by providing read/write/execute permissions.chown: To change the ownership of a file or folder.
chmod
There are two ways in which the permissions can...]]></description><link>https://tech.anupamm.com/linux-chmod-chown-the-file-folder-access-control</link><guid isPermaLink="true">https://tech.anupamm.com/linux-chmod-chown-the-file-folder-access-control</guid><category><![CDATA[chmod]]></category><category><![CDATA[chown]]></category><category><![CDATA[Linux]]></category><category><![CDATA[permissions]]></category><category><![CDATA[command line]]></category><dc:creator><![CDATA[Anupam Majhi]]></dc:creator><pubDate>Tue, 17 May 2016 14:26:56 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1693327788366/41e12043-8be4-409c-9ca2-22f5cc5a60f6.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>chmod and chown are among those popular Linux commands.</p>
<p>chmod: To modify access to files and folders by providing read/write/execute permissions.<br />chown: To change the ownership of a file or folder.</p>
<h1 id="heading-chmod"><strong>chmod</strong></h1>
<p>There are two ways in which the permissions can be changed/set.</p>
<p>The symbolic method is the one where we mention:</p>
<p>Example :<br />To remove read and write permission from the group and other of file “myfile.txt”</p>
<pre><code class="lang-bash">chmod og-rw myfile.txt
</code></pre>
<p>To add execute permission to group of the file “myfile2.txt”</p>
<pre><code class="lang-bash">chmod g+x myfile2.txt
</code></pre>
<p>The numeric method (my personal favorite) adds up the numbers to determine what kind of permission a file should have:</p>
<p>Now here’s the magic:</p>
<p>1 = execute (1)<br />2 = write (2)<br />3 = write (2) + execute (1)<br />4 = read (4)<br />5 = read (4) + execute (1)<br />6 = read (4) + write (2)<br />7 = read (4) + write (2) + execute (1)</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1693327763371/0a210921-6a5e-4d4a-8cde-363cddc5d429.png" alt class="image--center mx-auto" /></p>
<p>And the only extra thing to remember is the sequence of permission, it’s always<br />User -&gt; Group -&gt; Others</p>
<p>Example:<br />To set the permission for a file “myfile2.txt” such as:<br />a. User has full (read, write, and execute) permission …<em>(read+write+execute = 4+2+1 = 7)</em><br />b. Group has read and write permission …<em>(read+write = 4+2 = 6)</em><br />c. Others have only read permission …<em>(read = 4)</em></p>
<pre><code class="lang-bash">chmod 764 myfile2.txt
</code></pre>
<p><em>Note: 777 is a very dangerous way to give permission, this gives everyone in the world full control over file.</em></p>
<h1 id="heading-chown"><strong>chown</strong></h1>
<p>chown is pretty straightforward. Just remember that the syntax used for ownership is <strong>owner:group</strong></p>
<p>Here are a few examples:</p>
<p>To make a user named bob the owner of a folder called MyDirectory:</p>
<pre><code class="lang-bash">chown bob MyFolder
</code></pre>
<p>To make a group name myGroup the owner of MyDirectory folder (notice the colon before group name, remember the owner:group pattern):</p>
<pre><code class="lang-bash">chown :myGroup MyDirectory
</code></pre>
<p>To make a user named john and a group named group2 the owner of folder MyDirectory:</p>
<pre><code class="lang-bash">chown john:group2 MyDirectory
</code></pre>
]]></content:encoded></item><item><title><![CDATA[LINUX: useradd & usermod : The Linux User Administration]]></title><description><![CDATA[Adding user to a Linux environment is pretty easy!Just type useradd followed by username. Example:
useradd anupam

But!! the user cannot login yet, because the password needs to be set.The password must follow the suggested password rule. To set pass...]]></description><link>https://tech.anupamm.com/linux-useradd-usermod-the-linux-user-administration</link><guid isPermaLink="true">https://tech.anupamm.com/linux-useradd-usermod-the-linux-user-administration</guid><category><![CDATA[Linux]]></category><category><![CDATA[user management]]></category><category><![CDATA[command line]]></category><category><![CDATA[access control]]></category><category><![CDATA[Ubuntu]]></category><dc:creator><![CDATA[Anupam Majhi]]></dc:creator><pubDate>Mon, 16 May 2016 17:19:30 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1693327590398/344eaff8-980f-45f8-914f-98006df50325.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Adding user to a Linux environment is pretty easy!<br />Just type <strong>useradd</strong> followed by username. Example:</p>
<pre><code class="lang-bash">useradd anupam
</code></pre>
<p>But!! the user cannot login yet, because the password needs to be set.<br />The password must follow the suggested password rule. To set password, just type <strong>passwd</strong> followed by username and enter the new password ( <em>needs to be executed as root or SU privileges</em>). If you are not a SU then you can only change your password with this command.</p>
<p>You can find the password rules, aging rules etc in the file:</p>
<pre><code class="lang-bash">/etc/login.defs
</code></pre>
<p>To modify existing user use the command <strong>usermod</strong>. It has a lot of options like modifying primary group, supplementary group, lock and unlock user account, move or update user home directory etc. Example, to lock user account:</p>
<pre><code class="lang-bash">usermod -L anupam
</code></pre>
<p>And finally to delete a user, use the command <strong>userdel</strong></p>
<p>Pretty interesting eh!</p>
]]></content:encoded></item><item><title><![CDATA[LINUX: man, info & pinfo : The Linux Documentations]]></title><description><![CDATA[In Linux, to get help or to read the documentation on a particular command we can use either of the three ways: man, info or pinfo .
The help command man is more popular and gives concise documentation of how to use a command, whereas the info or pin...]]></description><link>https://tech.anupamm.com/linux-man-info-pinfo-the-linux-documentations</link><guid isPermaLink="true">https://tech.anupamm.com/linux-man-info-pinfo-the-linux-documentations</guid><category><![CDATA[Linux]]></category><category><![CDATA[manual]]></category><category><![CDATA[Help Needed]]></category><category><![CDATA[documentation]]></category><category><![CDATA[command line]]></category><dc:creator><![CDATA[Anupam Majhi]]></dc:creator><pubDate>Mon, 16 May 2016 16:56:29 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1693088527006/89f6757a-86a3-4f19-98fa-2421038a65f4.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In Linux, to get help or to read the documentation on a particular command we can use either of the three ways: <strong>man</strong>, <strong>info</strong> or <strong>pinfo</strong> .</p>
<p>The help command <strong>man</strong> is more popular and gives concise documentation of how to use a command, whereas the <strong>info</strong> or <strong>pinfo</strong> is the GNU documentation which is more detailed.</p>
<p>I personally liked <strong>pinfo</strong> the most, maybe because I come from a Windows background, but I guess I will use <strong>man</strong> more 😀</p>
<p>To get help with any of these documentation commands, just write the documentation command followed by the command with which you need help. Example:</p>
<pre><code class="lang-bash">man date
</code></pre>
<p>or</p>
<pre><code class="lang-bash">pinfo date
</code></pre>
<p>or</p>
<pre><code class="lang-bash">info date
</code></pre>
]]></content:encoded></item><item><title><![CDATA[LINUX: locale & localectl — The Linux Locale Settings]]></title><description><![CDATA[You can get or set the locale settings in a linux environment (tried in fedora) by using the command :
localectl

You can remember it as Locale Control
You can also get more locale information by simply executing the command:
locale

To learn all the...]]></description><link>https://tech.anupamm.com/linux-locale-localectl-the-linux-locale-settings</link><guid isPermaLink="true">https://tech.anupamm.com/linux-locale-localectl-the-linux-locale-settings</guid><category><![CDATA[Linux]]></category><category><![CDATA[command line]]></category><category><![CDATA[Bash]]></category><dc:creator><![CDATA[Anupam Majhi]]></dc:creator><pubDate>Mon, 16 May 2016 16:27:51 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1693088522552/4204a7a2-fe7d-4380-b29a-030a0a87da17.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>You can get or set the <strong>locale</strong> settings in a linux environment (tried in fedora) by using the command :</p>
<pre><code class="lang-bash">localectl
</code></pre>
<p>You can remember it as <strong>Locale Control</strong></p>
<p>You can also get more locale information by simply executing the command:</p>
<pre><code class="lang-bash">locale
</code></pre>
<p>To learn all the possible locale languages type this in terminal:</p>
<pre><code class="lang-bash">locale -a
</code></pre>
<p>To set locale (to change locale language setting), you can do something like this example:</p>
<pre><code class="lang-bash">localectl set-locale LANG=fr_FR.utf8
</code></pre>
<p>Also to temporarily to execute any command in a different language, prefix the command with the LANG=&lt;appropriate languagr&gt; &lt;command&gt;. For example:</p>
<pre><code class="lang-bash">LANG=fr_FR.utf8 date
</code></pre>
<p>To learn more about locale always take help of documentations.</p>
]]></content:encoded></item></channel></rss>