0

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?

user1128677
  • 479
  • 2
  • 11
  • 18

2 Answers2

1

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
KamilCuk
  • 120,984
  • 8
  • 59
  • 111
  • Lmao, ty so much, i've just removed that line and it worked. And i'll think about second solution too – user1128677 Mar 05 '22 at 19:27
  • As this require [tag:bash], you could `wireguard-install.sh < <(read -t .01 _;printf '%s\n' 51822 clientcustom 2 y')` – F. Hauri - Give Up GitHub Mar 06 '22 at 10:02
  • I'm not sure `IFS= read -ru $FD line` will terminate when `read -p "IPv4 address [1]: " ip_number` send *prompt* **without** newline!! – F. Hauri - Give Up GitHub Mar 06 '22 at 10:07
  • Typo: in my [1st comment](https://stackoverflow.com/questions/71365216/bash-filling-user-read-input-automatically-with-param-list#comment126149722_71365288), there was a trailing unwanted quote (`'`).... And another syntax: `bash <(sed /read\ -N\ 999999/d wireguard-install.sh) < <(printf %s\\n 51822 clientcustom 2 y)` – F. Hauri - Give Up GitHub Mar 06 '22 at 10:57
  • Have a look at [my expect bash functon](https://stackoverflow.com/a/70411122/1765658) where `exp1` read input **byte by byte** for handlng lines without *newline*!! – F. Hauri - Give Up GitHub Mar 06 '22 at 11:05
1

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
)
F. Hauri - Give Up GitHub
  • 64,122
  • 17
  • 116
  • 137