LinuxQuestions.org
Review your favorite Linux distribution.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 03-28-2011, 01:30 PM   #1
toordog
Member
 
Registered: Jul 2010
Location: Montreal, Canada
Distribution: RedHat, Ubuntu, Solaris, AIX, BSD
Posts: 42

Rep: Reputation: 3
Korn Shell syntax issue for remote complex command.


I'm trying to send a serie of command to a remote server via ssh and upon some condition (command success state).

Unfortunately, the quote to encapsulate the remote command put a limitation. I wonder if there is a workaround to get it working.

Code:
ssh $(whoami)@${hostname_T} \
'ypwhich; \
case $? in \
"0") echo "INFO: NIS domain configured and working";; \
"1") echo "WARNING: Unable to communicate with NIS domain. Trying to reconfigure NIS domain and restart service."; \
/usr/share/authconfig/authconfig.py --enablenis --nisdomain=montreal.domain --nisserver=mt-nis1 --update; \
service ypbind restart;\
token_check=${token_check}+1;\
ypwhich_test "Couldn\'t connect to NIS domain";; \
"127") echo "WARNING: yp-tools not installed! Installing yp-tools with yum."; \
if [[ -r /etc/yum.repos.d/public-yum-el5.repo ]]; \
then \
yum -y install yp-tools.x86_64; \
token_check=${token_check}+1; \
ypwhich_test "ypwhich command not found"; \
else \
echo "ERROR: Repository channel for Oracle Enterprise Linux not found! /etc/yum.repos.d/public-yum-el5.repo NOT FOUND. EXITING!"; \
fi;; \
*) echo "ERROR: CatchALL: Unknown return code. Probably fatal."; \
token_check=${token_check}+10; \
ypwhich_test "CatchALL: Unknown return code. Probably fatal.";; \
esac;'
When i test the script for syntax error, i get this :


default_deploy.ksh: warning: line 221: " quote may be missing
default_deploy.ksh: warning: line 225: " quote may be missing
default_deploy.ksh: syntax error at line 234: `"' unmatched.

The error on line 221, 225, 234 refer to the line I pasted. When I comment this line, all error disapear except for the if condition that is empty.




For reference, here is the full script:
Code:
#!/usr/bin/ksh
################################################################
function usagemsg {
print "
Program: deploy_default

This script will synchronize the user in between a list of Linux host.
It will validate that the host is configured to use NIS authentication.

Usage: ${1##*/} [-?adghilsvV] 
Usage: ${1##*/} -i -l /root/sync_list.txt
Usage: ${1##*/} -l /root/sync_list.txt -s
Usage: ${1##*/} -h somehost.domain.com -s
Usage: ${1##*/} -a somehost.domain.com
Usage: ${1##*/} -d somehost.domain.com

Where:
-a = Add host - Add host to the list
-d = Del host - Delete a host from the list
-g = Generate certificate for executing user.
-h = Hostname - Can be a Filename containing a list of hostname one per line or a single hostname *Default ~/sync_list.txt
-i = Install - Install ssh certificat on remote host
-l = List of hostname - the path to a file containing a list of hosts.
-s = Sync - Sync Authentication file between host list
-v = Show version - Display the version of this script.
-V = Debug mode - Execute in debug mode. (ksh -x)
-? = Help - display this message

Author: Olivier Contant (olivier.contant@domain.com
\"AutoContent\" enabled
"
}

################################################################
#### 
#### Description:
#### 
#### This script will synchronize the user in between a list of Linux host.
#### It will validate that the host is configured to use NIS authentication.
#### 
#### Assumptions:
#### 
#### Assume root user certificate exist on all remote host.
#### Will prompt for root password if no certificate exist.
#### 
#### Product
#### Will replace remote file:
#### /etc/passwd
#### /etc/passwd-
#### /etc/shadow
#### /etc/shadow-
#### /etc/group
#### /etc/group-
#### /etc/gshadow
#### /etc/gshadow-
#### /etc/hosts
####
#### 
#### 
################################################################


function deploy_default {
typeset VERSION="1.0"
typeset TRUE="1"
typeset FALSE="0"
typeset DT=$(date +%m-%d-%y)
typeset DATE=$(date +%D)
typeset DATET=$(date +%D\ %T)
typeset -Z2 token_check=0

typeset hostname_T

if [[ -e ~/sync_list.txt ]]
then
typeset filelist="~/sync_list.txt"
else
typeset filelist
fi

while getopts ":a:d:gh:ilsvV" OPTION
do
case "${OPTION}" in
'a') hostname_T=${OPTARG}
add_host;;
'd') hostname_T=${OPTARG}
del_host;;
'g') gen_rsa;;
'h') hostname_T=${OPTARG}
hostname_T_check="${TRUE}";;
'i') install_ssh_key_check="${TRUE}";;
'l') filelist=${OPTARG}
if [[ -r $filelist ]]
then
filelist_check="${TRUE}"
else
echo "ERROR: File list $filelist not found. Exiting!" && exit 1
fi;;
's') sync_config_check="${TRUE}";;
'v') VERSION="${TRUE}";;
'V') VERYVERB="${TRUE}";;
'?') usagemsg "${0}" && return 1 ;;
':') usagemsg "${0}" && return 1 ;;
'#') usagemsg "${0}" && return 1 ;;
esac
done

shift $(( ${OPTIND} - 1 ))

trap "usagemsg ${0}" EXIT

## Trap if no argument are set
trap "-" EXIT

(( VERYVERB == TRUE )) && set -x
(( VERSION == TRUE )) && print -u 2 "# Version........: ${VERSION}"


if [[ $filelist_check == "${TRUE}" && $hostname_T_check == "${TRUE}" ]] 
then
echo "ERROR: You cannot use -l and -h at the same time. Exiting!"
usagemsg ${0} && exit 1
fi

if [[ $hostname_T_check == "${FALSE}" && -z $filelist ]]
then
echo "ERROR: Couldn't find a hostname. Ensure to set a valid filename -l or hostname -h. Exiting!"
usagemsg ${0} && exit 1
fi

if [[ $install_ssh_key_check == "${TRUE}" && $hostname_T_check == "${TRUE}" ]] 
then
install_ssh_key $hostname_T
else
if [[ -r $1 ]]
then
while read fileline
do
hostname_T=${fileline}
install_ssh_key $hostname_T
done < ${filelist}
else
echo "ERROR: We were unable to access the file list $filelist. Exiting!" && exit 1
fi
fi

if [[ $sync_config_check == "${TRUE}" && $hostname_T_check == "${TRUE}" ]] 
then
echo "INFO: To avoid to be prompt for password, ensure your SSH certificate for your user is correctly installed on all host."
echo "INFO: To install your certificate use flag -i. Ex.: deploy_default.ksh -i -h somehost.domain.com"
echo ""
sync_config $hostname_T
else
echo "INFO: To avoid to be prompt for password, ensure your SSH certificate for your user is correctly installed on all host."
echo "INFO: To install your certificate use flag -i. Ex.: deploy_default.ksh -i -h somehost.domain.com"
echo ""
if [[ -r $1 ]]
then
while read fileline
do
hostname_T=${fileline}
sync_config $hostname_T
done < ${filelist}
else
echo "ERROR: We were unable to access the file list $filelist. Exiting!" && exit 1
fi
fi
}
################################################################

### Function definition ###

function add_host
{
echo ${hostname_T} >> ${filelist}
}

function del_host
{
grep -v ${hostname_T} ${filelist} > ${filelist}.new
mv -f ${filelist}.new ${filelist}
}

function gen_rsa
{
ssh-keygen -q -t rsa -f $HOME/.ssh/id_rsa -P ""
}

function install_ssh_key # $1=hostname
{
ssh-copy-id -i ~/.ssh/id_rsa.pub root@${1}
if (( $? -ne 0 ))
then
echo "ERROR: Couldn't install ssh key to remote host: $hostname_T. EXITING."
echo "ERROR: Couldn't install ssh key to remote host: $hostname_T. EXITING."
echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
echo "" >> ~/deploy_default-${dt}.errlog && exit 1
fi
}

function ypwhich_test #$1="Trigger message"
{
if (( ${token_check} -ge 2 ))
then
echo "ERROR: Hostname: $hostname_T: Couldn't connect to NIS domain after 3 attempts. Aborting!"
echo "INFO: Error message: $1. Dumping log to deploy_default.errlog"
echo ""
echo "ERROR: Hostname: $hostname_T: Couldn't connect to NIS domain after 3 attempts. Aborting!" >> ~/deploy_default-${dt}.errlog
echo "INFO: Error message: $1.">> ~/deploy_default-${dt}.errlog
echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@">> ~/deploy_default-${dt}.errlog
echo "" >> ~/deploy_default-${dt}.errlog
else

ssh $(whoami)@${hostname_T} 'ypwhich; \
case $? in \
"0") echo "INFO: NIS domain configured and working";; \
"1") echo "WARNING: Unable to communicate with NIS domain. Trying to reconfigure NIS domain and restart service."; \
/usr/share/authconfig/authconfig.py --enablenis --nisdomain=montreal.domain --nisserver=mt-nis1 --update; \
service ypbind restart;\
token_check=${token_check}+1;\
ypwhich_test "Could not connect to NIS domain";; \
"127") echo "WARNING: yp-tools not installed! Installing yp-tools with yum."; \
if [[ -r /etc/yum.repos.d/public-yum-el5.repo ]]; \
then \
yum -y install yp-tools.x86_64; \
token_check=${token_check}+1; \
ypwhich_test "ypwhich command not found"; \
else \
echo "ERROR: Repository channel for Oracle Enterprise Linux not found! /etc/yum.repos.d/public-yum-el5.repo NOT FOUND. EXITING!"; \
fi;; \
*) echo "ERROR: CatchALL: Unknown return code. Probably fatal."; \
token_check=${token_check}+10; \
ypwhich_test "CatchALL: Unknown return code. Probably fatal.";; \
esac;'
fi
}
function sync_config #$1=hostname
{
echo "INFO: Uploading configuration file to remote host: ${hostname_T}."
echo ""

scp /etc/passwd /etc/passwd- /etc/shadow /etc/shadow- /etc/group /etc/group- /etc/gshadow /etc/gshadow- /etc/hosts $(whoami)@${1}:/tmp/ || echo "ERROR: Couldn't copy files to remote server: ${hostname_T}. FATAL EXITING!" && echo "ERROR: Couldn't copy files to remote server: ${hostname_T}. FATAL EXITING!">>~/deploy_default-${dt}.errlog && continue
ssh $(whoami)@${1} 'mv -f /tmp/passwd /tmp/passwd- /tmp/shadow /tmp/shadow- /tmp/group /tmp/group- /tmp/gshadow /tmp/gshadow- /tmp/hosts /etc/'
ypwhich_test "First check for NIS configuration"
}



################################################################


deploy_default "${@}"

Last edited by toordog; 03-30-2011 at 09:42 AM.
 
Old 03-28-2011, 03:53 PM   #2
toordog
Member
 
Registered: Jul 2010
Location: Montreal, Canada
Distribution: RedHat, Ubuntu, Solaris, AIX, BSD
Posts: 42

Original Poster
Rep: Reputation: 3
Deleted

duplicated

Last edited by toordog; 03-28-2011 at 03:56 PM.
 
Old 03-28-2011, 04:35 PM   #3
toordog
Member
 
Registered: Jul 2010
Location: Montreal, Canada
Distribution: RedHat, Ubuntu, Solaris, AIX, BSD
Posts: 42

Original Poster
Rep: Reputation: 3
ssh $(whoami)@${hostname_T} \
ypwhich; \
case $? in \
0) echo \\'INFO: NIS domain configured and working\\';; \
1) echo \\'WARNING: Unable to communicate with NIS domain. Trying to reconfigure NIS domain and restart service.\\'; \
/usr/share/authconfig/authconfig.py --enablenis --nisdomain=montreal.speechworks --nisserver=mt-nis1 --update; \
service ypbind restart;\
token_check=${token_check}+1;\
ypwhich_test \\'Couldn\'t connect to NIS domain\\';; \
127) echo \\'WARNING: yp-tools not installed! Installing yp-tools with yum.\\'; \
if [[ -r /etc/yum.repos.d/public-yum-el5.repo ]]; \
then \
yum -y install yp-tools.x86_64; \
token_check=${token_check}+1; \
ypwhich_test \\'ypwhich command not found\\'; \
else \
echo \\'ERROR: Repository channel for Oracle Enterprise Linux not found! /etc/yum.repos.d/public-yum-el5.repo NOT FOUND. EXITING!\\'; \
fi;; \
*) echo \\'ERROR: CatchALL: Unknown return code. Probably fatal.\\'; \
token_check=${token_check}+10; \
ypwhich_test \\'CatchALL: Unknown return code. Probably fatal.\\';; \
esac;


---------- Post added 03-28-11 at 05:36 PM ----------

Solved
 
Old 03-30-2011, 09:39 AM   #4
toordog
Member
 
Registered: Jul 2010
Location: Montreal, Canada
Distribution: RedHat, Ubuntu, Solaris, AIX, BSD
Posts: 42

Original Poster
Rep: Reputation: 3
The problem i'm facing now, is that variable defined with typeset -x are unreachable by the ypwhich_test function. When call, they are empty variable.

It output: ERROR: Failed to open a SSH Tunnel with ON at /home/test.FATAL ERROR EXITING!
from the line: echo "ERROR: Failed to open a SSH Tunnel with ${hostname_T} ON ${DT} at ${HOME}.FATAL ERROR EXITING!"

It cans still see Shell environment variable but not those I declared.


Code:
ssh root@${hostname_T} 'ypwhich;\
        case $? in
            0) echo "INFO: NIS domain configured and working";;
            1) echo "WARNING: Unable to communicate with NIS domain. Trying to reconfigure NIS domain and restart service.";
                /usr/share/authconfig/authconfig.py --enablenis --nisdomain=montreal.speechworks --nisserver=mt-nis1 --update;
                service ypbind restart;
                token_check=${token_check}+1;
                ypwhich_test "Could not connect to NIS domain";;
            127) echo "WARNING: yp-tools not installed! Installing yp-tools with yum.";
                if [[ -r /etc/yum.repos.d/public-yum-el5.repo ]];
                then
                    yum -y install yp-tools.x86_64;
                    token_check=${token_check}+1;
                    ypwhich_test "ypwhich command not found";
                else
                    echo "ERROR: Repository channel for Oracle Enterprise Linux not found! /etc/yum.repos.d/public-yum-el5.repo NOT FOUND. EXITING!";
                fi;;
            *) echo "ERROR: CatchALL: Unknown return code. Probably fatal.";
                token_check=${token_check}+10;
                ypwhich_test "CatchALL: Unknown return code. Probably fatal.";;
        esac;'
                if [[ $? -ne 0 ]]
                then
                        echo "ERROR: Failed to open a SSH Tunnel with ${hostname_T} ON ${DT} at ${HOME}.FATAL ERROR EXITING!"
                fi
 
Old 03-30-2011, 08:27 PM   #5
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,012

Rep: Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194
Well the first testing I would suggest is to see at what point you are losing the definitions of the variables.
Try a simple code with 2 functions:
Code:
#!/usr/bin/ksh

function defaults {

    typeset DT=$(date +%m-%d-%y)
    typeset hostname_T

    hostname_T="blah"

    echo ${DT}
    echo ${hostname_T}

    second_call
}

function second_call {

    echo ${DT}
    echo ${hostname_T}
}

defaults
Then try changing typeset to typeset -x and see if it helps. My first thought is that using typeset inside a function is causing the variables to be local, which
seems to be commented on here under the section on 'scope'

See how you go?
 
Old 03-31-2011, 09:43 AM   #6
toordog
Member
 
Registered: Jul 2010
Location: Montreal, Canada
Distribution: RedHat, Ubuntu, Solaris, AIX, BSD
Posts: 42

Original Poster
Rep: Reputation: 3
I found out for the date variable and the hostname variable. The typeset -x was already set but it was set inside another function. *my main function let say*. I put the variable definition out of all function and it worked.

Now I still have an issue about variable reachability. I try to catch the command $? return code in a remote ssh like this:

typeset -x status_var=-1

ssh root@somehost 'ypwhich; status_var=$?'
echo $status_var

and it return -1. If i didn't set a value, it would return empty.
Look like the variable substitution doesn't work in the remote command.

Any idea How I could set an event in the case ypwhich return an error ?
 
Old 03-31-2011, 09:56 AM   #7
toordog
Member
 
Registered: Jul 2010
Location: Montreal, Canada
Distribution: RedHat, Ubuntu, Solaris, AIX, BSD
Posts: 42

Original Poster
Rep: Reputation: 3
This test make me think that the variable is set locally on the remote shell

Code:
#!/bin/ksh

typeset -x var1

ssh root@10.3.23.193 'ypwhich; var1=$?;echo $var1'
echo $var1
[test@mtl-sdama04-pxe-4 test]$ ksh -x test.ksh
+ typeset -x var1
+ ssh root@10.3.23.193 'ypwhich; var1=$?;echo $var1'
1
ypwhich: can't get local yp domain: Local domain name not set
+ echo
 
Old 03-31-2011, 10:21 AM   #8
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,012

Rep: Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194
I am not a guru on ssh but my understanding is that you treat it as if you logged into the machine you are connecting to for the first time, ie there would be no additional variables brought in.
The other part is that once the ssh session has been left, anything done inside the session is lost to the caller outside the session.

So essentially you will need the script that is run inside the ssh to do all the work. As from your last test it appears the calling shell is still able to receive data, ie the 1 returned from the echo,
this would be a mechanism to send back data to the calling program that can be caught in a variable and then tested.

Now the question would be, what is the best way to deliver back meaningful information?

The solution to your issue in post #6 is obvious:
Code:
return_val=$(ssh root@somehost 'ypwhich; echo $?')
Maybe start there and see how you go?
 
Old 03-31-2011, 10:29 AM   #9
toordog
Member
 
Registered: Jul 2010
Location: Montreal, Canada
Distribution: RedHat, Ubuntu, Solaris, AIX, BSD
Posts: 42

Original Poster
Rep: Reputation: 3
Quote:
Originally Posted by grail View Post
I am not a guru on ssh but my understanding is that you treat it as if you logged into the machine you are connecting to for the first time, ie there would be no additional variables brought in.
The other part is that once the ssh session has been left, anything done inside the session is lost to the caller outside the session.

So essentially you will need the script that is run inside the ssh to do all the work. As from your last test it appears the calling shell is still able to receive data, ie the 1 returned from the echo,
this would be a mechanism to send back data to the calling program that can be caught in a variable and then tested.

Now the question would be, what is the best way to deliver back meaningful information?

The solution to your issue in post #6 is obvious:
Code:
return_val=$(ssh root@somehost 'ypwhich; echo $?')
Maybe start there and see how you go?

I think you are right that there would have only one way and with the constraint of returning a only single value back from a remote execution. Unfortunately the design of my script couldn't take advantage of this way. Another way I found is to dump the status in a temp file in /tmp and to read that file from my local script and do my case logic from it. This way I limit the number of remote ssh i have to call (can be a constraint for a client that doesn't have certificate set).

By the way, I think it was too obvious, I couldn't see it! I'll keep it in mind so next time I can design my script in a way to use it, which is preferable to what I'm doing.
 
Old 03-31-2011, 10:34 AM   #10
toordog
Member
 
Registered: Jul 2010
Location: Montreal, Canada
Distribution: RedHat, Ubuntu, Solaris, AIX, BSD
Posts: 42

Original Poster
Rep: Reputation: 3
Quote:
return_val=$(ssh root@somehost 'ypwhich; echo $?')
I found another limitation. return_val will contain everything that the remote command has output to stdout. I would not have only the $? value but everything else that can be a bit unpredictable. Seems like the only efficient controllable way would be dumping to a file and read it.

If you have another idea let me know
 
Old 03-31-2011, 11:37 AM   #11
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,012

Rep: Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194
Quote:
I found another limitation. return_val will contain everything that the remote command has output to stdout.
Not necessarily. i have not used ypwhich but I assume it is the output of its data you are referring to, so simply shunt that off to /dev/null. It will not change the outcome
of the commands success or failure.
Something like:
Code:
return_val=$(ssh root@somehost 'ypwhich > /dev/null; echo $?')
Depending on whether or not there are possible errors displayed you may also need to redirect it as well.
 
Old 04-01-2011, 11:30 AM   #12
toordog
Member
 
Registered: Jul 2010
Location: Montreal, Canada
Distribution: RedHat, Ubuntu, Solaris, AIX, BSD
Posts: 42

Original Poster
Rep: Reputation: 3
Code:
#!/usr/bin/ksh
################################################################
function usagemsg {
  print "
Program: deploy_default

This script will synchronize the user in between a list of Linux host.
It will validate that the host is configured to use NIS authentication.

Usage: ${1##*/} [-?adghilsvV] 
Usage: ${1##*/} -i -l /root/sync_list.txt
Usage: ${1##*/} -l /root/sync_list.txt -s
Usage: ${1##*/} -h somehost.nuance.com -s
Usage: ${1##*/} -a somehost.nuance.com -l host_file.txt
Usage: ${1##*/} -d somehost.nuance.com -l host_file.txt

  Where:
    -a = Add host - Add host to the list
    -d = Del host - Delete a host from the list
    -g = Generate certificate for executing user.
    -h = Hostname - The hostname of the machine you want to sync to  *Default ~/host_list.txt
    -i = Install - Install ssh certificat on remote host
    -l = List of hostname - the path to a file containing a list of hosts.
    -s = Sync - Sync Authentication file between host list
    -v = Show version - Display the version of this script.
    -V = Debug mode - Execute in debug mode. (ksh -x)
    -? = Help - display this message

Author: Olivier Contant (olivier.contant@nuance.com
\"AutoContent\" enabled
"
}

################################################################
#### 
#### Description:
#### 
#### This script will synchronize the user in between a list of Linux host.
#### It will validate that the host is configured to use NIS authentication.
#### 
#### Assumptions:
#### 
#### Assume root user certificate exist on all remote host.
#### Will prompt for root password if no certificate exist.
#### 
#### Product
#### Will replace remote file:
#### /etc/passwd
#### /etc/passwd-
#### /etc/shadow
#### /etc/shadow-
#### /etc/group
#### /etc/group-
#### /etc/gshadow
#### /etc/gshadow-
#### /etc/hosts
####
#### 
#### 
################################################################

typeset VERSIONREV="1.0"
typeset TRUE="1"
typeset FALSE="0"
typeset -x DT=$(date +%m-%d-%y)
typeset -x DATE=$(date +%D)
typeset -x DATET=$(date +%D\ %T)
typeset VERSION="${FALSE}"
typeset VERYVERB="${FALSE}"
typeset -x token_check=0
typeset -x nbsargs=$#
typeset -x args_=$*
typeset -x cmd_=$@
typeset -x hostname_T
typeset -x ypwhich_status="-1"

typeset hostname_T_check="${FALSE}"
typeset add_host_check="${FALSE}"
typeset del_host_check="${FALSE}"
typeset gen_rsa_check="${FALSE}"
typeset filelist_check="${FALSE}"
typeset sync_config_check="${FALSE}"

function deploy_default 
{
  if [[ -e ${HOME}/host_list.txt ]]
  then
    typeset -x filelist=${HOME}/host_list.txt
  else
    typeset -x filelist
  fi
  
  while getopts ":a:d:gh:il:svV" OPTION
  do
      case "${OPTION}" in
          'a') hostname_T=${OPTARG}
               add_host_check="${TRUE}";;
          'd') hostname_T=${OPTARG}
               del_host_check="${TRUE}";;
          'g') gen_rsa_check="${TRUE}";;
          'h') hostname_T=${OPTARG}
               hostname_T_check="${TRUE}";;
          'i') install_ssh_key_check="${TRUE}";;
          'l') filelist=${OPTARG}
               if [[ -r $filelist ]]
               then
                filelist_check="${TRUE}"
               else
                echo "ERROR: File list $filelist not found. Exiting!" && exit 1
               fi;;
          's') sync_config_check="${TRUE}";;
          'v') VERSION="${TRUE}";;
          'V') VERYVERB="${TRUE}";;
          '?') usagemsg "${0}" && return 1 ;;
          ':') usagemsg "${0}" && return 1 ;;
          '#') usagemsg "${0}" && return 1 ;;
      esac
  done
   
  shift $(( ${OPTIND} - 1 ))
  
  
  if [[ $VERYVERB == ${TRUE} ]] 
  then
	echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
	echo "@@@@@@@@    Troubleshooting DATA     @@@@@"
	echo "@@                                      @@"
	echo "@@  Version: 	     ${VERSIONREV}        @@"
	echo "@@  Nbs arguments: ${nbsargs}           @@"
	echo "@@  Commande:      ${cmd_}              @@"
	echo "@@  Hostname:      ${hostname_T}        @@"
	echo "@@  Host file:     ${filelist}          @@"
	echo "@@  True value:    ${TRUE}              @@"
	echo "@@  False value:   ${FALSE}             @@"
	echo "@@  whoami:        $(whoami)            @@"
	echo "@@                                      @@"
	echo "@@                                      @@"
	echo "@@                                      @@"
	echo "@@@@@@@@    Troubleshooting DATA     @@@@@"
	echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
  fi
  
  
  (( VERSION  == ${TRUE} )) && print -u 2 "# Version........: ${VERSIONREV}" && exit 0
  
  
  if [[ $nbsargs -lt 1 ]]
  then
    usagemsg ${0} && exit 1
  fi
  
  ## -a, -d and -g are not host relative.  They should be check first.
  # -a check
  if [[ $add_host_check == "${TRUE}" ]]
  then
    if [[ $nbsargs -le 4 ]]
    then
        add_host 
        if [[ $? -eq 0 ]]
        then
            echo "INFO: Hostname added" && exit 0
        else
            echo "ERROR: Failed to add hostname to host file" && exit 1
        fi
    else
        echo "ERROR: -a cannot be combined with other options than -l. EXITING!"
        echo "INFO: Command arguments entered: $args_" && exit 1
    fi
  fi
  
  # -d check
  if [[ $del_host_check == "${TRUE}" ]]
  then
    if [[ $nbsargs -le 4 ]]
	then
        del_host 
        if [[ $? -eq 0 ]]
        then
            echo "INFO: Hostname deleted" && exit 0
        else
            echo "ERROR: Failed to delete hostname from host file" && exit 1
        fi
    else
        echo "ERROR: -d cannot be combined with other options than -l. EXITING!"
        echo "INFO: Command arguments entered: $args_" && exit 1
    fi
  fi
  
  # -g check
  if [[ $gen_rsa_check == "${TRUE}" ]]
  then
      if [[ $nbsargs -lt 2 ]]
    then
        gen_rsa
        if [[ $? -eq 0 ]]
        then
            echo "INFO: Key RSA generated successfully" && exit 0
        else
            echo "ERROR: Failed to generate RSA key." && exit 1
        fi
    else
        echo "ERROR: -g cannot be combined with other options. EXITING!"
        echo "INFO: Command arguments entered: $args_" && exit 1
    fi    
  fi
  
  # Option -l and -h cannot be set together
  if [[ $filelist_check == "${TRUE}" && $hostname_T_check == "${TRUE}" ]] 
  then
    echo "ERROR: You cannot use -l and -h at the same time.  Exiting!"
    usagemsg ${0} && exit 1
  fi
  
  # We didn't specify -l or -h and the default host file doesn't exist.
  if [[ $hostname_T_check == "${FALSE}" && -z $filelist ]]
  then
    echo "ERROR: Couldn't find a hostname; ${HOME}/host_list.txt File Not Found. Ensure to enter a valid filename -l or hostname -h. Exiting!"
    usagemsg ${0} && exit 1
  fi
  
  # if -i set 
  if [[ $install_ssh_key_check == "${TRUE}" ]] 
  then
    if [[ $hostname_T_check == "${TRUE}" ]] # read hostname from -h optargs or will read a file containing the list of hosts.
    then
        install_ssh_key 
    else
        if [[ -r $filelist ]]
        then
            while read fileline
            do
                hostname_T=${fileline}
                install_ssh_key 
            done < ${filelist}
        else
            echo "ERROR: We were unable to read access the file list $filelist. Exiting!" 
            echo "INFO: Verify that you have read access to the file" && exit 1
        fi
    fi
  fi
  
  # if -s set 
  if [[ $sync_config_check == "${TRUE}" ]] 
  then
    if [[ $hostname_T_check == "${TRUE}" ]] # read hostname from -h optargs or will read a file containing the list of hosts.
    then
        echo "INFO: To avoid to be prompt for password, ensure your SSH certificate for your user is correctly installed on all host."
        echo "INFO: To install your certificate use flag -i. Ex.: deploy_default.ksh -i -h somehost.nuance.com"
        echo ""
        sync_config 
		clean_up_
    else
        echo "INFO: To avoid to be prompt for password, ensure your SSH certificate for your user is correctly installed on all host."
        echo "INFO: To install your certificate use flag -i. Ex.: deploy_default.ksh -i -h somehost.nuance.com"
        echo ""
        if [[ -r $filelist ]]
        then
            while read fileline
            do
				hostname_T=${fileline}
				token_check=0
				ypwhich_status="-1"
                echo "Syncing with server ${hostname_T}"
				sync_config
				clean_up_
            done < ${filelist}
        else
            echo "ERROR: We were unable to access the file list $filelist. Exiting!" && exit 1
        fi
    fi
  fi
}
################################################################

### Function definition ###

function add_host
{
    echo "Adding host: "${hostname_T} "to host file: "${filelist}
	echo ${hostname_T} >> ${filelist}
}

function del_host 
{
    echo "Deleting host :"${hostname_T} "from host file: "${filelist}
    grep -v ${hostname_T} ${filelist} > ${filelist}.new
    mv -f ${filelist}.new ${filelist}
}

function gen_rsa
{
    echo "Generate RSA Key"
    ssh-keygen -q -t rsa -f $HOME/.ssh/id_rsa -P ""
}

function install_ssh_key  
{
    echo "Install ssh key"
    ssh-copy-id -i ${HOME}/.ssh/id_rsa.pub root@${hostname_T}
    if [[ $? -ne 0 ]]
    then
        echo "ERROR: Couldn't install ssh key to remote host: $hostname_T.  EXITING."
        echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
		echo ""
		echo "ERROR: Couldn't install ssh key to remote host: $hostname_T.  EXITING."	>> ${HOME}/deploy_default-${DT}.errlog
        echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"	>> ${HOME}/deploy_default-${DT}.errlog
        echo "" 																		>> ${HOME}/deploy_default-${DT}.errlog
    fi
}

function ypwhich_test #$1="Trigger message"
{
    echo "ypwhich_test:" $1
    if [[ ${token_check} -ge 5 ]]
    then
        echo "ERROR: Hostname: $hostname_T: Couldn't connect to NIS domain after 5 attempts. Aborting!"
		echo "INFO: Error message: $1.  Dumping log to deploy_default.errlog"
        echo ""
		ypwhich_status=130
        echo "ERROR: Hostname: $hostname_T: Couldn't connect to NIS domain after 5 attempts. Aborting!" >> ${HOME}/deploy_default-${DT}.errlog
        echo "INFO: Error message: $1." 																>> ${HOME}/deploy_default-${DT}.errlog
        echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" >> ${HOME}/deploy_default-${DT}.errlog
        echo "" 																						>> ${HOME}/deploy_default-${DT}.errlog
    else
        ypwhich_status=`ssh root@${hostname_T} 'ypwhich >/dev/null; echo $?'`
		if [[ $? -ne 0 ]]
		then
			echo "ERROR: Error Code: $?"
			echo "ERROR: Failed to open a SSH Tunnel on ${hostname_T}. FATAL ERROR EXITING!"
		fi
    fi
}

function sync_config #$1=hostname
{
    echo "Sync_config"
    echo "INFO: Uploading configuration file to remote host: ${hostname_T}."
    echo ""
    
	ssh root@${hostname_T} 'mkdir /tmp/deploy_default'    
    scp /etc/passwd /etc/passwd- /etc/shadow /etc/shadow- /etc/group /etc/group- /etc/gshadow /etc/gshadow- /etc/hosts root@${hostname_T}:/tmp/deploy_default/ || echo "ERROR: Couldn't copy all files to remote server: ${hostname_T}." && echo "ERROR: Couldn't copy all files to remote server: ${hostname_T}." >>${HOME}/deploy_default-${DT}.errlog
	ssh root@${hostname_T} 'mv -f /tmp/deploy_default/* /etc/'
    if [[ $? == 0 ]]
	then
		echo "INFO: Replaced original file successfully"
		echo ""
	else
		echo "ERROR: Failed to replace all original file."
	fi
	
	
	while [[ $ypwhich_status -ne 2 && $ypwhich_status -ne 130 ]]
	do
		if [[ $token_check = 0 ]]
		then
			token_check=$((${token_check}+1));
			ypwhich_test "First check for NIS configuration"
		else
			case $ypwhich_status in
				0) 	 echo "INFO: Everything setup, NIS domain configured at retry attempt: $token_check"
					 ypwhich_status=2;;
				1) 	 token_check=$((${token_check}+1));
					 ssh root@${hostname_T} '/usr/share/authconfig/authconfig.py --enablenis --nisdomain=montreal.speechworks --nisserver=mt-nis1 --update;
					 service ypbind restart'
					 ypwhich_test "Domain NIS configured at retry attempt: ${token_check}.";;
				2)   echo "NIS domain configured correctly."
					 ypwhich_status=2;;
				127) token_check=$((${token_check}+1));
					 echo "WARNING: yp-tools not installed! Installing yp-tools with yum.";
					 ypwhich_status=`ssh root@${hostname_T} \
					'if [[ -r /etc/yum.repos.d/public-yum-el5.repo ]];
					then
						yum -y install yp-tools.x86_64 >/dev/null;
						if [[ $? -eq 0 ]];
						then
							echo "1";
						else
							echo "128";
						fi;
					else
						echo "129";			
					fi'`;;
				128) token_check=$((${token_check}+10));
					 ypwhich_test "ERROR: yp-tools failed to install at retry attempt: $token_check. FATAL ERROR! Exiting!";;
				129) token_check=$((${token_check}+10));
					 ypwhich_test "ERROR: Repository channel for Oracle Enterprise Linux not found at retry attempt: $token_check! /etc/yum.repos.d/public-yum-el5.repo NOT FOUND. EXITING!";;
				130) token_check=$((${token_check}+10));
					 ypwhich_test "CatchALL: Unknown return code. Probably fatal at retry attempt: $token_check.";;
				  *) token_check=$((${token_check}+10));
					 echo "CatchALL: Unknown return code: $ypwhich_status. EXITING!"
			esac;
		fi
	done
}

function clean_up_
{
	ssh root@${hostname_T} 'if [[ -d /tmp/deploy_default ]]; then echo "Deleting /tmp/deploy_default directory."; rm -rf /tmp/deploy_default; fi'
}

################################################################


deploy_default "${@}"


Is there a reason why this loop doesn't loop? I did some test with a loop that call a function that has a loop to read the file hostfile and everything run fine. But for some reason my loop in this code doesn't loop. It stop after the first line of the file hostfile.

Buggy loop:
Code:
  # if -s set 
  if [[ $sync_config_check == "${TRUE}" ]] 
  then
    if [[ $hostname_T_check == "${TRUE}" ]] # read hostname from -h optargs or will read a file containing the list of hosts.
    then
        echo "INFO: To avoid to be prompt for password, ensure your SSH certificate for your user is correctly installed on all host."
        echo "INFO: To install your certificate use flag -i. Ex.: deploy_default.ksh -i -h somehost.nuance.com"
        echo ""
        sync_config 
		clean_up_
    else
        echo "INFO: To avoid to be prompt for password, ensure your SSH certificate for your user is correctly installed on all host."
        echo "INFO: To install your certificate use flag -i. Ex.: deploy_default.ksh -i -h somehost.nuance.com"
        echo ""
        if [[ -r $filelist ]]
        then
            while read fileline
            do
				hostname_T=${fileline}
				token_check=0
				ypwhich_status="-1"
                echo "Syncing with server ${hostname_T}"
				sync_config
				clean_up_
            done < ${filelist}
        else
            echo "ERROR: We were unable to access the file list $filelist. Exiting!" && exit 1
        fi
    fi
  fi

The file contain:

10.3.23.193
10.3.23.219
iii.com
ooo.com
 
Old 04-01-2011, 12:02 PM   #13
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,012

Rep: Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194
Well I see nothing particularly obvious so testing wise I would look at:

1. Run the while loop but comment out each line in the loop and put in an echo to make sure the fileline variable is getting set (btw. you may as well just use hostname_T as it is a direct copy)

2. Assuming above is ok, slowly add back each line until you hit the problem (I am guessing it will actually be caused by one of the functions being called)
 
Old 04-01-2011, 01:11 PM   #14
toordog
Member
 
Registered: Jul 2010
Location: Montreal, Canada
Distribution: RedHat, Ubuntu, Solaris, AIX, BSD
Posts: 42

Original Poster
Rep: Reputation: 3
I commented already teh function line and just echoed the variable. The loop is working in this context.

I have the function clean_up_ that alone make the loop not loop. This function has only one line of code that run a command via ssh on a remote server. This shouldn't crash the loop because there is no exit or return, break etc.

I though that maybe my function called a subshell and that subshell would crash the loop, but I then tried to create a test script with 2 functions with a loop inside echoing the value of the same file that I use in my big script and it worked. So it is not the subshell or something like that.

I'm a bit lost on this one.
 
Old 04-02-2011, 03:31 AM   #15
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,012

Rep: Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194
Try the following in your clean_up_:
Code:
function clean_up_
{
	ssh root@${hostname_T} 'if [[ -d /tmp/deploy_default ]]; then echo "Deleting /tmp/deploy_default directory."; echo rm -rf /tmp/deploy_default; fi'
}
See what this gives you and if the while loop continues correctly afterwards?
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
remote ssh issue with the iptables command neteng996 Programming 1 09-21-2010 11:05 AM
korn shell loop jonlake Programming 2 03-28-2008 12:10 PM
running shell command on remote machine with ssh qrshat Solaris / OpenSolaris 3 08-17-2006 07:32 AM
Shell Command Syntax swan2925 Linux - Software 3 06-02-2005 10:07 AM
Korn shell script Muzica Solaris / OpenSolaris 4 09-06-2004 12:47 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 10:32 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration