'Couldn't read file' error in bash script with expect, sed and awk! | Unix Linux Forums | Shell Programming and Scripting

  Go Back    


Shell Programming and Scripting Post questions about KSH, CSH, SH, BASH, PERL, PHP, SED, AWK and OTHER shell scripts and shell scripting languages here.

'Couldn't read file' error in bash script with expect, sed and awk!

Shell Programming and Scripting


Tags
awk, bash, expect, script, sed

Closed Thread    
 
Thread Tools Search this Thread Display Modes
    #1  
Old 09-20-2012
alexdglover alexdglover is offline
Registered User
 
Join Date: Sep 2012
Last Activity: 20 September 2012, 9:49 PM EDT
Posts: 1
Thanks: 0
Thanked 0 Times in 0 Posts
'Couldn't read file' error in bash script with expect, sed and awk!

Ok, so I have a bash script with an embedded expect statement.
Inside of the expect statement, i'm trying to pull all of the non-comment lines from the /etc/oratab file one at a time.
Here's my command:


Code:
cat /etc/oratab |sed /^s*#/d\ | awk 'NR==1'|awk -F: '{print \"$1\"}'|. oraenv

Now, this works at the terminal, but it doesn't work inside of the expect statement.
When executed within the expect script, I get the following error:


Code:
missing close-brace
    while executing
"while { 1 > 0 } {

        #Pull the SIDs from oratab
        send "cat /etc/oratab |sed /^s*#/d\ | awk NR==1|awk -F: {print"
couldn't read file """}|. oraenv\r"
        expect "?"
        send "\r"
        expect "$"

I think the issue is with the "awk -F: '{print $1}' " command.
I've tried escape characters, quotes, backticks, quotes with escape characters... any help or ideas would be greatly appreciated!

Here's the complete script for reference:


Code:
#!/bin/bash

#set a timestamp that will be used for labeling the log file
timestamp=$(date +%Y-%m-%d-%H:%M:%S)

#set log_file variable; logs will be stored under /var/log/change_password/day-and-time-run.log
log_file="./change_password_$timestamp.log"

#set a variable to hold the number of entries in ORATAB
numDatabases=$(echo cat /etc/oratab | sed '/^\s*#/d;/^\s*$/d' |grep -v "#"|awk -F: '{print $1}'|wc -l)

echo "----------   $numDatabases DATABASES FOUND!!!"

#Ask user to confirm that they have updated the host list (host_list)
echo -n "----------   Welcome to the Password Change Script. Have you edited the host_list file? (Y or N):"

#Collect user's input
read answer

#handle user's input; proceed with collecting CURRENT password if 'Y', otherwise send message and exit 
if [ "$answer" = "Y" ]
then
    #Prompt user for CURRENT password - will be used to log in at the OS level
    echo "----------   Enter the CURRENT password and press [Enter] NOTE - The password must be the same for all user account on all servers and databases to work correctly"
    echo -n "----------   Current Password:"
    read current_password
fi
if [ "$answer" != "Y" ]
then
        echo "----------   You must edit the host_list file first! Exiting!"
        exit 
fi

#Prompt user for NEW password that will be set for several OS user accounts and DB accounts
echo "----------   Enter a NEW password to be applied to all accounts (OS, DB, RMAN) and press [Enter]"
echo -n "----------   New Password:"
read new_password

#Get the number of servers from the text file, based on number of lines
server_count=$(wc -l < host_list)

#Communicate to user the number of servers found
echo "----------   Changing passwords on "$server_count" servers..."

#Notice to users not to prematurely kill the process/script, as sometimes it appears to be hung/crashed
echo "----------   Do not kill the process/command until you see the 'Goodbye' message - you will see several ssh connections and password updated successfully messages. Starting in 3 seconds..."

#wait 3 seconds
sleep 3


#create 'i' variable for iteration
i=1

#Execute the code within the while loop for every server name found in host file
while [ $i -le $server_count ]; do
    #set current_server variable to the server name found on each line of the host_list file
    current_server=$(sed -n "$i"p host_list)

    #communicate to user/log that script is attempting to SSH to the server and change passwords    
    echo "----------   Attempting to connect to server "$current_server" ("$i" of "$server_count" servers) and reset password for all accounts..." 

    #set VAR variable - it will hold the entire expect script command that will SSH to every server and remotely execute password change commands
    VAR=$(expect -c '

    # Set the log file.
    log_file '$log_file'

    send_user "\n-------------   '$numDatabases' = numDatabases\n"

    #start an SSH session as root on the current server
    spawn ssh oracle@'$current_server'

    #Script has initiated an SSH session; if prompted with the RSA warning, send yes and enter. 
    #If prompted for password to login, send password and enter
    expect { 
        "The authenticity of host"    {send "yes\r"}
        "password:"            {send "'$current_password'\r"}
    }
    
    #Script has attempted to authenticate via SSH by passing a password. If prompted for password again, password must be wrong. 
    #If prompted with the # then script must have successfully connected to server. Change the OS password for user account oracle
    expect {
        "password:"    {send_user "\n----------   SSH failed - most likely due to incorrect password! Exiting!\n"; exit }
        "$"        {send "passwd oracle\r"}
    }
    #Script has attempted to change OS password for user account oracle. 
    #If prompted for password, OS is ready for new password; send new password and enter. 
    #If OS returns Unknown user... then oracle user account probably doesnt exist
    expect {
        "password:"                {send "'$new_password'\r"}
        "Unknown user name oracle."        {send_user "\n----------   passwd failed - there is no user oracle on host $current_server! Exiting!\n"; exit}
    }    

    #Script has supplied the new password for oracle once, just needs to send again to confirm
    expect "password:"
    send "'$new_password'\r"

    #Script will now change password for asm OS user account
    expect "$"
    send "passwd applmgr\r"
    
    expect {
        "password:"                {send "'$new_password'\r"}
        "Unknown user name applmgr."        {send_user "\n----------   passwd failed - there is no user applmgr on host $current_server! Exiting!\n"; exit}
    }

    #Script has supplied the new password for applmgr once, just needs to send again to confirm
    expect "password:"
    send "'$new_password'\r"
    expect "$"

    #Script will now log in to each oracle database and change DB user passwords there
    #Looping through all of the databases in oratab
    while { '$numDatabases' > 0 } {

    #Pull the SIDs from oratab
    send "cat /etc/oratab |sed /^s*#/d\ | awk 'NR==1'|awk -F: '{print \"$1\"}'|. oraenv\r"
    expect "?"
    send "\r"
    expect "$"

    #log on as sysdba
    send "sqlplus / as sysdba\r"

    #Expecting the oracle prompt
    expect ">"
    send "ALTER USER sys IDENTIFIED BY '$new_password';\r"
     expect ">"
    send "ALTER USER system IDENTIFIED BY '$new_password';\r"
     expect ">"
    send "ALTER USER dbsnmp IDENTIFIED BY '$new_password';\r"
     expect ">"
    send "ALTER USER outln IDENTIFIED BY '$new_password';\r"
     expect ">"
    send "quit\r"
    #End while/for loop
    }

    expect "$"
    #If we havent exited by now, everything should be OK - send the all clear message
    send_user "\n----------   No errors while changing passwords on $current_server\n"
    
    #Exit the SSH session
    send "exit\r"

    #Closing the expect statement here
    ')

    #Execute the above expect script
    echo "$VAR"
    
    #Notify user/log that all accounts have been updated on current server
    echo "----------   Finished with "$current_server"!"
    
    #Wait one second to allow people to see what's happening
    sleep 1
    
    #Increment i so loop hits the next server in the host_list
    (( i++ ))
#finish loop
done

#Prompt user to clear all clear-text passwords in the log file
echo -n "----------   Complete! Do you want to clear clear-text passwords from the log files? (Y or N):"

#Collect user's input
read answer

#If user answers 'Y', replace all clear-text passwords with '********'
if [ "$answer" = "Y" ]
then
        echo "----------   Scrubbing clear-text passwords from log file..."
    sed -i 's/'$new_password'/********/g' $log_file
    echo "----------   All clear-text passwords have been masked!"
    echo "***************   Script has completed"
    echo "***************   Log can be found at $log_file"
    echo "***************   GOODBYE"
    exit
fi
#If user answers with any other string, warn the user of the clear-text passwords
if [ "$answer" != "Y" ]
then
        echo "----------   Log file unmodified. CAUTION - your new password is stored in clear-text the log files!"
    echo "***************   Script has completed"
    echo "***************   Log can be found at $log_file"
    echo "***************   GOODBYE"
        exit 
fi


Last edited by vbe; 09-21-2012 at 08:59 AM..
Sponsored Links
Closed Thread

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

More UNIX and Linux Forum Topics You Might Find Helpful
Thread Thread Starter Forum Replies Last Post
[Solved] SFTP error - Couldn't close file: Failure nickg Shell Programming and Scripting 1 10-28-2011 11:52 AM
I have a bash script and tried very hard but i couldn't solve it please help testman84 Shell Programming and Scripting 10 10-19-2010 02:42 PM
Bash script to read file location Prodiga1 Shell Programming and Scripting 8 09-17-2010 04:27 PM
read -n1 -r -p "Press..." key / produces error in bash shell script linuxinho Shell Programming and Scripting 4 05-26-2010 01:56 PM
Bash Script to read a file and parse each record 3vilwyatt Shell Programming and Scripting 8 02-25-2010 01:04 AM



All times are GMT -4. The time now is 11:46 PM.