Bash Shell Scripting - Basics

Working with text

1. Read a CSV file line by line and extract specific filed, and store it in a variable.
file_name="data.csv"
while read line
do
field1=$(echo -e $line | gawk -F, '{ print $1}')
field2=$(echo -e $line | gawk -F, '{ print $2}')
done < $file_name

2. Find and repace a string in a file.
sed -i 's/foo/bar/g' file.txt

Arithematic Operations
1. Increment a variable
count=$((count+1))

2. Decrement a variable
count=$((count-1))

Working with date and time
1. Get current date in yy-mm-dd format.
current_date="`date +%y-%m-%d`"
echo $current_date

2. Get backup time stamp in yymmdd-hhmmss format and store it in a variable.
bkptime=("`date +%y%m%d-%H%M%S`")

3. Get yesterday's date in yyyy-mm-dd format.
yesterday_date="`date --date=yesterday +%Y/%m/%d`"
echo $yesterday_date

3. Get 10 days old date in yyyy-mm-dd format.
day=("`date --date=\"10 day ago\" +%Y-%m-%d`")

OR

daysold=10
day=("`date --date=\"$daysold day ago\" +%Y-%m-%d`")

4. Get last day of the month
To get last day of current month:
date -d "-$(date +%d) days 1 month" +%Y-%m-%d

To get last day of last month:
date -d "-$(date +%d) days 0 month" +%Y-%m-%d

To get last day of last before month
date -d "-$(date +%d) days -1 month" +%Y-%m-%d

To get last day of next month
date -d "-$(date +%d) days 2 month" +%Y-%m-%d

To get last day of next to next month
date -d "-$(date +%d) days 3 month" +%Y-%m-%d

If conditions

1. Check a vriable is having some value (it is non-zero)
if [ ! -z "$var" ]; then
     echo "Variable value is $val"
else
     echo "Variable has no value"
fi

2. Check if file exist
if [  -e "$file.csv" ]; then
     echo "File exist"
fi

3. Check if doesn't file exist
if [ !  -e "$file.csv" ]; then
     echo "File exist"
fi

4. Check if previously executed command is successful or not. If not successful exit from loop.
ssconvert "file.xls" "file.csv"
if [ "$?" == "0" ]; then
      echo "File converted successfully.."
else
exit
fi

Working with files

1. Covert EXCEL(.xls) file to CSV file.
ssconvert "file.xls" "file.csv"

2. Compress a directory using 7zip.
/usr/bin/7z a reportdir.7z reportdir > /dev/null

3. Upload a directory and its content to an FTP location
ftp_server="ftp.mydomain.com"
ftp_bkp_username="myusername"
ftp_bkp_password="mypassword"
FTP Over TLS
lftp -c "open -e \"set ftps:initial-prot \"\"; set ftp:ssl-force true; set ftp:ssl-protect-data true; mirror -R mydir; \" -u \"$ftp_bkp_username\",\"$ftp_bkp_password\" ftp://$ftp_server/mypath/"
FTP (without TLS)
ncftpput –R -u $ftp_bkp_username -p $ftp_bkp_password $ftp_server mypath mydir

4. Upload a file to an FTP location.
ftp_server="ftp.mydomain.com"
ftp_bkp_username="myusername"
ftp_bkp_password="mypassword"
FTP Over TLS
lftp -c "open -e \"set ftps:initial-prot \"\"; set ftp:ssl-force true; set ftp:ssl-protect-data true; put myfile; \" -u \"$ftp_bkp_username\",\"$ftp_bkp_password\" ftp://$ftp_server/mypath/"
FTP (without TLS)
ncftpput -u $ftp_bkp_username -p $ftp_bkp_password $ftp_server mypath myfile

5. Create an empty directory in an FTP location over TLS.
ftp_server="ftp.mydomain.com"
ftp_bkp_username="myusername"
ftp_bkp_password="mypassword"
lftp -c "open -e \"set ftps:initial-prot \"\"; set ftp:ssl-force true; set ftp:ssl-protect-data true; put myemptydir; \" -u \"$ftp_bkp_username\",\"$ftp_bkp_password\" ftp://$ftp_server/mypath/"


Working with user input
1. Read input from user.
echo -n "Enter date for processing data (yyyy/mm/dd) : "
read given_date
echo "You have entered $given_date"

Working with MySQL statements
1. Change a MySQL environment variable.
 db.cnf
[client]
user = root
password = mypassword
host = localhost

mysql --defaults-extra-file=db.cnf  -e "set global general_log='ON';"

2. Get the pids of sleeping MySQL connections and kill them whose sleep time is more than 100 sec.
sleeptime=100
/usr/bin/mysql -N -h $host -p$password -u $username -e "select id from information_schema.processlist where command='Sleep' and time > $sleeptime;" > kill_ids
while read id
do
/usr/bin/mysqladmin -h $host -p$password -u $username kill $id
done < kill_ids
rm -f kill_ids

3. Various options used while taking MySQL DB backup
/usr/bin/mysqldump -h $host --no-data  --routines -p$password -u $username $database > $database-Schema_only.sql
/usr/bin/mysqldump -h $host -p$password -u $username $database  --no-create-db --no-create-info --ignore-table=$database.cdrdetails --ignore-table=$database.clientsummary > $database-without_CDR_Data_tables.sql
--no-data Ã  Do not write any table row information i.e structure only
--routines Ã  Dump stored routines (procedures and functions)
--no-create-db Ã  Do not write CREATE DATABASE statements
--ignore-table=db_name.tbl_name Ã  Do not dump given table
--skip-add-drop-table Ã  Do not add a DROP TABLE statement before each CREATE TABLE statement

Sending Mail
1. Send mail with body text stored in a file.
message.txt
Hi
  Some text here
Thanks & Regards
xxxxxxxxxxxxx

mail -s "Log Rotation Failed" abc@xyz.com < message.txt

2. Send mail with attachment.
mail -a Report.txt -s "Log Rotation Failed" abc@xyz.com < message.txt

3. Send a mail with Cc
mail -a Report.txt -s "Log Rotation Failed" -c id@domain.com abc@xyz.com < message.txt

Working across multiple scripts
  1. There will be situations, where multiple scripts dependent on same data. Such data can be stored in one script, and can be exported to multiple scripts. This will help us in managing the data centrally that changes time to time.
00_CONFIG.sh
#!/bin/bash
host="192.168.10.23"
export host

database=mydbname
export database

port=3306
export port

serverids="1 2 3 4 5 6 7 8 9 10"
export serverids

recenthours="3 2 1"
export recenthours

mysql_username="myuserid"
export mysql_username

mysql_password="mypassword"
export mysql_password

01_DAILY DATA_VERIFY.sh
#!/bin/bash
source 00_CONFIG.sh

for id in `echo $serverids`
do
..................
..................
done

02_DAILY DATA_BACKUP.sh
#!/bin/bash
source 00_CONFIG.sh

for id in `echo $serverids`
do
..................
..................
done

03_DAILY DATA_DELETE.sh
#!/bin/bash
source 00_CONFIG.sh

for id in `echo $serverids`
do
..................
..................
done

Important Note: The above example will work when you run scripts manually in shell. In case if you want to schedule the jobs using crontab, you need to declare those variables (CONFIG.sh) in cron environment. In this case it looks like this.
# crontab -e 
host="192.168.10.23"
database=mydbname
port=3306
serverids="1 2 3 4 5 6 7 8 9 10"
recenthours="3 2 1"
mysql_username="myuserid"
mysql_password="mypassword"
30    5     *    *     *    /mypath_to_scripts/01_DAILY DATA_VERIFY.sh
59    23     *    *     *    /mypath_to_scripts/01_DAILY DATA_BACKUP.sh

Vsftpd Response :550 Permission denied.

Hello,

After installing vsftpd you may receive error as

Response:550 Permission denied.


Thats because you havent enabled write permission in your vsftpd.conf file.

in Ubuntu edit ,
/etc/vsftpd.conf
file and make sure you have uncommented 
write_enable=YES
.

in CentOS/RHEL,
/etc/vsftpd.conf
file and make sure you have uncommented
write_enable=YES


Hope it helps.

Thank you.



Installing Chef server in your CentOS 6.7 easily.

I have tried to install chef in my CentOS 6.7 but it was like complicated thing till today.

So many problems I have faced and I am giving them as precautions to you.

1. You should have minimum 1 Mbps unlimited connection. Atleast 5 GB data you are going to download.

2. Always you have to choose your current OS version builds, If you choose other version builds you will be stopped with library issues.

3. Atleast 6 - 7 GB of freespace

and Lot of patience.

I will give you in a simple way. Just open your terminal and turn into root user if you were not.

Then Download files from below links. Open them via browser and get the final link and download in your way.

1. https://packagecloud.io/chef/stable/packages/el/6/chef-server-core-12.3.1-1.el6.x86_64.rpm/download

2.https://packagecloud.io/chef/stable/packages/el/6/opscode-reporting-1.5.5-1.el6.x86_64.rpm/download

3.https://packagecloud.io/chef/stable/packages/el/6/opscode-push-jobs-server-1.1.6-1.x86_64.rpm/download

4.https://web-dl.packagecloud.io/chef/stable/packages/el/6/chef-sync-1.0.0~rc.7-1.el6.x86_64.rpm

5. https://packagecloud.io/chef/stable/packages/el/6/chef-manage-2.1.1-1.el6.x86_64.rpm/download

6. https://opscode-omnibus-packages.s3.amazonaws.com/el/6/x86_64/chefdk-0.10.0-1.el6.x86_64.rpm


After download all these files place them in any directory.

Now let us assume these files are in /home/mypc/chef directory.


Step 1:

rpm -ivh chef-server-core-12.3.1-1.el6.x86_64.rpm

chef-server-ctl reconfigure

chef-server-ctl user-create rajachef Raja G raja@myserver.com  abc123 --filename /home/virt01/userkey.pem

Original Syntax : $ chef-server-ctl user-create user_name first_name last_name email password --filename FILE_NAME

chef-server-ctl org-create virt02 "virt02.myserver.com." --association_user virt02 --filename /home/virt02/virt02-validator.pem

Original Syntax: $ chef-server-ctl org-create short_name "full_organization_name" --association_user user_name --filename ORGANIZATION-validator.pem

Step 2: 


chef-server-ctl install opscode-manage --path /home/mypc/chef/chef-manage-2.1.1-1.el6.x86_64.rpm

chef-server-ctl reconfigure

opscode-manage-ctl reconfigure

Step 3: 

chef-server-ctl install opscode-push-jobs-server --path /home/mypc/chef/opscode-push-jobs-server-1.1.6-1.x86_64.rpm

chef-server-ctl reconfigure

opscode-push-jobs-server-ctl reconfigure

Step 4:

chef-server-ctl install chef-sync --path /home/mypc/chef/chef-sync-1.0.0~rc.7-1.el6.x86_64.rpm

chef-server-ctl reconfigure

chef-sync-ctl reconfigure

Step 5: 


chef-server-ctl install opscode-reporting --path /home/mypc/chef/ opscode-reporting-1.5.5-1.el6.x86_64.rpm

chef-server-ctl reconfigure

opscode-reporting-ctl reconfigure

Step 6:


And now install Chef Development Kit.

rpm -ivh chefdk-0.10.0-1.el6.x86_64.rpm

That's it chef server successfully installed in your system. To access chef , just open your browser and type localhost or IP of your PC. And you will get Login page and login with those credentials given initially at Step 1. 

If you are facing any issues please dont hesitate to ask. 

Thank you.

Regards
Raja





Extract log efficiently by using sed

Modification of Log pulling command by using sed

Old command That I use to do log extraction

sed -nre '/12:23:12/,/12:24:12/ p' logfile > /tmp/somelog.txt

But this will take match of given two time stamps at any where in log file.And sometimes from middle of the line which gives obviously wrong log that I need.

So , Now we are modifying sed to look after only at lines starting with timestamp.
It will pull the logs if timestamp exists at beginning of the lines else It wont pull any log.

sed -nre '/^12:23:12/,/^12:24:12/ p' logfile > /tmp/somelog.txt

Note: If you want to make sure that given timestamp existed or not at line starting
you can use

grep -m 5 12:23:12 server.log

The above command ran for 5 first matching of grep and so you can conclude the availability of
given time-stamp in logfile.

For more information please refer sed man page

Hope it will help you.


Reset Gnome 2 panel to default applets

If you ever accidentally remove your Gnome Panel in any Gnome 2.X default DE Linux then,  you can reset it to default with

mv ~/.gconf/apps/panel ~/.gconf/apps/panel.bak

Now restart your Linux and re login. Your gnome panel will be back 🔙.

Hope it helps you.

Changing hostname in CentOS ,Redhat Linux OS

Hello ,

Today lets see an article about changing hostname in CentOS and Redhat.

We have to change hostname in 3 locations to apply changes globally in all locations. 
Configuration filenames :

    

1. /etc/sysconfig/network
2. /etc/hosts
3. hostname command 

1. Open /etc/sysconfig/network with any editor.
           
                                     
# vim /etc/sysconfig/network


And write/modify line as

                                   
HOSTNAME=


Ex: HOSTNAME=centos.virt02.com

close and save file.

2. Open /etc/hosts file  and add as
   

                               
                                # vim /etc/hosts

and add as
                           
192.168.56.101 centos.virt02.com centos


close and save file.

3. Now type command hostname to see current hostname . To assign new hostname

                                 
# hostname=centos.virt02.com



after doing all those steps , restart network with
service network restart


Hope it will help you.

Summary :

[root@localhost Tools]# cat /etc/sysconfig/network
NETWORKING=yes
NETWORKING_IPV6=no
HOSTNAME=centos.virt02.com
[root@localhost Tools]# cat /etc/hosts
127.0.0.1               localhost.localdomain localhost
::1             localhost6.localdomain6 localhost6
192.168.56.101 centos.virt02.com centos
[root@localhost Tools]# hostname
centos.virt02.com
[root@localhost Tools]#


How to avoid ambiguous redirect error in Bash ?

Hello ,

Today I was trying to take Threaddump for my Java process in single command with date and hostname like this

$ jstack -l `pgrep java` > /tmp/TD_`hostname`_`date`_`pgrep java`

But I am getting error like 

-bash: /tmp/TD_`hostname`_`date`_`pgrep java`: ambiguous redirect

Then I posted at  unix.stackexchange.com and a friend named Muru helped me in fixing that issue with very simple way


$ echo foo > /tmp/TD_`hostname`_`date`_`pgrep java`
bash: /tmp/TD_`hostname`_`date`_`pgrep java`: ambiguous redirect
$ echo foo > /tmp/"TD_`hostname`_`date`_`pgrep java`"
$ ls /tmp/TD*

/tmp/TD_muru-arch_Sat 26 Dec 16:14:29 IST 2015

Summary : Command jstack -l `pgrep java` > /tmp/TD_`hostname`_`date`_`pgrep java` is wrong 

and right way of using this is jstack -l `pgrep java` > /tmp/"TD_`hostname`_`date`_`pgrep java` "


Hope it will help you.