1

I have the following bash script with an embedded expect script:

#!/bin/bash

if [ ! $# == 2 ]
  then
    echo "Usage: $0 os_base_version sn_version"
    exit
fi

if [ -e /some/file/path/$10AS_26x86_64_$2_*.bin ]
  then
    filename="/some/file/path/$10AS_26x86_64_$2_*.bin"
    echo ${filename}
else
  echo "install archive does not exist."
  exit
fi

{
  /usr/bin/expect << EOD
  set timeout 20
  spawn "${filename}"

  expect {
      "Press Enter to view the End User License Agreement" {
          send "\r"
          exp_continue
      }
      "More" {
          send " "
          exp_continue
      }
      "Do you accept the End User License Agreement?" {
          send "y\r"
      }
  }
  interact
  expect eof
EOD
}

In the folder are several files in the format {x}0AS_26x86_64_{x.x.x}_{rev}.bin

When I run the script, I get the correct filename on the first echo. But when I try to pass this to the expect script using ${filename}, the filename expansion is gone.

Sample output:

# ./make.sh 2 1.2.3
/some/file/path/20AS_26x86_64_1.2.3_45678.bin
spawn /some/file/path/20AS_26x86_64_1.2.3_*.bin
couldn't execute "/some/file/path/20AS_26x86_64_1.2.3_*.bin": no such file or directory
    while executing
"spawn /some/file/path/20AS_26x86_64_1.2.3_*.bin"

As you can see the $filename shows correct with the echo, but not inside the expect part.

Edit:

Just run the script with -x, and it looks like the filename variable never get the full filename expansion, only the echo does.

# ./make.sh 2 1.2.3
+ '[' '!' 2 == 2 ']'
+ '[' -e /some/file/path/20AS_26x86_64_1.2.3_45678.bin ']'
+ filename='/some/file/path/20AS_26x86_64_1.2.3_*.bin'
+ echo /some/file/path/20AS_26x86_64_1.2.3_45678.bin
/some/file/path/20AS_26x86_64_1.2.3_45678.bin
+ exit
2

You are never actually assigning a specific filename to the variable. What you are doing is setting the variable to a glob pattern. Then, when you pass the variable to echo, the glob pattern is expanded, so you see your file's name pritned. However, the variable has never been set to a specific file name.

So, you need a better way of getting the file name. Something like:

#!/bin/bash

## Make globs that don't match anything expand to a null
## string instead of the glob itself
shopt -s nullglob
## Save the list of files in an array
files=( /some/file/path/$10AS_26x86_64_$2_*.bin )
## If the array is empty
if [ -z $files ]
then
    echo "install archive does not exist."
    exit
## If at least one file was found    
else
    ## Take the first file 
    filename="${files[0]}"
    echo "$filename"
fi

{
  /usr/bin/expect << EOD
  set timeout 20
  spawn "${filename}"

  expect {
      "Press Enter to view the End User License Agreement" {
          send "\r"
          exp_continue
      }
      "More" {
          send " "
          exp_continue
      }
      "Do you accept the End User License Agreement?" {
          send "y\r"
      }
  }
  interact
  expect eof
EOD
}
  • Thanks, I will give this a try. In the meantime I have a "hacky" workorund: set -- /some/file/path/$10AS_26x86_64_$2_*.bin filename=("$@") – derchris Nov 1 '15 at 19:04
  • Just tested it, works perfectly. And much better than my "workaround" approach. Thanks. – derchris Nov 1 '15 at 19:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.