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?

2 Answers 2

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
Sign up to request clarification or add additional context in comments.

5 Comments

Lmao, ty so much, i've just removed that line and it worked. And i'll think about second solution too
As this require bash, you could wireguard-install.sh < <(read -t .01 _;printf '%s\n' 51822 clientcustom 2 y')
I'm not sure IFS= read -ru $FD line will terminate when read -p "IPv4 address [1]: " ip_number send prompt without newline!!
Typo: in my 1st comment, 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)
Have a look at my expect bash functon where exp1 read input byte by byte for handlng lines without newline!!
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
)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.