user1128677
user1128677

Reputation: 479

bash: filling user read input automatically with param list

I'm trying to use Wireguard road-warrior script from here https://github.com/Nyr/wireguard-install

But i cant make it run in noninteractive mode with predefined parameters. I've read some other similar topics here about how to provide answers to bash "read", but suggestions from there doesn't work.

I've tried this:

# bash wireguard-install.sh < params
# printf '%s\n' 51822 clientcustom 2 y | bash wireguard-install.sh
# echo "51822 clientcustom 2 y" | bash wireguard-install.sh

in every case installer just uses default values. What am i doing wrong?

Upvotes: 0

Views: 125

Answers (2)

F. Hauri  - Give Up GitHub
F. Hauri - Give Up GitHub

Reputation: 70792

Some alternatives:

1. you could simply drop problematic line while running.

bash <(sed /read\ -N\ 999999/d wireguard-install.sh) < <(
    printf %s\\n 51822 clientcustom 2 y)

This will drop line used to

# Discard stdin. Needed when running from an one-liner which includes a newline
read -N 999999 -t 0.001

2. Instead of passing variables, you could edit script:

$ sed 's/^[ \o11]*read -p/   /p;d' wireguard-install.sh  | uniq
   "DNS server [1]: " dns
   "IPv4 address [1]: " ip_number
   "Public IPv4 address / hostname [$get_public_ip]: " public_ip
   "Public IPv4 address / hostname: " public_ip
   "IPv6 address [1]: " ip6_number
   "Port [51820]: " port
   "Name [client]: " unsanitized_client
   "Should automatic updates be enabled for it? [Y/n]: " boringtun_updates
   "Option: " option
   "Name: " unsanitized_client
   "Client: " client_number
   "Confirm $client removal? [y/N]: " remove
   "Confirm WireGuard removal? [y/N]: " remove

So you could prepare a sed string:

printf -v sedscr 's/read -p.* \(%s\) *$/\\1="%s"/;' port 51822 \
    unsanitized_client clientcustom     client_number 2     remove y

Then ensure all's ok:

sed -e "/read -N 99999/d;$sedscr" <wireguard-install.sh |
    diff -u wireguard-install.sh -

you will see some lines like

 # Discard stdin. Needed when running from an one-liner which includes a newline
-read -N 999999 -t 0.001
 
 # Detect OpenVZ 6
 if [[ $(uname -r | cut -d "." -f 1) -eq 2 ]]; then
@@ -235,15 +234,15 @@
    fi
    echo
    echo "What port should WireGuard listen to?"
-   read -p "Port [51820]: " port
+   port="51822"
    until [[ -z "$port" || "$port" =~ ^[0-9]+$ && "$port" -le 65535 ]]; do

And finally

bash <(
    printf -v sedscr 's/read -p.* \(%s\) *$/\\1="%s"/;' port 51822 \
    unsanitized_client clientcustom     client_number 2     remove y
    sed -e "/read -N 99999/d;$sedscr" <wireguard-install.sh
)

Upvotes: 1

KamilCuk
KamilCuk

Reputation: 140970

https://github.com/Nyr/wireguard-install/blob/master/wireguard-install.sh#L15

Indeed, this is a bit problematic. Typically, not caring, you would just:

( sleep 1; printf '%s\n' 51822 clientcustom 2 y ) | ...

A real robust solution, you would parse the output of the process to know when to write response, either with expect or Bash or something better.

coproc bash wireguard-install.sh
while IFS= read -r -u "${COPROC[0]}" line; do
    case "$line" in
    "IPv4 address [1]:"*) echo something >&"${COPROC[1]}"; ;;
    "other prompt"*) echo other stuff >&"${COPROC[1]}"; ;;
    "etc...") echo ... ;;
    esac
done

Upvotes: 1

Related Questions