簡體   English   中英

如何使用Expect內部循環遍歷Bash數組?

[英]How to loop over Bash array using expect inside?

我正在嘗試遍歷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

您的任何建議將不勝感激! 提前致謝!

內心期待

  • 您可以使用$env(PASSPHRASE)獲得環境變量。
  • 您已經在全局范圍內了,所以global ::env是多余的(實際上對於完全合格的::env是雙重的)。

猛烈地

  • 將行讀入數組中

     mapfile PLIST < <(find "$PPATH" -name "*.rpm") 
  • 擺脫使用ALLCAPSVARNAMES的習慣,如果不小心使用“保留”變量名,可能會惹上麻煩。

  • -s使用read選項-e似乎很奇怪-很難編輯看不見的內容。
  • “數組”是數組元素的較差的變量名。

在您的情況下,PLIST不是數組,您需要將其轉換為數組。 將下面的行放在for循環之前(第6行)

PLIST=( $PLIST )

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM