LordZardeck
LordZardeck

Reputation: 8283

How to use Expect in a Bash script

I am trying to write a script that pulls the latest version of my software from a Git repository and updates the configuration files. When pulling from the repository though, I have to enter a password. I want the script to automate everything, so I need it to automatically fill it in for me. I found this site that explained how to use Expect to look for the password prompt and send the password. I can't get it to work though.

Here's my script:

#!/usr/bin/expect -f
set password [lrange $argv 0 0]
set timeout -1

clear
echo "Updating Source..."
cd sourcedest
git pull -f origin master

match_max 100000
# Look for passwod prompt
expect "*?assword:*"
# Send password aka $password
send -- "$password\r"
# send blank line (\r) to make sure we get back to gui
send -- "\r"
expect eof

git checkout -f master
cp Config/database.php.bak Config/database.php
cp webroot/index.php.bak webroot/index.php
cp webroot/js/config.js.bak webroot/js/config.js

What am I doing wrong?

Here's the site I got it from: http://bash.cyberciti.biz/security/expect-ssh-login-script/

Upvotes: 9

Views: 37616

Answers (2)

tumelo dlodlo
tumelo dlodlo

Reputation: 11

If you want Application service automation. Use the autoexpect command to generate your expect script workflow.

Create a file: interactive_git_script.sh Save your git code inside it:

    #! /bin/bash
    
    # interactive git script

    git pull -f origin master
    git checkout -f master

Then generate your expect script with these commands:

    # run this in bash commandline
    chmod u+x interactive_git_script.sh

    # run this in bash commandline and answer
    #+    all the interactive prompts you are
    #+    interested in
    autoexpect ./interactive_git_script.sh

The generated file is called script.exp Refactor your code or the generated script.exp. Then create a new file called main.sh with with content:

    #! /bin/bash

    # my simple and repeatable 
    #+    deployment tasks

    chmod u+x script.exp
    ./script.exp
    cp Config/database.php.bak Config/database.php
    cp webroot/index.php.bak webroot/index.php
    cp webroot/js/config.js.bak webroot/js/config.js

Then run your app on the bash command line:

    # run command 1 on command line
    chmod u+x main.sh
    # run command 2 on command line
    ./main

Upvotes: 0

Tim Pote
Tim Pote

Reputation: 28029

This is pretty much taken from the comments, with a few observations of my own. But nobody seems to want to provide a real answer to this, so here goes:

Your problem is you have an Expect script and you're treating it like a Bash script. Expect doesn't know what cd, cp, and git mean. Bash does. You want a Bash script that makes a call to Expect. For example:

#!/usr/bin/env bash

password="$1"
sourcedest="path/to/sourcedest"
cd $sourcedest

echo "Updating Source..."
expect <<- DONE
  set timeout -1

  spawn git pull -f origin master
  match_max 100000

  # Look for password prompt
  expect "*?assword:*"
  # Send password aka $password
  send -- "$password\r"
  # Send blank line (\r) to make sure we get back to the GUI
  send -- "\r"
  expect eof
DONE

git checkout -f master
cp Config/database.php.bak Config/database.php
cp webroot/index.php.bak webroot/index.php
cp webroot/js/config.js.bak webroot/js/config.js

However, as larsks pointed out in the comments, you might be better off using SSH keys. Then you could get rid of the expect call altogether.

Upvotes: 23

Related Questions