<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Kinjal</title>
    <description>The latest articles on DEV Community by Kinjal (@skypy).</description>
    <link>https://dev.to/skypy</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F585997%2F99076e5c-80ab-4352-a190-6594762fd77b.png</url>
      <title>DEV Community: Kinjal</title>
      <link>https://dev.to/skypy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/skypy"/>
    <language>en</language>
    <item>
      <title>Configure JDK17 in Ubuntu 20.04</title>
      <dc:creator>Kinjal</dc:creator>
      <pubDate>Fri, 03 Dec 2021 06:33:03 +0000</pubDate>
      <link>https://dev.to/skypy/configure-jdk17-in-ubuntu-2004-2ek</link>
      <guid>https://dev.to/skypy/configure-jdk17-in-ubuntu-2004-2ek</guid>
      <description>&lt;p&gt;Java 17 was released in September 2017. Java has multiple distributors as it is open source.&lt;br&gt;
Download from &lt;a href="https://jdk.java.net/17/" rel="noopener noreferrer"&gt;jdk.java.net&lt;/a&gt; for openjdk. The commerical verion can be found from &lt;a href="https://jdk.java.net/17/" rel="noopener noreferrer"&gt;oracle&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this setup openjdk x64 version is used.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9ppe6ewz2n69aqu3oao6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9ppe6ewz2n69aqu3oao6.png" alt="Open JDK" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here are the steps to configure jdk17.&lt;/p&gt;

&lt;p&gt;Create default jdk location if it is not there&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mkdir /usr/lib/jvm/ cd $_ 
$ tar -xvzf ~/Downloads/openjdk-17.0.1_linux-x64_bin.tar.gz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside &lt;code&gt;/opt&lt;/code&gt; create a directory for &lt;code&gt;jdk&lt;/code&gt; which will link to the actual jdk package.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cd /opt
$ mkdir jdk
$ ln -s /usr/lib/jvm/jdk-17.0.1 jdk17
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the following symlink is created, the next is to update &lt;code&gt;~/.bashrc&lt;/code&gt; file to update path for Java.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ jdk17 -&amp;gt; /usr/lib/jvm/jdk-17.0.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the following lines to &lt;code&gt;~./bashrc&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export JAVA_HOME=/opt/sun/jdk17/bin
export PATH=$PATH:$JAVA_HOME/bin 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The setup is completed and now Ubuntu should be informed about the new package by using &lt;code&gt;update-alternatives&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo update-alternatives --install "/usr/bin/java" "java" "/usr/lib/jvm/jdk-17.0.1/bin/java" 0
$ sudo update-alternatives --install "/usr/bin/javac" "javac" "/usr/lib/jvm/jdk-17.0.1/bin/javac" 0
$ sudo update-alternatives --install "/usr/bin/javap" "javap" "/usr/lib/jvm/jdk-17.0.1/bin/javap" 0
$ sudo update-alternatives --set java /usr/lib/jvm/jdk-17.0.1/bin/java
$ sudo update-alternatives --set javac /usr/lib/jvm/jdk-17.0.1/bin/javac
$ sudo update-alternatives --set javap /usr/lib/jvm/jdk-17.0.1/bin/javap
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, verify the setup to know jdk location as it was provided&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ update-alternatives --list java 
$ update-alternatives --list javac
$ update-alternatives --list javap
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, verify the java version&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ java -version
openjdk version "17.0.1" 2021-10-19
OpenJDK Runtime Environment (build 17.0.1+12-39) 
OpenJDK 64-Bit Server VM (build 17.0.1+12-39, mixed mode, sharing)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>java</category>
      <category>ubuntu</category>
      <category>linux</category>
      <category>programming</category>
    </item>
    <item>
      <title>Sample code to setup Selenium, chrome driver with a java project</title>
      <dc:creator>Kinjal</dc:creator>
      <pubDate>Thu, 02 Dec 2021 10:35:54 +0000</pubDate>
      <link>https://dev.to/skypy/sample-code-to-setup-selenium-chrome-driver-with-a-java-project-j47</link>
      <guid>https://dev.to/skypy/sample-code-to-setup-selenium-chrome-driver-with-a-java-project-j47</guid>
      <description>&lt;p&gt;Slenium is popular open source project that consists of a range of tools and libraries. Here is the most basic example to get started selenium with a java project.&lt;/p&gt;

&lt;p&gt;At the core of the selenium is &lt;a href="https://www.selenium.dev/documentation/webdriver/" rel="noopener noreferrer"&gt;webdriver&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;It is a powerful API that drives a browser natively, just as a user would do.&lt;/p&gt;

&lt;p&gt;Major components of webdriver are - selenium client library, JSON wire protocol over HTTP, browser drivers, and browsers.&lt;/p&gt;

&lt;p&gt;To get started first, &lt;a href="https://chromedriver.storage.googleapis.com/index.html?path=96.0.4664.45/" rel="noopener noreferrer"&gt;download&lt;/a&gt; webdriver version 96. Select the webdriver version as per the chrome browser version where the tests will be executed.&lt;/p&gt;

&lt;p&gt;Get &lt;code&gt;chromedriver_linux64.zip&lt;/code&gt; file and unzip it the project directory. &lt;/p&gt;

&lt;p&gt;The project that I am using here is a java project created using gradle build.&lt;/p&gt;

&lt;p&gt;The next step is to unzip and copy the driver the project directory.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;unzip /tmp/chromedriver_linux64.zip -d &amp;lt;PROJECT_DIR&amp;gt;/webdriver/v96/&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Once the driver is ready, now it is time to write a sample program.&lt;/p&gt;

&lt;p&gt;Make sure program should import the selenium related packages from &lt;a href="https://www.selenium.dev/selenium/docs/api/java/org/openqa/selenium/package-summary.html" rel="noopener noreferrer"&gt;org.openqa.selenium&lt;/a&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

public class SeleniumBasicExample { 
 final static String PROJECT_PATH = System.getProperty("user.dir");
  public void run() 
    throws Exception
     {
      System.setProperty("webdriver.chrome.driver", PROJECT_PATH + "/webdriver/v96/chromedriver");
      ChromeOptions chromeOptions = new ChromeOptions();
      chromeOptions
        .addArguments("--headless")
        .addArguments("--no-sandbox");

      WebDriver driver = new ChromeDriver(chromeOptions); 
      driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);

      // set any url for test, here is an example with google
      driver.get("https://google.com");
      Thread.sleep(1000);
      if (driver.getPageSource().contains("I'm Feeling Lucky")) {
       log("pass");  
      } else {
       log("fail");
      }
      driver.quit();
     }
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Here is the output of the above program -&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff2nytr3qd1te2onxmc1h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff2nytr3qd1te2onxmc1h.png" alt="selenium output"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Download &lt;a href="https://github.com/skypy/aqua/tree/main/app/src/main/java/aqua/samples" rel="noopener noreferrer"&gt;SeleniumBasicExample&lt;/a&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>testing</category>
      <category>programming</category>
      <category>testdev</category>
    </item>
    <item>
      <title>Clear out MySql/MariaDB binary log files</title>
      <dc:creator>Kinjal</dc:creator>
      <pubDate>Tue, 07 Sep 2021 12:47:49 +0000</pubDate>
      <link>https://dev.to/skypy/clearing-mysql-mariadb-binary-log-files-k8f</link>
      <guid>https://dev.to/skypy/clearing-mysql-mariadb-binary-log-files-k8f</guid>
      <description>&lt;p&gt;I came across the following error while resroting a databsae in MariaDB.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

ERROR 3 (HY000) at line 87066: Error writing file '/tmp/MLvCaXNh' (Errcode: 28 "No space left on device") 


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This is due to the excesive binary logs which are generated by database server.&lt;/p&gt;

&lt;p&gt;From &lt;a href="https://mariadb.com/kb/en/overview-of-the-binary-log/" rel="noopener noreferrer"&gt;MariaDB&lt;/a&gt; documentation - The binary log contains a record of all changes to the databases, both data and structure, as well as how long each statement took to execute. It consists of a set of binary log files and an index. &lt;/p&gt;

&lt;p&gt;It is required to periodically clear out those logs to avoid runninng into the problem of &lt;code&gt;No space left on device&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Clearing old log files also helps the process of database replication.&lt;/p&gt;

&lt;p&gt;List all the binary logs:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

mysql&amp;gt; show binary logs;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;And the query to delete all old files that were generated 2 days back:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

mysql&amp;gt; purge binary logs before date(now() - interval 2 day);


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You can only delete the files that are older than the oldest file that is used by the slaves.&lt;/p&gt;

&lt;p&gt;The diskspace error should be gone after clearing the logs.&lt;/p&gt;

&lt;p&gt;Where these log files are stored?&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg894lij05bwx256pak94.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg894lij05bwx256pak94.png" alt="mysql-binary-log"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Usually log files are stored in &lt;code&gt;/opt/mariadb/data&lt;/code&gt;.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6jn5plx4g6suyz599imq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6jn5plx4g6suyz599imq.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;sup&gt;Reference:&lt;br&gt;
&lt;a href="https://mariadb.com/kb/en/purge-binary-logs/" rel="noopener noreferrer"&gt;PURGE BINARY LOGS&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

</description>
      <category>mysql</category>
      <category>mariadb</category>
      <category>ubuntu</category>
      <category>linux</category>
    </item>
    <item>
      <title>A simple Gradle build with example on Ubuntu</title>
      <dc:creator>Kinjal</dc:creator>
      <pubDate>Thu, 02 Sep 2021 18:34:44 +0000</pubDate>
      <link>https://dev.to/skypy/a-simple-gradle-build-with-example-on-ubuntu-1hbo</link>
      <guid>https://dev.to/skypy/a-simple-gradle-build-with-example-on-ubuntu-1hbo</guid>
      <description>&lt;p&gt;Gradle is a higly customizable, powerful and fast build system.&lt;br&gt;
Let's walk through a simple example to configure a project using gradle.&lt;/p&gt;

&lt;p&gt;First, download a specific &lt;a href="https://gradle.org/releases/" rel="noopener noreferrer"&gt;release&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Here are the steps to configure it.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

$ mkdir /opt/gradle
$ unzip -d /opt/gradle gradle-7.2-bin.zip
$ ls /opt/gradle/gradle-7.2/
LICENSE  NOTICE  README  bin  init.d  lib  


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Add the following line in &lt;code&gt;~/.bashrc&lt;/code&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

export PATH=$HOME/.local/bin:$PATH 


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;~/.bashrc&lt;/code&gt; file should be updated to get the changes.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

$ source ~/.bashrc


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Run &lt;code&gt;gradle -version&lt;/code&gt; when the above steps are completed. &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7n93o76726wkpqgyg4p0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7n93o76726wkpqgyg4p0.png" alt="gradle version"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's call the project name &lt;code&gt;blue&lt;/code&gt; and scaffold gradle for it.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

$ mkdir blue
$ cd blue
$ gradle init


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;It will ask few to setup the directory strucutre&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

Select type of project to generate:
 1. basic
 2. application
 3. library
 4. Gradle plugin


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;For this example, let's select &lt;code&gt;2. application&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;The following question will ask selecting the implementation language which I choose &lt;code&gt;java&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;The other options could be selected as per the given default choice.&lt;/p&gt;

&lt;p&gt;Let's create a &lt;code&gt;makefile&lt;/code&gt; and add some basic gradle commands there.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

$ cat makefile
 JAVA_HOME = /opt/sun/jdk15
 GRADLE_HOME = /opt/gradle/gradle-7.2

 GRADLE = $(GRADLE_HOME)/bin/gradle
 clean:
       ./gradlew clean  
 build:
      ./gradlew build
 run:
      ./gradlew run
 test:
      gradle test --tests AppTest 


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;App.java&lt;/code&gt; which is located in &lt;code&gt;app/src/main/java/blue/&lt;/code&gt; is the entry point to the project. &lt;br&gt;
Edit this class and add soem message to it.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

package blue;

public class App {
 private String getMessage() { return "My Gradle Project"; } 

 public static void main(String[] args) {
   App app = new App();
   System.out.println(app.getMessage());
 }
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now, run the project.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

$ make build
$ make run


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The sample message should be printed in the console if the build is successful.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/skypy/blue" rel="noopener noreferrer"&gt;Download&lt;/a&gt; this sample.&lt;/p&gt;

</description>
      <category>gradle</category>
      <category>ubuntu</category>
      <category>java</category>
      <category>linux</category>
    </item>
    <item>
      <title>Linux make install command</title>
      <dc:creator>Kinjal</dc:creator>
      <pubDate>Wed, 01 Sep 2021 13:56:49 +0000</pubDate>
      <link>https://dev.to/skypy/linux-make-install-command-2dd6</link>
      <guid>https://dev.to/skypy/linux-make-install-command-2dd6</guid>
      <description>&lt;p&gt;While installing packages in linux, we come across the following command many times.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ make install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's understand this with a simple example.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;install&lt;/code&gt; is a command that was written for software installation, but it can do more than that. &lt;code&gt;make install&lt;/code&gt; will do whatever instruction is defined in &lt;code&gt;makefile&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This example uses a sample hello world C program.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt; 
int main() {
 printf("Hello, World!"); 
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the directory structure of &lt;code&gt;testapp&lt;/code&gt; which is created for this example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ls testapp
installer.sh  makefile  testapp  testapp.c  testapp.conf 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's take closer look at &lt;code&gt;installer.sh&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash
ROOTDIR=${1:-/opt/testapp}
OWNER=${2:-testapp}
GROUP=${3:-testapp}

# Create bin and opt directories
install -v -m 755 -o $OWNER -g $GROUP -d $ROOTDIR/bin $ROOTDIR/etc
if [ "$?" -ne "0" ]; then
  echo "Install: Failed to create directories."
  exit 1
fi

# install binary
install -b -v -m 750 -o $OWNER -g $GROUP -s testapp $ROOTDIR/bin
if [ "$?" -ne "0" ]; then
  echo "Install: Failed to install the binary"
  exit 2
fi

# install configuration file
install -b -v -m 600 -o $OWNER -g $GROUP testapp.conf $ROOTDIR/etc
if [ "$?" -ne "0" ]; then
  echo "Install: Failed to install the config file"
  exit 3
fi

echo "installation completed.."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All the &lt;code&gt;chown&lt;/code&gt; &lt;code&gt;install&lt;/code&gt; ect commands are defined in &lt;code&gt;installer.sh&lt;/code&gt; and &lt;code&gt;insatller&lt;/code&gt; itself is wrapped up in &lt;code&gt;makefile&lt;/code&gt; so that &lt;code&gt;makefile&lt;/code&gt; can be kept clean.&lt;/p&gt;

&lt;p&gt;Here is &lt;code&gt;makefile&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;all:    testapp.c
    $(CC) -o testapp     testapp.c

clean:
    rm -f testapp

install: testapp
    ./installer.sh /opt/testapp kiwi kiwi

purge:
    rm -rf /opt/testapp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;code&gt;install&lt;/code&gt; command, &lt;code&gt;kiwi&lt;/code&gt; refers to the username. You can have your custom name here.&lt;/p&gt;

&lt;p&gt;And the content of sample conf file &lt;code&gt;testapp.conf&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cat testapp.conf
testapp=testapp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, running it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo make install
./installer.sh /opt/testapp kiwi kiwi
'testapp' -&amp;gt; '/opt/testapp/bin/testapp' (backup: '/opt/testapp/bin/testapp~')
'testapp.conf' -&amp;gt; '/opt/testapp/etc/testapp.conf' (backup: '/opt/testapp/etc/testapp.conf~')
installation completed..
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;testapp&lt;/code&gt; can be found in &lt;code&gt;/opt&lt;/code&gt; directory if the installation is successful.&lt;/p&gt;

&lt;p&gt;That's a very simple example. Here is one &lt;a href="https://thoughtbot.com/blog/the-magic-behind-configure-make-make-install" rel="noopener noreferrer"&gt;useful link &lt;/a&gt; for further reading.&lt;/p&gt;

&lt;p&gt;Download the code &lt;a href="https://github.com/skypy/sample/tree/main/testapp" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Reference&lt;/em&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;sup&gt;&lt;a href="https://www.amazon.in/Shell-Scripting-Expert-Recipes-Linux/dp/1118024486" rel="noopener noreferrer"&gt;Shell Scripting: Expert Recipes for Linux, Bash, and more&lt;/a&gt;&lt;sup&gt;&lt;/sup&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>linux</category>
      <category>install</category>
      <category>makefile</category>
      <category>shellscript</category>
    </item>
  </channel>
</rss>
