Create a new kubernetes user with custom kubeconfig auth

The important directories in the reckoning are /etc/kubernetes/pki/
The file ca.key and ca.crt are the Certificate Authority key and certificate respectively.

STEP 1: Generating the key and .csr(Certificate Signing Request)

Lets now generate the .key and .csr. certificates for 1 year with openssl:

[root@node01 ssl]# openssl req -new -sha256 -newkey rsa:2048 -nodes -keyout builduser01.key -days 365 -out builduser01.csr -sha256 -subj "/C=IN/ST=TG/L=/O=/OU=/CN=/subjectAltName=DNS.1="

Verification of the CSR:

[root@node01 ssl]# openssl req -in linuxcent.com.csr -noout -text
Certificate Request:
Data:
Version: 0 (0x0)
Subject: C=IN, ST=TG/subjectAltName=DNS.1= -- INFORMATION RETRACTED --
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:00:e4:b4:24:d7:22:ec:5d:c1:37:8c:d1:a0:62:17:
96:24:77:8d:75:4e:d5:74:15:4d:61:e0:8b:66:d6:
                Exponent: 65537 (0x10001)
        Attributes:
            a0:00
    Signature Algorithm: sha256WithRSAEncryption
         87:ef:83:b2:a6:f5:3a:f3:6f:1c:e4:02:ec:bf:5d:75:64:1d:

STEP 2: Digitally Signing .csr and generating .crt using root CA files.

Now we will using the root ca.key and ca.crt to digitally sign this csr and generate a .crt

[root@node01 ssl]# openssl x509 -req -in builduser01.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out builduser01.crt -days 365 -sha256
Signature ok
subject=/C=IN/ST=TG/subjectAltName=DNS.1=
Getting CA Private Key

We have successfully generated the .crt file from the .csr along with the .key file from STEP1 with the below names. builduser01.crt and builduser01.key

How to create user accounts on kubernetes

We now will create a builduser-config to create a kubeconfig for new user.

Injecting the cluster and the API server information into the kubernetes config file:

[root@node01 ssl]# kubectl config --kubeconfig=builduser-config set-cluster kubernetes --server=https://10.100.0.10:6443 --insecure-skip-tls-verify

We are now injecting the CA certificate information into the config file:

[root@node01 ssl]# kubectl config --kubeconfig=builduser-config set-cluster kubernetes --server=https://10.100.0.10:6443 --certificate-authority=/etc/kubernetes/pki/ca.crt --embed-certs=true

Injecting the credentials key and cert file data into the config file.

[root@node01 ssl]# kubectl config --kubeconfig=builduser-config set-credentials builduser01 --client-certificate=linuxcent.com.crt --client-key=linuxcent.com.key --embed-certs=true

Using –embed-certs=true, we can dump the cert and key file data into the config file instead of writing the path names

[root@node01 ssl]# kubectl config --kubeconfig=builduser-config set-credentials builduser01 --username=builduser01 --password=password123

Using the username and password is not explicitly required while the keys are being used.
Now copy the builduser-config to the $HOME/.kube/config and connect to the kubernetes cluster.

How to Inject Variables into Docker image in build time without modifying the Dockerfile

How to Inject Variables into Docker image in build time without modifying the Dockerfile

 

We have a requirement wherein we need to modify the specific Dockerfile with the build information and we make use of string replace operations like SED to modify the data in Dockerfile, But we can make use of the docker build time arguments to achieve the results efficiently.

Here’s a snippet of Dockerfile

FROM ubuntu:17.04
LABEL maintainer="vamshi" version="1.0.0" description="JRUBY Docker image"
WORKDIR /app
ARG JRUBY_VER 9.2.11.1
ENV JRUBY_VER ${JRUBY_VER}
ADD https://repo1.maven.org/maven2/org/jruby/jruby-dist/${JRUBY_VER}/jruby-dist-${JRUBY_VER}-bin.tar.gz .

We now build this Dockerfile as follows passing the –build-arg:

# docker build --build-arg JRUBY_VER=9.2.8.0 -t jruby:v2  -f ./Dockerfile .

Here we have passed in the build arguments of –build-arg the JRUBY_VER=9.2.8.0 and this then assigns the Argument to the ENV and passed it to ADD command which downloads tar.gz.

When run the command without any build-args it readsup the predefined ARG JRUBY_VER 9.2.11.1 from the Dockerfile.

Conclusion:
Another best usecase is while you have a continuous Docker build pipeline system and want to pass the build time arguments on user input, Its best to use ARG statements inside while writing your Dockerfile

Environmental Variables in Dockerfile.

The Docker Environment variables can be declared during the (1) Docker image creation inside the Dockerfile and (2) During the docker container run time.

The Dockerfile ENV syntax is shown as follows:

ENV VAR_NAME value

We will look at the Dockerfile syntax in the following snippet:

# Exporting the Environment Variables
ENV MAVEN_HOME /usr/share/maven/
ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64/
# Added as per Java team
ENV JAVA_OPTS -Xms256m -Xmx768m

We can even reference the ENV variable after the declaration at the next statement.

RUN ${JAVA_HOME}/bin/java -version

Conclusion:

Setting the ENV is a lot better than Hard coding the values into the Dockerfile, as it makes maintaining the Dockerfile a simpler task.

Its a good practice for storing the path names, version of packages which are set to be modified over a longer course of time.

How to identify if a docker container files have been modified

The docker container is simply a run time copy of a docker image resources, The docker container utilizes the filesystem structure originally packed into it via the union filesystem packaged from various image layers during the docker image creation.

The docker provides a standard diff command which compares the filesystem data in docker image with the container.

Syntax:

# docker diff [CONTAINER ID | CONTAINER NAME]

Before jumping in lets examine a docker container below and take a look at filesystem by logging into it.

root@node03:~# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
e3de85aaf61c        9a0b6e4f0956        "sh"                2 months ago        Up 3 minutes                            jovial_hertz

We have a running container with a random name jovial_hertz, and we login to the container as follows

root@node03:~# docker exec -it jovial_hertz bash

We are now inside the container and now will create a directory linuxcent and the also create a ASCII text file test and then exit out from the container.

root@e3de85aaf61c:~# mkdir linuxcent
root@e3de85aaf61c:~# cd linuxcent
root@e3de85aaf61c:~# touch test
root@e3de85aaf61c:~# exit

Created a directory called linuxcent and a touched a test file and now logged out from the container with the exit command.
The docker diff command will run against the container should result in the modified data and we contemplate the results

root@node03:~# docker diff jovial_hertz 
C /root
A /root/linuxcent
A /root/linuxcent/test
C /root/.bash_history

The Flags A in front of /root/linuxcent and /root/linuxcent/test indicate that these are directory and file that were the new additions to the container and Flag C indicates that the other 2 files were changed.
Thus it helps us to compare and contrast the new changes to a container filesystem for better auditing.

Docker login to private registry

STEP 1: Docker login to private registry

Lets see the syntax of docker login command followed by the authorized username and the repository URL.
Syntax:

[root@docker03:~]# docker login [DOCKER-REGISTRY-SERVER] -u <username> [-p][your password will be seen here]

The -p is the option for password which can be given along with the docker command or you can type it in the password prompt after hitting enter on the docker login command.

Example given:

[root@docker03:~]# docker login nexusreg.linuxcent.com:5000 -u vamshi
Password:
Login Succeeded

Once the docker login is succeeded a json file will be generated under your home directory at the following path which contains the auth metadata information.

[root@docker03:~]# cat $HOME/.docker/config.json
{
	"auths": {
		"nexusreg.linuxcent.com:5000": {
			"auth": "1234W46TmV0ZW5yaWNoMjAxOQ=="
		}
	},
	"HttpHeaders": {
		"User-Agent": "Docker-Client/18.09.1 (linux)"
	}
}

The docker login repository URL can be found out from your docker client machine using docker info command if you had previously logged in, as we see below:

[root@docker03:~]# docker info | grep Registry
Registry: https://index.docker.io/v1/

How to logout from the specific docker registry use the docker logout command.
The syntax is shown as below:
docker logout [DOCKER-REGISTRY-SERVER]

Example given:

[root@docker03:~]# docker logout 
Removing login credentials for https://index.docker.io/v1/

Setup and configure Zookeper and Kafka on Linux

We would need java runtime environment to install and operate the kafka and zookeeper programs on our linux environment as a dependency which uses the java runtime environment.
So lets quickly check the current java version on the system with java -version.
If its not present Lets now begin with the setup of Java and quickly download the java stable version from the epel repository.

# yum install java-1.8.0-openjdk

Once the java version is installed we verify it with the java -version command.
Creating the kafka user account.

# useradd kafka -m -d /opt/kafka

Adding the kafka password

# echo "kafka" | passwd kafka --stdin
usermod -aG wheel kafka
# su -l kafka

Now login to the system as kafka user.

# cd /opt

Navigate to the url : https://downloads.apache.org/kafka/ and download the latest kafka version

# curl https://downloads.apache.org/kafka/2.5.0/kafka_2.13-2.5.0.tgz -o /opt/kafka.tgz
# tar -xvzf ~/opt/kafka.tgz --strip 1
# cd /opt/kafka
# cp -a /opt/kafka/config/server.properties ~/opt/kafka/config/server.properties.bkp
# echo -e "\ndelete.topic.enable = true\nauto.create.topics.enable = true" >> /opt/kafka/config/server.properties

Adding the Kafka start/stop scripts to systemctl controller daemon services

# sudo vim /etc/systemd/system/zookeeper.service
Add the following lines to /etc/systemd/system/zookeeper.service
[Unit]
Requires=network.target remote-fs.target
After=network.target remote-fs.target

[Service]
Type=simple
User=kafka
ExecStart=/opt/kafka/bin/zookeeper-server-start.sh /opt/kafka/config/zookeeper.properties
ExecStop=/opt/kafka/bin/zookeeper-server-stop.sh
Restart=on-abnormal

[Install]
WantedBy=multi-user.target

Now adding the Kafka control scripts to systemd service

# sudo vim /etc/systemd/system/kafka.service
Add the following lines to /etc/systemd/system/kafka.service
[Unit]
Requires=zookeeper.service
After=zookeeper.service

[Service]
Type=simple
User=kafka
ExecStart=/bin/sh -c '/opt/kafka/bin/kafka-server-start.sh /opt/kafka/config/server.properties > /opt/kafka/kafka.log 2>&1'
ExecStop=/opt/kafka/bin/kafka-server-stop.sh
Restart=on-abnormal

[Install]
WantedBy=multi-user.target
# sudo chown kafka.kafka -R /opt/kafka/logs
# sudo mkdir /var/log/kafka-logs
# sudo chown kafka.kafka -R /var/log/kafka-logs

Now start the zookeeper and kafka services as follows:

# sudo systemctl enable zookeeper --now

# sudo systemctl enable kafka --now





How to create user account in Linux

The Linux system provides a couple of command line utilities to create new users on the system

As we are aware, the Linux login has the essential fields listed as follows:

  • A unique system wide username,
  • A Strong password,
  • The home directory and
  • A login shell.

These are the mandatory fields to enable account creation.

The other fields are the UID and GID numbers associated with User an Group name numerical IDs which will be generated sequentially allocated by the Linux Kernel

We can do a broad categorization of login accounts into 2 types, those are the Privileged and the normal user.

The Absolute Privileged account is root which comes by default in all the linux machines.

The normal account can be enabled with root Privileged by assigning user to certain groups and providing elevated access in the scope.

What is the Process to create a User account in Linux?

The user creation has to be done with root privileges using useradd command.

$ sudo useradd newuser

Now it’s time to enter the password

$ sudo passwd newuser

How to check if the userid is present and active on the system?

The new user details will be updated to /etc/passwd file and the login information updated to /etc/shadow

Now let’s check if the user account is created and has a valid shell

vamshi@node03:/$ grep vamshi /etc/passwd

vamshi:x:1001:1001::/home/vamshi:/bin/bash

How to Add the user to new groups in Linux?

Usermod command line linux utility enables to add user to groups and the ability to add an existing user to new groups additionally or overwrite the group membership

$ usermod -aG dockerroot wheel vamshi

The option -a: appends the user to two new groups called dockerroot and wheel with out overwriting the existing user assigned groups, violating this option will restrict the newuser to be part of only the mentioned groups in the command

How to check and verify if the user is a member of group in Linux?

[vamshi@node02 Linux-blog]$ id vamshi
uid=1001(vamshi) gid=1001(vamshi) groups=1001(vamshi),0(root),10(wheel),992(dockerroot)

How to Verify the Login Confirmation in Linux?

From the root user account run the command: su - newuser to check the new login account environment.

How to find the group names assigned to the user

The user can list of his active membership groups by running the linux command groups

The user can run the groups command to list the groups with active membership

[vamshi@linuxcent ~]$ groups
vamshi root wheel dockerroot

Login to the server remotely using SSH

You may now use the ssh command to login with the new username and enter your password at login prompt.

$ ssh [email protected]

How to connect to server with SSH running on non-standard port like 2202?

[vamshi@linuxcent ~]$ ssh localhost -p 2202
Last login: Mon Mar 13 17:57:56 2020 from 10.100.0.1

How to create a useraccount in Linux using useradd command?

The usercreation can also be done with parametrized command as demonstrated below:

$ sudo useradd vamshi -b /home/ -m -s /bin/bash

Alternatively you can be more elaborate as mentioned below:

$ sudo useradd vamshi -c "Vamshi's user account" -d /home/vamshi -m -s /bin/bash -G dockerroot

The useradd command-utility options describes as follows:

-b or --base-dir : base directory of new user home directory.

-c or --comment : Description about the user Or as A Standard Practice can be used to Mention the Current User’s Full name.

-d or --home-dir : create the user’s home directory

-m or --create-home :  create the user’s home directory as per -d option.

-s or --shell : Type of Login Shell.

-u or --uid : is the Unique UID on linux machine

-G or --groups : list of secondary groups to be assigned

-k or --skel : determines the default parameters if no options are passed while account creation. Present at /etc/default/useradd

With the skel properties finely tunes, you can proceed to use adduser command which is based on the default skel behavior as shown below:

$ sudo adduser vamshi

How to using the SSH key pair to login:
Use the -i followed by the /path/to/id_rsa private key file

$ ssh -i ~/.ssh/id_rsa [email protected]
$ ssh -i ~/.ssh/id_rsa -l linuxcent.com

-l : using the login name

-i : is the identity file; rsa the private key file

 

Troubleshooting the SSH connection in Verbose mode printing Debug information

Using -v option with the ssh command will print the debug information while logging

The verbosity levels -v can be concatenated from one to Nine; eg -v to -vvvvvvvvv

$ ssh -i ~/.ssh/id_rsa [email protected] -vvvvvvvvv

How to make a file or Folder undeletable on Linux

How to make a file or Folder/Directory un-deletable on Linux?

The linux operating as we know if famous for the phrase “Everything is a file”, In such circumstances it is interesting to explore the possibilities of making a file undeletable, even by the owner of the file and for that matter even the root user, In the Linux Ecosystem the root is the poweruser.

This section we will see the potential of such feature.

As we have already seen the section on deleting files on Linux (removing the files in Linux).

We will now demonstrate the power of Linux where you can restrict the deletion of a file on Linux.

Linux offers a chattr commandline utility which generally modifies the file attributes as the name suggests, but the practical use is to make a file undeletable.

Sample command syntax:

[vamshi@linuxcent ~]$ chattr +i <samplefile>
vamshi@linuxcent delete-dir]$ sudo chattr +i samplefile2.txt
Now we do ls -l samplefile2.txt
[vamshi@linuxcent ~]$ sudo chattr +i samplefile2.txt
[vamshi@linuxcent ~]$ ls -l samplefile2.txt
-rw-rw-r--. 1 vamshi vamshi 4 Apr 8 15:42 samplefile2.txt

Now we shall try to write some content to this file and see no change in the basic file permissions(see changing ownership of files).

[vamshi@linuxcent delete-dir]$ echo "New content" > samplefile2.txt
-bash: samplefile2.txt: Permission denied

Deleting file forcefully with the --force option ?

[vamshi@linuxcent delete-dir]$ sudo /bin/rm -f samplefile2.txt

/bin/rm: cannot remove ‘samplefile2.txt’: Operation not permitted

Linux command lsattr offers the ability to view the permissions set by the chattr command.
The current File attributes can be listed using lsattr followed by the filename [/code]samplefile2.txt[/code] as below

[vamshi@linuxcent delete-dir]$ lsattr samplefile2.txt
----i----------- samplefile2.txt

Even the root user on the host is unable to delete the file or modify its contents.

The file can be deleted only when the attributes are unset, It is demonstrated as follows:

[vamshi@linuxcent delete-dir]$ sudo chattr -i samplefile2.txt
[vamshi@linuxcent delete-dir]$ lsattr samplefile2.txt
---------------- samplefile2.txt

As we can see the lsattr doesn’t hold true anymore attributes on our file samplefile2.txt and is now being treated as any other normal file with basic file attributes.
The - operation removes the special linux file attributes on the mentioned file.

The chattr / lsattr linux commandline utilities currently supports the popular filesystems such as ext3,ext4,xfs, btrfs etc,.

Linux Find command – with Practical examples

The Linux find command utility is a powerful command in locating the files and directories at system wide level, the

The basic syntax of find command is very straight forward. The number of filters and types of options you choose while forming the find command determines and complexity of the operation and is directly proportional to the run time of the command.

Lets examine the general syntax of Linux find command line utility

$ find [path] [Options/filters] [expression]

How to Find all the files that are modified within 1 day.

$ find . -mtime -1

Use find command to find all the files that are modified within last x Minutes

$ find . -mmin -360

How to Find all the files that are created within given Minutes

$ find . -cmin -360

How to Find all the files under a specific size on the filesystem.

$ find . -type f -size -100G

NOTE: the - will find the files including and under the mentioned size

How to find really big size files with a given size using Linux Find Command.

$ find . -type f -size +100G

NOTE: the + will find the files exceeding the mentioned size

How to Find all the files with a pattern match using Find command?

vamshi.santhapuri@linux-pc:~/Linux/Programs> find *.py
my_program.py
myProgram.py
My_program.py

OutPut Demonstrated:

vamshi@linuxcent:~/Linux/Programs> ls -l
total 0
-rwxr-xr-x 1 vamshi users 0 Apr 8 16:33 my_program.py
-rwxr-xr-x 1 vamshi users 0 Apr 8 16:32 myProgram.py
-rwxr-xr-x 1 vamshi users 0 Apr 8 16:32 My_program.py ex

 

Find Files Based on file-type using option -type

Find only the regular file type

$ sudo find / -type f -print

Find only the Directory

$ sudo find / -type d -print

Lets see some special file formats like character files as in network level files and block files as in storage device file type.

$ sudo find /dev/ -type b -print
/dev/sdb8
/dev/sdb7
/dev/sdb6
/dev/sdb5
/dev/sdb4
/dev/sdb1
/dev/sdb
/dev/sda6
/dev/sda5

How to find empty files and Directories in Linux using Find command?

$ find . -empty # Finds all files and directories that are empty
$ find . -type f -empty #Find onlt empty files
$ find . -type d -empty #Find only empty Directories

How to Find all the hidden files and directories using Find command

You can also add the type flag as required

$ find . -name ".*" //Prints all the files and directories that are hidden

Find the character stream files and identify them yourselves.

$ sudo find / -type c -print

 

How to exclude some files or directories while using the find command?

The negation Operator ! in find command line

[vamshi@linuxcent ~]$ find / -type d  ! -path /mount ! -path /mnt/3TB/

How to find the files with .py extension and then setting the execute permission on them ?

-exec is a special builtin option which takes the specified command on the selected files

[vamshi@linuxcent ~]$ find *.py -exec chmod +x {} \;

A practical example of Finding and Deleting Big size files using Find Command

We Demonstrate a Big thread dump file that we generated in our Test environment by finding it on our server and then deleting it.

[vamshi@linuxcent ~]$ find /var -type f -size +100G -exec rm {} \;

 

To find the files with matching file permissions

[vamshi@linuxcent ~]$ sudo find / -type f -perm 0600 -print

More complex find operations can be performed by combining the negation operator and by excluding the certain mount points and using the logical AND OR operators.

For example:

sudo find / -xdev -type d \( -perm -0002 -a ! -perm -1000 \) -exec ls -ld {} \;

Ignore case using the find command

The filter -iname enables the find to perform case insesitive search.

[vamshi@node02 Linux-blog]$ find . -iname "rEadMe*" 
./Debian-Distro/README-Debian-Distro
./OpenSuse-Distro/README-Opensuse-Distro
./README
./Redhat-Distro/Centos/README-CentOS
./Redhat-Distro/README-Redhat-Distro

How to use Maxdepth Option in the find command to explore the directory depth?

[vamshi@node02 Linux-blog]$ find . -maxdepth 1 -name "README*" 
./README

By using find command filter option -maxdepth Now we can extract the results based on the one level deeper subdirectory, which is demonstrated as follows:

[vamshi@node02 Linux-blog]$ find . -maxdepth 2 -name "README*" 
./Debian-Distro/README-Debian-Distro
./OpenSuse-Distro/README-Opensuse-Distro
./README
./Redhat-Distro/README-Redhat-Distro

How to use mindepth Option in the find command to restrict the results based on the subdirectory depth?

The -mindepth filter option restricts the find command search to nth subdirectory level from the given path.

[vamshi@node02 Linux-blog]$ find . -mindepth 3 -name "README*" 
./Redhat-Distro/Centos/README-CentOS

 

How to use grep command in Linux and Unix

The grep command is one of the most essential commands in Unix/Linux ecosystem, It is used to extract match and find the occurrence of string literals and patterns among the text files.

In this section we will focus on the important scenarios and provide the realtime explanation about the Various Grep command options offered in linux command line.

We now have a text file with Following content.

Below is the content of the file called intro.txt.

[vamshi@linuxcent grep]$ cat intro.txt
the first line is in lower case
THE SECOND LINE IS IN UPPER CASE


There following are Most popular Linux server Distributions:
1) Redhat Enterprise Linux
2) Ubuntu
3) Centos
4) Debian
5) SUSE Linux Enterprise Server
This is a Demonstration of Linux grep command

Let’s start with search of a string pattern in the given file

The grep command sample search syntax is

$ grep “string pattern” <filename>
$ cat < filename | * > | grep "string pattern"

Lets see the Demonstration

[vamshi@linuxcent grep]$ grep "Linux" intro.txt
There following are Most popular Linux server Distributions:
1) Redhat Enterprise Linux
5) SUSE Linux Enterprise Server
This is a Demonstration of Linux grep command

Searching for a pattern on multiple files using grep command

Lets see the Demonstration

[vamshi@linuxcent grep]$ grep "Linux" intro.txt intro-demo.txt
intro.txt:There following are Most popular Linux server Distributions:
intro.txt:1) Redhat Enterprise Linux
intro.txt:5) SUSE Linux Enterprise Server
intro.txt:This is a Demonstration of Linux grep command
intro-demo.txt:There following are Most popular Linux server Distributions:
intro-demo.txt:1) Redhat Enterprise Linux
intro-demo.txt:5) SUSE Linux Enterprise Server
intro-demo.txt:This is a Demonstration of Linux grep command

 

How to print the sequence number of matched pattern in file using Grep command in Linux?

Print the sequence number of lines that contain the matched string pattern can be achieved using -n Option:

[vamshi@linuxcent grep]$ grep -n "Linux" intro.txt
4:There following are Most popular Linux server Distributions:
5:1) Redhat Enterprise Linux
9:5) SUSE Linux Enterprise Server
11:This is a Demonstration of Linux grep command

The -b Option prints the subsequent starting offset index of the matching word from the lines within the given filename.

[vamshi@linuxcent grep]$ grep -b "Linux" intro.txt
66:There following are Most popular Linux server Distributions:
127:1) Redhat Enterprise Linux
184:5) SUSE Linux Enterprise Server
217:This is a Demonstration of Linux grep command

So far we have seen only the matching string pattern, but if you want to find the occurance of particular word then use grep -w Option

Lets us see the Demonstration below:

[vamshi@linuxcent grep]$ grep -w "Cent" intro.txt


And As expected here we have not seen any occurrence of the word Cent from the file although the word Centos was present, But it didnt match because we used -w option to match the word Cent.

But when we grep for the Word Linux then we can see the exact occurrence of the word and the matching lines are printed.

[vamshi@linuxcent grep]$ grep -w "Linux" intro.txt
There following are Most popular Linux server Distributions:
1) Redhat Enterprise Linux
5) SUSE Linux Enterprise Server
This is a Demonstration of Linux grep command

This can be used in conjunction with -o prints only completely matched word string pattern.

[vamshi@linuxcent grep]$ grep -w -o "Linux" intro.txt
Linux
Linux
Linux
Linux

How to use the Invert Option in Linux grep command

The -v option prints all the lines not matching the given string pattern.

[vamshi@linuxcent grep]$ grep -v "Linux" intro.txt
the first line is in lower case
THE SECOND LINE IS IN UPPER CASE


2) Ubuntu
3) Centos
4) Debian

 

How to print the names of all the files matching the string pattern using Linux Grep command.

Using the -l Option of grep command will print all the file names containing the matching string pattern/string literal

[vamshi@node02 grep]$ grep -l Linux *
intro-demo.txt
intro.txt

How to get the number of Count Matches using Grep command ?

In Linux Grep command we can use the Option -c to get the total occurance Count of the matching pattern/string

Lets see the Demonstration below

[vamshi@linuxcent grep]$ grep -c "Linux" intro.txt
4

How to Exclude specific Directories while searching with grep command ?

The --exclude-dir="Some Directory name" options skips the contents of the mention directory Lets see the Demonstration:

$ grep -w -E "data" * -R --exclude-dir="backup" --exclude-dir="adb-fastboot" --exclude-dir="IntelliJ-IDEA"

How to use Linux Grep commmand to ignore the case  OR perform Case Insensitive search ?

Linux Grep Command offers the -i to skip the case and perform the search.

[vamshi@linuxcent grep]$ grep -i Cent intro.txt
3)Centos

Lets search for the Work Upper from the file with -i option

[vamshi@linuxcent grep]$ grep Upper -i intro-demo.txt
THE SECOND LINE IS IN UPPER CASE

How to Grep for the lines before and After the pattern occurrence in a file

We can use the below options in Linux Grep command to extract the N number of lines matching the containing pattern before/After from the given file.. Lets look at the Options in detail

Generic Syntax:

grep -<A|B|C> “string pattern” filename*

Lets see the Demonstration as follows:

-A: Prints N number of lines After the pattern match and the line containing the match

[vamshi@linuxcent grep]$  grep -A2 docker /etc/passwd
dockerroot:x:996:992:Docker User:/var/lib/docker:/sbin/nologin
mysql:x:27:27:MariaDB Server:/var/lib/mysql:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin

-B: Prints N number of lines Before the pattern match and the line containing the match

[vamshi@linuxcent grep]$  grep -B2 docker /etc/passwd
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
builduser1:x:1002:1002::/home/builduser1:/bin/bash
dockerroot:x:996:992:Docker User:/var/lib/docker:/sbin/nologin

-C: Prints the line Containing the pattern and the N number of lines Before and After

[vamshi@linuxcent grep]$ grep -C2 docker /etc/passwd
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
builduser1:x:1002:1002::/home/builduser1:/bin/bash
dockerroot:x:996:992:Docker User:/var/lib/docker:/sbin/nologin
mysql:x:27:27:MariaDB Server:/var/lib/mysql:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin

Linux Grep command using the Regular Expression (regex) search pattern

How to use the Special Meta-characters in Grep Command

The Special Meta-Character ^ (caret) symbol to match expression at the start of a line.
Practical examples of grep command using meta-characters are as follows:

[vamshi@linuxcent grep]$ grep ^root /etc/services
rootd           1094/tcp                # ROOTD
rootd           1094/udp                # ROOTD

$ (dollar) symbol to match expression at the end of a line

[vamshi@linuxcent grep]$ grep "bash$" /etc/passwd
root:x:0:0:root:/root:/bin/bash
vagrant:x:1000:1000:vagrant:/home/vagrant:/bin/bash
vamshi:x:1001:1001::/home/vamshi:/bin/bash
jenkins:x:997:994:Jenkins Automation Server:/var/lib/jenkins:/bin/bash
builduser1:x:1002:1002::/home/builduser1:/bin/bash
linuxcent:x:1003:1004::/home/linuxcent:/bin/bash

Another Bonus regex for evading Empty lines from a text file using the Meta-characters ^ Carat and $ Dollar Symbols.

[vamshi@node02 grep]$ grep -Ev "^$" intro.txt
the first line is in lower case
THE SECOND LINE IS IN UPPER CASE
There following are Most popular Linux server Distributions:
1) Redhat Enterprise Linux
2) Ubuntu
3) Centos
4) Debian
5) SUSE Linux Enterprise Server
This is a Demonstration of Linux grep command

As the result of the above command observed Empty lines in our text file are now excluded with the inverted matching of Empty line pattern expression.

Digit Matching operation using Linux Grep Command

The Grep command Option -P offers the perl-regex pattern matching to perform some of the tricky pattern matching conditions, Lets see the Demonstration.

[vamshi@linuxcent grep]$ grep -P "[\W][\d][\d]/" /etc/services

Now we Demonstrate Numerical pattern matching in the following ways to match the exact occurrence of IPv4 address

[vamshi@linuxcent grep]$ ip a |grep -E "[0-9].[0-9].[0-9].[0-9]"
inet 127.0.0.1/8 scope host lo
inet 10.100.0.20/24 brd 10.100.0.255 scope global noprefixroute eth1

The similar result can be extracted using -P, Demonstrated as below:

[vamshi@linuxcent grep]$ ip a  | grep -P "[\d].[\d].[\d].[\d]"
inet 127.0.0.1/8 scope host lo
inet 10.100.0.20/24 brd 10.100.0.255 scope global noprefixroute eth1

Highlighting the Search patterns with Color codes

If you want to highlight the search pattern from the output we can make use of Color code Option is grep

[vamshi@linuxcent ~]$ ps -ef |grep java --color=yes

 

grep command and the Meta-characters with practical examples

In the Extended Regular Expression the metacharacters ?, \+, \{,  \|, \(, and \) enhances and takes the search string to manifest into a rich pattern

The square brackets [/code][ ][/code] includes a list of characters and it matches a single character in the list. Within the bracket, we can specify a  range, like [a-z] [0-9] [abcd], But it only matches a single character in the give list range.
The brackets can contain the carat ^ or the $ symbols and can be globbed with the wildcard characters for finding the repetitive pattern.

Here we shall see the demonstration of a few metacharacters conjunction into a single grep command

Using the Infix Operator | with the meta-characters

$ dmesg -H | egrep '(s|h)d[a-z]'

A quick practical look at the dmesg to find about the errors and warnings using grep command.

$ dmesg -H | grep -Ei “error|warn”

How to find the exact work match for the word error or err with a blank white space at the start of the word from dmesg?
$ dmesg -H | grep -Ei “(er)[r]{1,2}(or)”
$ dmesg -H | grep -Ei “(\We)[r]+(or)|(\Werr)”

Explanation: The grep search metacharacter regular expression matches the occurring of the string literals “error” with the minimum 1 time occurrence (error) of literal r and maximum 2 times.

The output only prints lines containing the word “error“ in a case insensitive grep search.

 

Another great practical example here we apply the same logic to enhance the metacharacter regex pattern to search for the occurrence of error with but without a trailing colon “:” symbol

dmesg -H | grep -Ei “(error)[:]{0}”

 

How to create symbolic Link or Softlinks in Linux and differentiate between Softlink vs Hardlink

The concept of Links in Linux/Unix based systems is Unique and gives a very deeper understanding of the Linux working internals at various levels.

The symbolic also known as Soft link is a special type of linking that acts as a pointer to the original file present on the disk.

The Softlink span across different filesystems extensively and widely used during software package installation and configuring

Lets look at the example of java command linking:

[root@node02 ]# which java
/bin/java
[root@linuxcent ]# ls -l /bin/java
lrwxrwxrwx. 1 root root 22 Apr 10 11:52 /bin/java -> /etc/alternatives/java
[root@node02 boot]# ls -l /etc/alternatives/java
lrwxrwxrwx. 1 root root 73 Apr 10 11:52 /etc/alternatives/java -> /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.242.b08-0.el7_7.x86_64/jre/bin/java
[root@linuxcent ]#

If you upgrade java on your system then the /bin/java command points out to a newer installed version of /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.242.b08-0.el7_7.x86_64/jre/bin/java

We will see the demonstration of a Symbolic link.

In Linux to make the links between files, the command-line utility is “ln”.

Softlink Creation syntax using the Linux command line utility ln -s option:

ln -s <source file|Directory > <destination Link file|Directory>

Below is an example

[vamshi@linuxcent html]$ ln -sf /var/www/html/index.html /tmp/index.html

[vamshi@linuxcent html]$ ls -l /tmp/index.html

lrwxrwxrwx. 1 vamshi vamshi 24 Apr  1 18:23 /tmp/index.html -> /var/www/html/index.html

 

The second file is called a symbolic ink to /tmp/index.html

Now the second file /tmp/index.html is called a Symbolic link to the First file on the disk /var/www/html/index.html

It means that the second file is just pointing to the first file’s location on disk without actually copying the contents of the file.

[vamshi@linuxcent html]$ cat /var/www/html/index.html
Welcome to LinuxCent.com
[vamshi@linuxcent html]$ cat /tmp/index.html
Welcome to LinuxCent.com

When you edit either of the file, the contents of the original file on disk are directly modified.

 

How to create Softlinks to Directories in Linux ?
The same logic applies to creating the soft links to directories, Lets see the Demonstration below:

[vamshi@linuxcent html]$  ln -sf /var/www/html/linuxcent/static/ /tmp/static
[vamshi@linuxcent html]$ ls -l /tmp/static
lrwxrwxrwx. 1 vamshi vamshi 32 Apr  8 18:37 /tmp/static -> /var/www/html/linuxcent/static/


 

How do we Remove the linking between the files is even simpler.

Simply run the unlink command on its Destination:

Sample command:

unlink <destination Link file | Directory>

Lets see the Demonstration

unlink /tmp/data-dir

 

Understanding Symbolic / Hard link concept better with improving knowledge on Inode.

To better understand the concept of Symbolic linking we need to understand the concept of Inode numbers present in Linux. I will give a brief overview of it in this section But for Detailed Review, Please see the What is Inode in Linux Section.

We can list out the inode number of any file on linux system using [/code]ls -i <filename>[/code]

Now The extreme left column indicates the system wide unique inode number:

[root@node02 ~]# ls -li /var/www/html/index.html /tmp/index.html 
67290702 lrwxrwxrwx. 1 root root 24 Apr 8 19:09 /tmp/index.html -> /var/www/html/index.html
33557754 -rw-r--r--. 1 root root 25 Apr 8 18:19 /var/www/html/index.html

We can see here the inode number for both the files have different, Because the second file is just a pointer to the original source file..

So why do we create the Symbolic Links ?

We have the advantages of the Softlinks

  1. One Advantage of Softlinks/symbolic links is they span across different filesystems
  2. Can have many softlinks to a single file/Directory.
  3. Can create Symbolic Links of Directories and Files respectively.
  4. Rsync program by default preserves the symbolic links.
  5. The softlinks become activated immediately if the source is recreated or recovered after any kinds of network outages.

What are the best practices when using Softlinks ?

The best practice while creating softlinks is to mention absolute path for source and destination links.

On the other hand you should also understand the disadvantages or shortcomings.

  1. It is Important to observe that If the source file is deleted then the symbolic link becomes useless.
  2. Incases of the Network filesystem issues leading to unavailability of softlinks.

It is also Essential to understand about the Hardlinks to get an overall understanding.

 

Creating a hard link is a simple operation using ln command with no options

Sample Command:

$ ln /path/to/source/ /path/to/HardLink/

So lets start of by creating a hard link of our file /var/www/html/index.html

[vamshi@linuxcent linuxcent]$ ln /var/www/html/index.html /tmp/index-hl.html

The command ls -il lists the inode number of the files.

[vamshi@linuxcent  ]$ ls -i
33557752 index-hl.html  33557752 index.html

So to conclude, The hard linking results in the same inode number, howmany ever times the hardlink of same file is created.
The data continues to persists in the same storage location on the filesystem even if one of the hardlink file is deleted.
As long as the inode number is identical on the files, no filename change matters to the filesystem.
There will be no change in Hardlink behaviour.

Let’s add some content to the hardlink file here and see the Demonstration

[vamshi@linuxcent ]$ echo "We are updating the file to check out the Hardlinks" >>  /tmp/index-hl.html
We are updating the file to check out the Hardlinks

The new line is added in the original file.

[vamshi@linuxcent linuxcent]$ cat index.html
Welcome to LinuxCent.com
We are updating the file to check out the Hardlinks

Content manipulations to either of the files will be treated as a same file.

How to Identify how many times a particular file was linked ?

Note that Linux Command ls -li provides the actual link aggregate count information in the fourth column represented by the number 2 here, which means that it has a second hardlink reference and both the files are interchangeable.
And It should be noted that a file has a link count of 1 by default as it references itself

$ls -li
33557752 -rw-rw-r--. 2 vamshi vamshi 59 Apr  8 19:48 index-hl.html
33557752 -rw-rw-r--. 2 vamshi vamshi 59 Apr  8 19:48 index.html

In case either one of the file is deleted, the other file survives and continues to function properly.

Lets see some hard facts on the Hardlinks.

  1. Hardlinks can’t be created to Directories.
  2. They do not span across filesystems.