如何在expect内部循环使用Bash数组?

时间:2016-02-25 01:21:33

标签: arrays bash loops expect eof

我正在尝试遍历Bash数组(包列表),并在循环内部使用一些expect命令来自动化交互式输入。

脚本应该提出几个问题来提供密码短语和存储rpm包的路径。之后,阵列由列表形成,并且循环以签署rpm包(使用expect代码进行自动密码输入)并将包推送到RedHat Satellite。

循环无效,我无法将数组正确导出到expect

```在Glenn建议之后更新了代码。

#/bin/bash
read -srep $'Please, insert passphrase:\n\n' PASSPHRASE
read -rep $'Please, provide a path for your package(s) being signed and  pushed:\#n\n' PPATH
mapfile PLIST < <(find "$PPATH" -name "*.rpm")
export PASSPHRASE PLIST
for package in "${PLIST[@]}"
do
        echo "$package"
        export package
        /usr/bin/expect<<EOF 

        set force_conservative 0 ;
                             ;
        set filename [lindex $argv 0]
        set timeout -1
        spawn rpm --resign $::env(package)
        close $spawn_id
        expect "*phrase:"
        send -- "$PASSPHRASE\r" 
        expect eof
EOF
done
unset PASSPRASE

这就是我得到的:

spawn rpm --resign x86_64/myrpm9.rpm

expect: spawn id exp4 not open
    while executing
"expect "*phrase:""

spawn rpm --resign x86_64/myrpm1.rpm

expect: spawn id exp4 not open
    while executing
"expect "*phrase:""

更新2: 我继续努力解决这个问题,试图解决这个问题。为方便起见,我对bash变量进行了硬编码。我几乎想通了,显然不工作的东西仍然是来自bash的环境变量。 expect脚本正确地解释它,但是如果我用文件名替换变量,它会以某种方式产生' 无法访问文件 '(意味着它找不到文件)。

#/bin/bash
PASSPHRASE="IamPass"
PPATH="/home/user/strcompat-debuginfo-0.9.2.7-1.x86_64.rpm"
mapfile PLIST < <(find "$PPATH" -name "*.rpm")
export PASSPHRASE PLIST
for package in "${PLIST[@]}"
do
        export package
        /usr/bin/expect -d  <<EOF 
        set force_conservative 0 ;
        set filename [lindex $argv 0]
        set timeout -1
        spawn rpm --resign $::env(package)
        expect {  "*phrase:"
        { send -- "$PASSPHRASE\r"; incr i; exp_continue }
        eof exit
        }
EOF
done

调试模式下的输出:

[user@linuxbox ~]$ ./script.sh 
expect version 5.44.1.15
argv[0] = /usr/bin/expect  argv[1] = -d  
set argc 0
set argv0 "/usr/bin/expect"
set argv ""
executing commands from command file
spawn rpm --resign /home/user/strcompat-debuginfo-0.9.2.7-1.x86_64.rpm

parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {18487}

expect: does "" (spawn_id exp4) match glob pattern "  "*phrase:"\n\t{ send -- "IamPass\r"; incr i; exp_continue }\n\t# close \n\teof exit\n\t"? no
cannot access file /home/user/strcompat-debuginfo-0.9.2.7-1.x86_64.rpm


expect: does "cannot access file /home/user/strcompat-debuginfo-0.9.2.7-1.x86_64.rpm\r\n\r\n" (spawn_id exp4) match glob pattern "  "*phrase:"\n\t{ send -- "IamPass\r"; incr i; exp_continue }\n\t# close \n\teof exit\n\t"? no
expect: read eof
expect: set expect_out(spawn_id) "exp4"
expect: set expect_out(buffer) "cannot access file /home/user/strcompat-debuginfo-0.9.2.7-1.x86_64.rpm\r\n\r\n"

正常输出:

[user@linuxbox ~]$ ./script.sh 
spawn rpm --resign /home/user/strcompat-debuginfo-0.9.2.7-1.x86_64.rpm

cannot access file /home/user/strcompat-debuginfo-0.9.2.7-1.x86_64.rpm

[user@linuxbox ~]$ echo $?
0

任何你的建议将不胜感激! 提前谢谢!

2 个答案:

答案 0 :(得分:1)

内心期待,

  • 您获得了$env(PASSPHRASE)的环境变量。
  • 您已经在全球范围内,因此global ::env是多余的(实际上是完全限定的::env的双重冗余)。

在bash中,

  • 将行读入您将要执行的数组

    mapfile PLIST < <(find "$PPATH" -name "*.rpm")
    
  • 摆脱使用ALLCAPSVARNAMES的习惯,如果您不小心使用“保留”变量名称,可能会让您遇到麻烦。

  • 将阅读选项-e-s一起使用似乎很奇怪 - 很难编辑您看不到的内容。
  • “array”是数组的元素的不良变量名。

答案 1 :(得分:0)

在您的情况下,PLIST不是数组,您需要将其转换为数组。将下面的行放在for循环(第6行)之前

PLIST=( $PLIST )