Rabbitmq standalone and cluster installation

  • Install rabbitMQ in the VM. Following are the installations steps.
    ·         Verify if the earlang package is installed
  • rpm -q erlang-solutions-1.0-1.nonarch.rpm
  • wget http://packages.erlang-solutions.com/erlang-solutions-1.0-1.noarch.rpm
  • sudo wget http://packages.erlang-solutions.com/erlang-solutions-1.0-1.noarch.rpm
  • sudo yum update NOTE : use command “yum –releasever=6.7 update” if you want a specific version.
  • su -c ‘yum list rabbitmq’   Or use
  • yum install rabbitmq-server
  • sudo rpm -Uvh http://www.rabbitmq.com/releases/rabbitmq-server/v3.6.0/rabbitmq-server-3.6.0-1.noarch.rpm
  • sudo /etc/init.d/rabbitmq-server start·
  • Uncomment the loopback line in security section of rabbitMq.config :  {loopback_users, []}ss
  • rabbitmq-plugins enable rabbitmq_management·
  • Configure port firewall rule should be in place to accept the tcp connection.
  • Use following command : lokkit –p <rabbitMQ port>:tcp , lokkit –p <rabbitMQ management port>:tcp·
  • Default guest/guest account should be disabled. Change the user and user permissions using following commands :
  • Note : password should be 16 characters , no special characters allowed and should be generated by keypass.
  • rabbitmqctl set_user_tags <username> administrator      rabbitmqctl change_password guest guest123
  • Disable the guest user by changing the password once the created user is tested.
  • rabbitmqctl add_user <username> <password>
  • Avoid use of RabbitMQ default port and configure to use our own choice. Edit the port in rabbitMq.config file. uncomment following line and edit the port : {tcp_listeners, [<rabbitMQ port>]} and {listener, [{port,    <rabbitMQ management port>}.
  • Install management console of rabbitmq using following command :
  • Copy  /usr/share/doc/rabbitmq-server/ rabbitmq.config.example in /etc/rabbitmq folder and rename it as rabbitmq.config. Edit the permissions for the file to: 666
  • sudo chkconfig rabbitmq-server on
  • sudo rpm –import http://www.rabbitmq.com/rabbitmq-signing-key-public.asc
    for rabbitmq 3.6.*  ,require socat dependency:
    steps : sudo yum install epel-release
    sudo yum install socat
  • sudo yum install -y erlang-18.2-1.el6
  • sudo rpm -Uvh erlang-solutions-1.0-1.noarch.rpm
  • Install erlang package:
  • dowload the erlang package from web site:
  • Restart the rabbitmq server using commnad : sudo service rabbitmq_server restart.
  • Make the following changes on rabbitmq console:  Got to Admin > click on user and click on set permissions. Check the permissions of the user. It should be same as user guest.
  • Try to create new queue to check it is working fine.

 

Create RabbitMQ High Availability Cluster:

1) Stop RabbitMQ in Master and slave nodes. Ensure service is stopped properly.

/etc/init.d/rabbitmq-server stop

2) Copy the file below to all nodes from the master. This cookie file needs to be the same across all nodes.

$ sudo cat /var/lib/rabbitmq/.erlang.cookie

3) Make sure you start all nodes after copying the cookie file from the master.

Start RabbitMQ in master and all nodes.

$ /etc/init.d/rabbitmq-server start

4) Then run the following commands in all the nodes, except the master node:

$ rabbitmqctl stop_app$ rabbitmqctl reset$ rabbitmqctl start_app

5) Now, run the following commands in the master node:

$ rabbitmqctl stop_app$ rabbitmqctl reset

6) Do not start the app yet.

Open port 4369 and 25672: lokkit -p 4369:tcp -p 25672:tcp

Stop the iptables on both master and slaves.

The following command is executed to join the slaves to the cluster:

$ rabbitmqctl join_cluster rabbit@slave1 rabbit@slave2

Update slave1 and slave2 with the hostnames/IP address of the slave nodes. You can add as many slave nodes as needed in the cluster.

7) Start master app in master machine

$ rabbitmqctl start_app

8) Check the cluster status from any node in the cluster:

$ rabbitmqctl cluster_status

9) In rabbitmq management console check if you can login with previous user and have all the previous settings in place.

If not create users by following command:

rabbitmqctl add_user <username> <password>

give admin rights:

rabbitmqctl set_user_tags <username> administrator

rabbitmqctl add_vhost /

Give vhost rights by:

rabbitmqctl set_permissions -p / <username> “.*” “.*” “.*”

10) Create ha mirroring by:

rabbitmqctl set_policy ha-all “” ‘{“ha-mode”:”all”,”ha-sync-mode”:”automatic”}’This will mirror all queues.

11) Now start iptables. You will have created rabbitmq HA cluster.

Linux ldconfig Command Examples

What is ldconfig?

ldconfig is used to create, udpate and remove symbolic links for the current shared libraries based on the lib directories present in the /etc/ld.so.conf

3 ldconfig Examples

1. Display current libraries from the cache

This displays the list of directories and the libraries that are stored in the current cache. In the following example, it indicates that there are 916 libraries found in the cache file /etc/ld.so.cache, and it lists all of them below.

# ldconfig -p | head -5
916 libs found in cache `/etc/ld.so.cache'
	libzephyr.so.4 (libc6) => /usr/lib/libzephyr.so.4
	libzbar.so.0 (libc6) => /usr/lib/libzbar.so.0
	libz.so.1 (libc6) => /lib/libz.so.1
	libz.so (libc6) => /usr/lib/libz.so

2. Display libraries from every directory

Scans all the directories, and prints the directory name, and all the links that are created under it.

# ldconfig -v | head
/usr/lib/mesa:
	libGL.so.1 -> libGL.so.1.2
/usr/lib/i686-linux-gnu:
	liblouis.so.2 -> liblouis.so.2.2.0
/usr/lib/alsa-lib:
	libasound_module_ctl_oss.so -> libasound_module_ctl_oss.so
	libasound_module_ctl_bluetooth.so -> libasound_module_ctl_bluetooth.so
	libasound_module_pcm_bluetooth.so -> libasound_module_pcm_bluetooth.so
	libasound_module_pcm_vdownmix.so -> libasound_module_pcm_vdownmix.so
	libasound_module_rate_speexrate.so -> libasound_module_rate_speexrate_medium.so

The /etc/ld.so.conf has an include statement, which indicates that all the *.conf file under /etc/ld.so.conf.d directory should be considered.

# cat /etc/ld.so.conf
include /etc/ld.so.conf.d/*.conf

As you see below, there are multiple *.conf file located under this ld.so.conf.d directory. All of these files will be used.

# ls -1 /etc/ld.so.conf.d/
GL.conf
i486-linux-gnu.conf
i686-linux-gnu.conf
libasound2.conf
libc.conf

Sometimes when you do ldconfig -v, you might get the following error. This is because the directory referred by some of the *.conf file located under /etc/ld.so.conf.d is not valid, and contains directory names that doesn’t exist.

/sbin/ldconfig.real: Can't stat /lib/i486-linux-gnu: No such file or directory
/sbin/ldconfig.real: Can't stat /usr/lib/i486-linux-gnu: No such file or directory
/sbin/ldconfig.real: Can't stat /lib/i686-linux-gnu: No such file or directory
/sbin/ldconfig.real: Can't stat /lib64: No such file or directory

Note: You can either ignore these error mesages are remove those *.conf files from the /etc/ld.so.conf.d directory.

3. Inform System about the New Libraries

If you’ve installed a new program by compiling it from source, you might want to inform the system about the new libraries.

For example, let us assume that you’ve installed a program called dummy, which has all it’s libraries under /opt/dummy/lib directory.

The following example will update the links using only the directory /opt/dummy/lib. This doesn’t rebuilt the links by processing the /etc/ld.so.conf file. Please note that this doesn’t rebuild the cache. It just updates the link.

# ldconfig -n /opt/dummy/lib

Instead of the above, you can also add the “/opt/dummy/lib” to /etc/ld.so.conf and do the following.

# vi /etc/ld.so.conf

# ldconfig

Syntax and Options

Syntax:

ldconfig [OPTION...]
Short Option Long Option Option Description
-v –verbose Indicates verbose mode. Prints current version number, name of each directory as it is scanned and links that are created.
-n Process the directories that are specified from the command line. This doesn’t process the regular /usr/lib and lib directories. This also doesn’t process directories specified in the /etc/ld.so.conf. This option implies -N.
-N This doesn’t rebuild the cache. Unless -X is also specified, links are still updated.
-X This doesn’t update the links. Unless -N is also specified, the cache is still rebuilt.
-f Use the specified config file instead of /etc/ld.so.conf.
-C Use the specified cache instead of /etc/ld.so.cache.
-r Change to and use root as the root directory.
-l This is library mode, which manually links individual libraries.
-p –print-cache Print the lists of directories and candidate libraries stored in the current cache.
-c FORMAT –format=FORMAT Uses FORMAT for the cache file. Valid values for FORMAT: old, new and compat. compat is the default value.
-i –ignore-aux-cache Ignore auxiliary cache file.
-? –help, –usage Display help
-V –version Display version number

An Easy Way to Hide Files and Directories in Linux

Do you occasionally share your Linux desktop machine with family members, friends or perhaps with colleagues at your workplace, then you have a reason to hide certain private files as well as folders or directories. The question is how can you do this?

In this tutorial, we will explain an easy and effective way to hide files and directories and view hidden files/directories in Linux from the terminal and GUI.

As we’ll see below, hiding files and directories in Linux is so simple.

How to Hide Files and Directories in Linux

To hide a file or directory from the terminal, simply append a dot . at the start of its name as follows using the mv command.

$ ls
$ mv mv sync.ffs_db .sync.ffs_db
$ ls

Hide File in Linux Terminal

Using GUI method, the same idea applies here, just rename the file by adding a . at the start of its name as shown below.

Hide File in Linux Using File Manager

Once you have renamed it, the file will still be seen, move out of the directory and open it again, it will be hidden thereafter.

How to View Hide Files and Directories in Linux

To view hidden files, run the ls command with the -a flag which enables viewing of all files in a directory or -al flag for long listing.

$ ls -a
OR
$ ls -al

View Hidden Files in Linux Terminal

From a GUI file manager, go to View and check the option Show Hidden Files to view hidden files or directories.

View Hidden File Using File Manager

How to Compress Files and Directories with a Password

In order to add a little security to your hidden files, you can compress them with a password and then hide them from a GUI file manager as follows.

Select the file or directory and right click on it, then choose Compress from the menu list, after seeing the compression preferences interface, click on “Other options” to get the password option as shown in the screenshot below.

Once you have set the password, click on Create.

Compress Files with Password in Linux

From now on, each time anyone wants to open the file, they’ll be asked to provide the password created above.

Enter Password to View Files

Now you can hide the file by renaming it with a . as we explained before.

pyDash – A Web Based Linux Performance Monitoring Tool

pydash is a lightweight web-based monitoring tool for Linux written in Python and Django plus Chart.js. It has been tested and can run on the following mainstream Linux distributions: CentOS, Fedora, Ubuntu, Debian, Arch Linux, Raspbian as well as Pidora.

You can use it to keep an eye on your Linux PC/server resources such as CPUs, RAM, network stats, processes including online users and more. The dashboard is developed entirely using Python libraries provided in the main Python distribution, therefore it has a few dependencies; you don’t need to install many packages or libraries to run it.

In this article, we will show you how to install pydash to monitor Linux server performance.

How to Install pyDash in Linux System

1. First install required packages: git and Python pip as follows:

-------------- On Debian/Ubuntu -------------- 
$ sudo apt-get install git python-pip
-------------- On CentOS/RHEL -------------- 
# yum install epel-release
# yum install git python-pip
-------------- On Fedora 22+ --------------
# dnf install git python-pip

2. If you have git and Python pip installed, next, install virtualenv which helps to deal with dependency issues for Python projects, as below:

# pip install virtualenv
OR
$ sudo pip install virtualenv

3. Now using git command, clone the pydash directory into your home directory like so:

# git clone https://github.com/k3oni/pydash.git
# cd pydash

4. Next, create a virtual environment for your project called pydashtest using the virtualenv command below.

$ virtualenv pydashtest #give a name for your virtual environment like pydashtest

Create Virtual Environment

Important: Take note the virtual environment’s bin directory path highlighted in the screenshot above, yours could be different depending on where you cloned the pydash folder.

5. Once you have created the virtual environment (pydashtest), you must activate it before using it as follows.

$ source /home/aaronkilik/pydash/pydashtest/bin/activate

Active Virtual Environment

From the screenshot above, you’ll note that the PS1 prompt changes indicating that your virtual environment has been activated and is ready for use.

6. Now install the pydash project requirements; if you are curious enough, view the contents of requirements.txt using the cat command and the install them using as shown below.

$ cat requirements.txt
$ pip install -r requirements.txt

7. Now move into the pydash directory containing settings.py or simple run the command below to open this file to change the SECRET_KEY to a custom value.

$ vi pydash/settings.py

Set Secret Key

Save the file and exit.

8. Afterward, run the django command below to create the project database and install Django’s auth system and create a project super user.

$ python manage.py syncdb

Answer the questions below according to your scenario:

Would you like to create one now? (yes/no): yes
Username (leave blank to use 'root'): admin
Email address: aaronkilik@gmail.com
Password: ###########
Password (again): ############

Create Project Database

9. At this point, all should be set, now run the following command to start the Django development server.

$ python manage.py runserver

10. Next, open your web browser and type the URL: http://127.0.0.1:8000/ to get the web dashboard login interface. Enter the super user name and password you created while creating the database and installing Django’s auth system in step 8 and click Sign In.

pyDash Login Interface

11. Once you login into pydash main interface, you will get a section for monitoring general system info, CPU, memory and disk usage together with system load average.

Simply scroll down to view more sections.

pyDash Server Performance Overview

12. Next, screenshot of the pydash showing a section for keeping track of interfaces, IP addresses, Internet traffic, disk read/writes, online users and netstats.

pyDash Network Overview

13. Next is a screenshot of the pydash main interface showing a section to keep an eye on active processes on the system.

pyDash Active Linux Processes

fswatch – Monitors Files and Directory Changes or Modifications in Linux

fswatch is a cross-platform, file change monitor that gets notification alerts when the contents of the specified files or directories are altered or modified.

It executes four types of monitors on different operating systems such as:

  1. A monitor build on the File System Events API of Apple OS X.
  2. A monitor based on kqueue, a notification interface present in FreeBSD 4.1 also supported on many *BSD systems, OS X inclusive.
  3. A monitor based on File Events Notification API of the Solaris kernel plus its spin-offs.
  4. A monitor based on inotify, a kernel subsystem that shows file system modifications to apps.
  5. A monitor based on ReadDirectoryChangesW, a Windows API that records alters to a directory.
  6. A monitor that regularly check that status of file system, keeps file modification times in memory, and manually determine file system changes (which works anywhere, where stat can be used).

Features of fswatch

  1. Supports several OS-specific APIs
  2. Allows recursive directory monitoring
  3. Performs path filtering using including and excluding regular expressions
  4. Supports customizable record format
  5. Additionally, it supports periodic idle events

How To Install fswatch in Linux Systems

Unfortunately, fswatch package is not available to install from the default system repositories in any Linux distributions. The only way to install the latest version of fswatch is to build from source tarball as show in the following installation instructions.

First grab the latest fswatch tarball using following wget command and install it as shown:

$ wget https://github.com/emcrisostomo/fswatch/releases/download/1.9.3/fswatch-1.9.3.tar.gz
$ tar -xvzf fswatch-1.9.3.tar.gz
$ cd fswatch-1.9.3
$ ./configure
$ make
$ sudo make install 

Important: Make sure you’ve GNU GCC (C and C++ Compiler) and Development Tools (build-essential on Debian/Ubuntu) installed on the system, before you compile fswatch from source. If not, install it using following command on your respective Linux distributions..

# yum group install 'Development Tools'		[On CentOS/RHEL]
# dnf group install 'Development Tools'		[On Fedora 22+ Versions]
$ sudo apt-get install build-essential          [On Debian/Ubuntu Versions]

On Debian/Ubuntu distributions, you might get following error while executing fswatch command..

fswatch: error while loading shared libraries: libfswatch.so.6: cannot open shared object file: No such file or directory

To fix it, you need to execute the command below, this will help refresh the links and cache to the dynamic libraries before you can start using fswatch.

$ sudo ldconfig

How do I use fswatch on Linux?

The general syntax for running fswatch is:

$ fswatch [option] [path]

On Linux, it is recommended that you use the default inotify monitor, you can list available monitors by employing the -M or - list-monitors option:

$ fswatch -M
$ fswatch --list-monitors

fswatch - List Monitors

The command below enables you to watch the changes in the current directory (/home/tecmint), with events being delivered to standard output every 4 seconds.

The -l or –-latency option allows you to set the latency in seconds, the default being 1 second.

$ fswatch -l 4 .

fswatch - Monitor Home Directory Changes

The next command monitors changes to the /var/log/auth.log file every 5 seconds:

$ fswatch -l 5 /var/log/auth.log

Using -t or --timestamp option prints the time stamp for every event, to print the time in UTC format, employ -u or --utf-time option. You can as well format time using -f or --format-time format option:

$ fswatch --timestamp /var/log/auth.log

Next, -x or --event-flags tells fswatch to print the event flags along side the event path. You can use –event-field-seperator option to print events using the particular separator.

$ fswatch --events-flags ~ /var/log/auth.log

To print the numeric value of an event indicating changes in your home directory and /var/log/auth.log file, use -n or --numeric option as below:

$ fswatch --numeric ~ /var/log/auth.log 

Perhaps you can look through the fswatch man page for detailed usage options and information:

$ man fswatch

Pyinotify – Monitor Filesystem Changes in Real-Time in Linux

Pyinotify is a simple yet useful Python module for monitoring filesystems changes in real-time in Linux.

As a System administrator, you can use it to monitor changes happening to a directory of interest such as web directory or application data storage directory and beyond.

It depends on inotify (a Linux kernel feature incorporated in kernel 2.6.13), which is an event-driven notifier, its notifications are exported from kernel space to user space via three system calls.

The purpose of pyinotify is to bind the three system calls, and support an implementation on top of them providing a common and abstract means to manipulate those functionalities.

In this article, we will show you how to install and use pyinotify in Linux to monitor filesystem changes or modifications in real-time.

Dependencies

In order to use pyinotify, your system must be running:

  1. Linux kernel 2.6.13 or higher
  2. Python 2.4 or higher

How to Install Pyinotify in Linux

First start by checking the kernel and Python versions installed on your system as follows:

# uname -r 
# python -V

Once dependencies are met, we will use pip to install pynotify. In most Linux distributions, Pip is already installed if you’re using Python 2 >=2.7.9 or Python 3 >=3.4 binaries downloaded from python.org, otherwise, install it as follows:

# yum install python-pip      [On CentOS based Distros]
# apt-get install python-pip  [On Debian based Distros]
# dnf install python-pip      [On Fedora 22+]

Now, install pyinotify like so:

# pip install pyinotify

It will install available version from the default repository, if you are looking to have a latest stable version of pyinotify, consider cloning it’s git repository as shown.

# git clone https://github.com/seb-m/pyinotify.git
# cd pyinotify/
# ls
# python setup.py install

How to Use pyinotify in Linux

In the example below, I am monitoring any changes to the user tecmint’s home (/home/tecmint) directory as root user (logged in via ssh) as shown in the screenshot:

# python -m pyinotify -v /home/tecmint

Monitor Directory Changes

Next, we will keep a watch for any changes to the web directory (/var/www/html/tecmint.com):

# python -m pyinotify -v /var/www/html/tecmint.com

To exit the program, simply hit [Ctrl+C].

Note: When you run pyinotify without specifying any directory to monitor, the /tmp directory is considered by default.

How to Trace Execution of Commands in Shell Script with Shell Tracing

In this article of the shell script debugging series, we will explain the third shell script debugging mode, that is shell tracing and look at some examples to demonstrate how it works, and how it can be used.

The previous part of this series clearly throws light upon the two other shell script debugging modes: verbose mode and syntax checking mode with easy-to-understand examples of how to enable shell script debugging in these modes.

Shell tracing simply means tracing the execution of the commands in a shell script. To switch on shell tracing, use the -x debugging option.

This directs the shell to display all commands and their arguments on the terminal as they are executed.

We will use the sys_info.sh shell script below, which briefly prints your system date and time, number of users logged in and the system uptime. However, it contains syntax errors that we need to find and correct.

#!/bin/bash
#script to print brief system info
ROOT_ID="0"
DATE=`date`
NO_USERS=`who | wc -l`
UPTIME=`uptime`
check_root(){
if [ "$UID" -ne "$ROOT_ID" ]; then
echo "You are not allowed to execute this program!"
exit 1;    
}
print_sys_info(){
echo "System Time    : $DATE"
echo "Number of users: $NO_USERS"
echo "System Uptime  : $UPTIME
}
check_root
print_sys_info
exit 0

Save the file and make the script executable. The script can only be run by root, therefore employ the sudo command to run it as below:

$ chmod +x sys_info.sh
$ sudo bash -x sys_info.sh

Shell Tracing - Show Error in Script

From the output above, we can observe that, a command is first executed before its output is substituted as the value of a variable.

For example, the date was first executed and the its output was substituted as the value of the variable DATE.

We can perform syntax checking to only display the syntax errors as follows:

$ sudo bash -n sys_info.sh 

Syntax Checking in Script

If we look at the shell script critically, we will realize that the if statement is missing a closing fi word. Therefore, let us add it and the new script should now look like below:

#!/bin/bash
#script to print brief system info
ROOT_ID="0"
DATE=`date`
NO_USERS=`who | wc -l`
UPTIME=`uptime`
check_root(){
if [ "$UID" -ne "$ROOT_ID" ]; then
echo "You are not allowed to execute this program!"
exit 1;
fi    
}
print_sys_info(){
echo "System Time    : $DATE"
echo "Number of users: $NO_USERS"
echo "System Uptime  : $UPTIME
}
check_root
print_sys_info
exit 0

Save the file again and invoke it as root and do some syntax checking:

$ sudo bash -n sys_info.sh

Perform Syntax Check in Shell Scripts

The result of our syntax checking operation above still shows that there is one more bug in our script on line 21. So, we still have some syntax correction to do.

If we look through the script analytically one more time, the error on line 21 is due to a missing closing double quote (”) in the last echo command inside the print_sys_info function.

We will add the closing double quote in the echo command and save the file. The changed script is below:

#!/bin/bash
#script to print brief system info
ROOT_ID="0"
DATE=`date`
NO_USERS=`who | wc -l`
UPTIME=`uptime`
check_root(){
if [ "$UID" -ne "$ROOT_ID" ]; then
echo "You are not allowed to execute this program!"
exit 1;
fi
}
print_sys_info(){
echo "System Time    : $DATE"
echo "Number of users: $NO_USERS"
echo "System Uptime  : $UPTIME"
}
check_root
print_sys_info
exit 0

Now syntactically check the script one more time.

$ sudo bash -n sys_info.sh

The command above will not produce any output because our script is now syntactically correct. We can as well trace the execution of the script all for a second time and it should work well:

$ sudo bash -x sys_info.sh

Trace Shell Script Execution

Now run the script.

$ sudo ./sys_info.sh

Shell Script to Show Date, Time and Uptime

Importance of Shell Script Execution Tracing

Shell script tracing helps us identify syntax errors and more importantly, logical errors. Take for instance the check_root function in the sys_info.sh shell script, which is intended to determine if a user is root or not, since the script is only allowed to be executed by the superuser.

check_root(){
if [ "$UID" -ne "$ROOT_ID" ]; then
echo "You are not allowed to execute this program!"
exit 1;
fi
}

The magic here is controlled by the if statement expression [ "$UID" -ne "$ROOT_ID" ], once we do not use the suitable numerical operator (-ne in this case, which means not equal ), we end up with a possible logical error.

Assuming that we used -eq ( means equal to), this would permit any system user as well as the root user to run the script, hence a logical error.

check_root(){
if [ "$UID" -eq "$ROOT_ID" ]; then
echo "You are not allowed to execute this program!"
exit 1;
fi
}

Note: As we looked at before at the start of this series, the set shell built-in command can activate debugging in a particular section of a shell script.

Therefore, the line below will help us find this logical error in the function by tracing its execution:

The script with a logical error:

#!/bin/bash
#script to print brief system info
ROOT_ID="0"
DATE=`date`
NO_USERS=`who | wc -l`
UPTIME=`uptime`
check_root(){
if [ "$UID" -eq "$ROOT_ID" ]; then
echo "You are not allowed to execute this program!"
exit 1;
fi
}
print_sys_info(){
echo "System Time    : $DATE"
echo "Number of users: $NO_USERS"
echo "System Uptime  : $UPTIME"
}
#turning on and off debugging of check_root function
set -x ; check_root;  set +x ;
print_sys_info
exit 0

Save the file and invoke the script, we can see that a regular system user can run the script without sudo as in the output below. This is because the value of USER_ID is 100 which is not equal to root ROOT_ID which is 0.

$ ./sys_info.sh

Run Shell Script Without Sudo