Accesing remote server in linux using bash script - bash

n=rijotests143.revsw.net
echo $n
me=$(echo $n | sed 's/"/ /g')
echo $me
u=$(echo $me | sed 's/\./\_/g')
echo $u
ssh -i m_bp.pem ubuntu#95.68.74.51 'bash -s' < domain_delbp.sh
I am getting accessed to the remote server and passing values in domain_delbp.sh file. In this i need to pass a value of $u in domain_delbp.sh and need to execute the command
cat /opt/rijo/var/$u.json
Please help me

You can simply parse the value to the script and in the script you can access that value as $1 variable.
n=rijotests143.revsw.net
echo $n me=$(echo $n | sed 's/"/ /g')
echo $me u=$(echo $me | sed 's/./_/g')
echo $u
ssh -i m_bp.pem ubuntu#95.68.74.51 'bash -s' < domain_delbp.sh $u

Related

Bash Script can run php script manually but cannot work in Cron

I have a bash script like this:
#!/bin/bash
log_file=/home/michael/bash/test.log
checkalive=checkalive.php
#declare
needRestart=0
#Check checkalive.php
is_checkalive=`ps aux | grep -v grep| grep -v "$0" | grep $checkalive| wc -l | awk '{print $1}'`
if [ $is_checkalive != "0" ] ;
then
checkaliveId=$(ps -ef | grep $checkalive | grep -v 'grep' | awk '{ printf $2 }')
echo "Service $checkalive is running. $checkaliveId"
else
echo "$checkalive OFF"
needRestart=1
fi
#NEED needRestart
if [ $needRestart == "1" ];
then
#START SERVICE
echo "Restarting services..."
/usr/bin/php5.6 /home/michael/bash/$checkalive >/dev/null 2>&1 &
echo "$checkalive..."
echo `date '+%Y-%m-%d %H:%M:%S'` " Start /home/michael/bash/$checkalive" >> $log_file
fi
I can run it manually but when I try to run it in Cron, it doesn't work for some reasons. Apparently the command:
/usr/bin/php5.6 /home/michael/bash/$checkalive >/dev/null 2>&1 &
does not work.
All of file permissions are already set to executable. Any advice?
Thank you
You have run into one of cron's most common mistakes, trying to use it like an arbitrary shell script. Cron is not a shell script and you can't do everything you can do in one, like dereferencing variables or setting arbitrary new variables.
I suggest you replace your values into the cron line and avoid usage of variables
/usr/bin/php5.6 /home/michael/bash/checkalive.php >/dev/null 2>&1 &
Also, consider removing the trailing & as it is not necessary.

Unix Shell Scripting - Add Extra Column In While Loop

I have a file server.txt containing different hostnames like:
hostname1.com
hostname2.com
My shell script servers.sh is written to get the /etc/passwd and /etc/group files from the list in servers.txt file.
I wish to add the hostname from which the entries came from in my final output file. My script looks something like below:
while read HOST ;
do
sshpass -p $password ssh -n $username#$HOST 'cat /etc/passwd'>>users.txt
sshpass -p $password ssh -n $username#$HOST 'cat /etc/group'>>groups.txt
done < servers.txt
echo -e "UserName;UID;GID;HomeDir;Shell" > final_users.csv
cut -d: -f1,3,4,6,7 users.txt | tr ':' ';'>> final_users.csv
echo -e "GroupName;GID;Members" > final_groups.csv
awk -F '[:,]' '{for(i=4;i<=NF;i++)print$1";"$3";"$i}' groups.txt >> final_groups.csv
The goal is to add another column in both final_users.csv and final_groups.csv like hostname so I can know which servers each entry came from.
Try like this:
while read HOST ;
do
sshpass -p $password ssh -n $username#$HOST 'cat /etc/passwd'>>users.txt
sshpass -p $password ssh -n $username#$HOST 'cat /etc/group'>>groups.txt
done < servers.txt
echo -e "UserName;UID;GID;HomeDir;Shell;Hostname" > final_users.csv
echo "`cut -d: -f1,3,4,6,7 users.txt | tr ':' ';'`;$HOST">> final_users.csv
echo -e "GroupName;GID;Members;Hostname" > final_groups.csv
echo "`awk -F '[:,]' '{for(i=4;i<=NF;i++)print$1";"$3";"$i}' groups.txt`;$HOST" >> final_groups.csv
Think I got it:
while read HOST ;
do
sshpass -p $password ssh -n $username#$HOST 'cat /etc/passwd'>>users_1.txt
while IFS= read -r line; do echo "$line:"$HOST; done < users_1.txt >> users_2.txt
sshpass -p $password ssh -n $username#$HOST 'cat /etc/group'>>groups_1.txt
while IFS= read -r line; do echo "$line:"$HOST; done < groups_1.txt >> groups_2.txt
done < servers.txt
echo -e "UserName;UID;GID;HomeDir;Shell;Hostname" > final_users.csv
cut -d: -f1,3,4,6,7,8 users_2.txt | tr ':' ';'>> final_users.csv
echo -e "GroupName;GID;Members;Hostname" > final_groups.csv
awk -F'[:,]' -v OFS=';' '{for(i=4;i<NF;i++) print $1, $3, $i, $NF}' groups_2.txt >> final_groups.csv

shell script not working through cron but manually

I'm using below command in a shell script:
echo "1" > log.txt
if [ `ifconfig eth0 | grep 'inet addr' | cut -d ":" -f 2 |
awk {'print $1'}` = 'ipaddress' ] && [ `whoami` = 'userid' ]; then
echo "2" >> log.txt
crontab -l > Cron.txt
echo "3" >> log.txt
fi
The script runs fine when run manually but when scheduled through cron, it
stucks at this IF.
cron entry: 31 11 * * * /home/abc/cron_backup.sh
Output in log.txt Manual run: prints 1,2,3 in log.txt through
cron: prints 1 in log.txt
I would suggest to put as first line of your script the command interpreter line #! to make sure that sh will run it
after that, have you consider to use double bracket syntax [[ ]]?
#!/bin/sh
echo "1" > log.txt
if [[ `ifconfig eth0 | grep 'inet addr' | cut -d ":" -f 2 |
awk {'print $1'}` = 'ipaddress' ]] && [[ `whoami` = 'userid' ]]; then
echo "2" >> log.txt
crontab -l > Cron.txt
echo "3" >> log.txt
fi
The problem could be with the ifconfig, grep, cut awk and whoami calls. When you run it from the command line you have your profile, which has your PATH setting.
When it is run from cron, it does not have your profile. If you modify your PATH variable to point to the location of these programs then you wouldn't have that change when run from cron.
Try putting in the full path for the each of the commands and see it that makes any difference when run from cron.

ssh instruction interrupt a while cycle?

I'm trying to deploy a cluster with a script which uses a yaml file. Except for an entry called "RaftFS" each yaml entry represents a machine to deploy. I don't understand why the script does only one while cycle if the ssh command is executed (even if the command is a simple ls !) but if I delete it then everything is fine and it does a number of cycle equals to the number of machines defined in the yaml file!
cat RaftFS/servers.yaml | shyaml keys-0 |
while read -r -d $'\0' value; do
if [ ! $value == "RaftArgs" ]; then
address=$(cat RaftFS/servers.yaml | shyaml get-value $value.machineIP | xargs -0 -n 1 echo)
username=$(cat RaftFS/servers.yaml | shyaml get-value $value.username | xargs -0 -n 1 echo)
password=$(cat RaftFS/servers.yaml | shyaml get-value $value.password | xargs -0 -n 1 echo)
#uploading my fingerprint (in order to use pssh)
echo $address $username $password
echo "uploading my fingerprint on $username#$address $password"
sshpass -p $password ssh-copy-id -oStrictHostKeyChecking=no $username#$address
echo "creating RaftFS"
ssh $username#$address echo "MACHINE=$value vagrant up">>vagrantscript.sh
fi
echo $address $username $password
done
I think there is no issue with the ssh command but it is a delimiter's issue
I've played a little with read -r -d $'\0' and these are the results
echo "a\0b\0c" | while read -r -d $'\0' var; do echo $var; done
prints
a
b
and
echo "a\0b\0c\0" | while read -r -d $'\0' var; do echo $var; done
prints
a
b
c
I assume there is some difference in the end line when the $value == "RaftArgs"
The standard input to the while loop is also the standard input to every command within the while loop. ssh reads from standard input in order to pipe the data to the remote command. It's probably consuming the data intended for the read statement.
You can redirect the ssh command's input:
ssh $username#$address ... >>vagrantscript.sh < /dev/null
Or you can run ssh with the "-n" flag to prevent reading from stdin:
ssh -n $username#$address ... >>vagrantscript.sh

Bash - output of command seems to be an integer but "[" complains

I am checking to see if a process on a remote server has been killed. The code I'm using is:
if [ `ssh -t -t -i id_dsa headless#remoteserver.com "ps -auxwww |grep pipeline| wc -l" | sed -e 's/^[ \t]*//'` -lt 3 ]
then
echo "PIPELINE STOPPED SUCCESSFULLY"
exit 0
else
echo "PIPELINE WAS NOT STOPPED SUCCESSFULLY"
exit 1
fi
However when I execute this I get:
: integer expression expected
PIPELINE WAS NOT STOPPED SUCCESSFULLY
1
The actual value returned is "1" with no whitespace. I checked that by:
vim <(ssh -t -t -i id_dsa headless#remoteserver.com "ps -auxwww |grep pipeline| wc -l" | sed -e 's/^[ \t]*//')
and then ":set list" which showed only the integer and a line feed as the returned value.
I'm at a loss here as to why this is not working.
If the output of the ssh command is truly just an integer preceded by optional tabs, then you shouldn't need the sed command; the shell will strip the leading and/or trailing whitespace as unnecessary before using it as an operand for the -lt operator.
if [ $(ssh -tti id_dsa headless#remoteserver.com "ps -auxwww | grep -c pipeline") -lt 3 ]; then
It is possible that result of the ssh is not the same when you run it manually as when it runs in the shell. You might try saving it in a variable so you can output it before testing it in your script:
result=$( ssh -tti id_dsa headless#remoteserver.com "ps -auxwww | grep -c pipeline" )
if [ $result -lt 3 ];
The return value you get is not entirely a digit. Maybe some shell-metacharacter/linefeed/whatever gets into your way here:
#!/bin/bash
var=$(ssh -t -t -i id_dsa headless#remoteserver.com "ps auxwww |grep -c pipeline")
echo $var
# just to prove my point here
# Remove all digits, and look wether there is a rest -> then its not integer
test -z "$var" -o -n "`echo $var | tr -d '[0-9]'`" && echo not-integer
# get out all the digits to use them for the arithmetic comparison
var2=$(grep -o "[0-9]" <<<"$var")
echo $var2
if [[ $var2 -lt 3 ]]
then
echo "PIPELINE STOPPED SUCCESSFULLY"
exit 0
else
echo "PIPELINE WAS NOT STOPPED SUCCESSFULLY"
exit 1
fi
As user mbratch noticed I was getting a "\r" in the returned value in addition to the expected "\n". So I changed my sed script so that it stripped out the "\r" instead of the whitespace (which chepner pointed out was unnecessary).
sed -e 's/\r*$//'

Resources