You are not logged in.

#1 2021-09-15 02:45:33

leanhtai01
Member
Registered: 2017-04-23
Posts: 19

Wait until expect spawn process end before continue bash script

Here is my full script:

#!/bin/bash

set -e

prefix=

if [ ! -z $1 ] && [ $1 = "in_chroot" ]
then
    prefix="arch-chroot /mnt "
else
    prefix="sudo "
fi

INSTALL_KVM=$($prefix expect -c "
set pid [spawn pacman -Syu --needed virt-manager qemu vde2 dnsmasq bridge-utils virt-viewer dmidecode edk2-ovmf cockpit cockpit-machines iptables-nft]

expect \":: iptables-nft and iptables are in conflict. Remove iptables? \[y/N\]\"
send \"y\r\"

expect eof

expect \":: Proceed with installation? \[Y/n\]\"
send \"y\r\"

expect eof

wait $pid
")

echo "${INSTALL_KVM}"

$prefix systemctl enable libvirtd
$prefix systemctl enable cockpit.socket

$prefix sed -i "/^#unix_sock_group = \"libvirt\"$/s/^#//" /etc/libvirt/libvirtd.conf
$prefix sed -i "/^#unix_sock_rw_perms = \"0770\"$/s/^#//" /etc/libvirt/libvirtd.conf
$prefix gpasswd -a $2 libvirt
$prefix gpasswd -a $2 kvm

Information:
1. Purpose of my script: install and configure KVM in running system (using sudo) and when install OS (using arch-chroot)
2. expect (come from https://archlinux.org/packages/extra/x86_64/expect/), and spawn command provide by expect.
3. Purpose when I use expect: to say yes to package conflict prompt.

INSTALL_KVM=$($prefix expect -c "
set pid [spawn pacman -Syu --needed virt-manager qemu vde2 dnsmasq bridge-utils virt-viewer dmidecode edk2-ovmf cockpit cockpit-machines iptables-nft]

expect \":: iptables-nft and iptables are in conflict. Remove iptables? \[y/N\]\"
send \"y\r\"

expect eof

expect \":: Proceed with installation? \[Y/n\]\"
send \"y\r\"

expect eof

wait $pid
")

4. Line echo "${INSTALL_KVM}" just to display the output from process spawn by expect

Problem: When I run the script, it seem process spawn by expect didn't end probably before continue the script. After read expect  manpage I come up with a solution using wait (inside expect ). But sometime the script run successfully, sometime it hang forever, sometime command spawn by expect didn't end probably

Last edited by leanhtai01 (2021-09-15 12:51:46)

Offline

#2 2021-09-15 03:36:37

Xyne
Administrator/PM
Registered: 2008-08-03
Posts: 6,963
Website

Re: Wait until expect spawn process end before continue bash script

We need more information to debug this:

  • What is the "spawn" command and what package provides it?

  • What is "$prefix"? (I'm guessing "sudo" or something similar?)

  • Do you actually need to invoke the pacman process in a subshell and save the output to INSTALL_KVM just to echo it later? If it's not used anywhere else in the script, omit it.

  • What is the output of 'echo "${INSTALL_KVM}"' just before PART 2?

Something in "$prefix expect..." is backgrounding the process but it's not obvious why. There may be something in $prefix or in your configuration of expect that is causing it. You need to either reconfigure it to not background the process, or capture the PID and use "wait" to wait for it to finish. Normally you can use the variable "$!" but it will not be set outside of the subshell for a background process within the subshell.

Btw, "systemctl enable --now foo" is equivalent to "systemctl enable foo; systemctl start foo".


My Arch Linux StuffForum EtiquetteCommunity Ethos - Arch is not for everyone

Offline

#3 2021-09-15 07:55:23

Raynman
Member
Registered: 2011-10-22
Posts: 1,539

Re: Wait until expect spawn process end before continue bash script

@Xyne: That looks like an Expect script and spawn is provided by expect.

I have never used expect before. My first thought was that you should use its `wait` command at the end, but `expect eof` also seems like a sort of `wait`ing. I did a quick web search and found that expect has a timeout that you need to handle when dealing with long-running processes. The simplest solution seems to be turning off the timeout:

expect -timeout -1 eof

Example of explicitly handling timeout: https://stackoverflow.com/a/29896507

Why is there a second `expect eof` in the middle? That seems wrong.

Edit: discussion of alternatives to using expect: https://bbs.archlinux.org/viewtopic.php?id=233231

Last edited by Raynman (2021-09-15 07:58:01)

Offline

#4 2021-09-15 12:49:44

leanhtai01
Member
Registered: 2017-04-23
Posts: 19

Re: Wait until expect spawn process end before continue bash script

@Xyne: Sorry for provided missing information, I have updated my question.
@Raynman: Thank for the hint. I tried turn of the timeout but it make my script hang forever.

Offline

#5 2021-09-15 12:56:15

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,514
Website

Re: Wait until expect spawn process end before continue bash script

Why do you have two "expect eof" lines?  I also don't have first-hand experience with expect, but it looks like those lines would make it wait for the "eof" or end of output from the spawned command.  But if you do that *before* the "proceed with installation" line, the proceed with installation line will never be processed by expect, so pacman will still be waiting for a confirmation.

The nested quotes also make me wonder what might happen with the \r, would it need to be \\r?  And why \r and not \n??  All the quote concerns could be remedied by using a single quote for the outer quotes and double quotes internally, e.g.

INSTALL_KVM=$($prefix expect -c '
## do stuff here like the following
#  expect "y\r"
## or perhaps
# expect "y\n"
')

Last edited by Trilby (2021-09-15 12:59:28)


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

Board footer

Powered by FluxBB