3

I have bash script and inside it part with expect code:

#!/bin/bash
set -ex

funct()
{
pass3="some_pass"

    expect -c "
    spawn su - oracle
    expect "Password:"
    send \"$pass3\n\"
    interact
    "
}
funct

var_ulimit=`ulimit -Ha |grep "open files" |awk '{print $4}'`
echo $var_ulimit

when i execute the script ./script.sh, part with exepct work's ok i have switched to correct user. Problem is that script stop's at that point when executed from shell. Only when i do exit from shell bash script continues. Is it possible to tune expect part of the script to proceed with the rest of the bash script and to preserve shell for the rest of the script when do su - oracle?

Thnx

3
  • I'm not clear on why you are doing su - oracle and then doing nothing in that shell. What is your goal here? May 15, 2015 at 12:44
  • goal is to execute commands after expect part withinin the shell invoked with su - oracle
    – klerk
    May 15, 2015 at 12:56
  • Then you have no choice but to expand your expect script. When your funct function returns, the "su" shell has been closed. I'll throw some ideas into an answer May 15, 2015 at 13:36

3 Answers 3

2

This is largely untested. The aim is to send the commands you want to run as user "oracle" to the function as a parameter, and then get those to execute within the expect session.

This uses single-quoted here-docs to contain both the commands you want to run as oracle and the expect body, so take care to match the quoting I'm demonstrating here.

#!/bin/bash
set -ex

as_oracle() {
    local pass="the_password"
    local cmds=$(cat -)         # read the oracle commands from stdin

    # quoting in the next line is very important
    expect -f - "$pass" "$cmds" <<'END_EXPECT'
        lassign $argv pass3 commands

        spawn su - oracle
        expect "Password:"
        send -- "$pass3\r"

        # this is the regular expression that matches the end
        # of oracle's prompt: please change it if it's not correct
        set prompt {\$ $}

        expect -re $prompt
        send -- "eval \"$commands\"\r"
        expect -re $prompt
        send -- "exit\r"
        expect eof
END_EXPECT
}


as_oracle <<'END_ORACLE'
    var_ulimit=$(ulimit -Ha | awk '/open files/ {print $4}')
    echo $var_ulimit
END_ORACLE

I'm not certain that eval is the way to execute those commands. This may be better:

send -- ". <(echo \"$commands\")\r"
1

The last two commands will never be executed in the shell of the oracle user. Try that:

expect -c "
  log_user 0
  spawn su - oracle -c \"ulimit -Hn\"
  expect \"Passwort:\"
  send \"$pass3\n\"
  expect eof
  puts \"\$expect_out(buffer)\"
"

Also assuming that you only want the open files limit, with the -n flag (no need to grep, awk, ...).

2
  • it's not important what is after expect. you are saying that it is not possible to execute anything in oracle user shell ? any trick ?
    – klerk
    May 15, 2015 at 12:23
  • @klerk You can call the command within expect itself. send "your_command"...
    – chaos
    May 15, 2015 at 12:28
0

Create a new script file for your expect script like "expect.sh". And call it in your bash script:

./expect.sh

Now your expect script will work in your bash script.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .