2

I want to open a Unix domain socket for both reading and writing from an AWK script. I'm using Gnu AWK.

Accoring to this guide, ordinary sockets could be opened as "/net-type/protocol/local-port/remote-host/remote-port", where "net-type" is inet4 or inet6. But could Unix domain sockets be opened this way? I found nothing in the manual.

Anyway, this is what I tried. I want to write "status 3" command in the Unix socket and read the output back.

    serv = "/var/etc/openvpn/serv.sock";

    printf("status 3\n") |& ("nc -U " serv)

    printf("wrote status command into serv.sock\n");
    getline ans < serv

    printf("ans = %s\n", ans);

But it doesn't read the data back.

    $ gawk -f bwlimit.awk db.txt
    wrote status command into serv.sock
    newdata =
Javad Kouhi
  • 135
  • 4
  • 1
    not something I've done myself but you might want to try `do { print data |& "subprogram"; "subprogram" |& getline results } while (data left to process) close("subprogram")` as described at https://www.gnu.org/software/gawk/manual/html_node/Two_002dway-I_002fO.html#Two_002dway-I_002fO after setting `subprogram="nc -U " serv`. – Ed Morton Jun 12 '19 at 09:43
  • 1
    `awk` is text operator/command, and sockets are networking level operators. Better not mix. I suggest you use `netcat` command also known as `nc` to test your socket on the command line. When successful integrate `netcat` commands into `awk` script. – Dudi Boy Jun 12 '19 at 17:11
  • I agree with the two comments above. In addition to netcat, socat is also excellent and capable of talking to UNIX domain sockets. See http://www.dest-unreach.org/socat/ – terafl0ps Aug 20 '20 at 18:25

1 Answers1

0

You have +/-2 syntax errors. In Awk, you almost never want to enclose strings with (…). Plus, instead of getline ans < serv, in Gawk the correct way to read from a socket or coprocess is socket |& getline [var].

Let's create an application that answers all lines received at $serv with "got …":

fifo="/tmp/fifo" ; mkfifo "$fifo"
cat "$fifo" | nc -l -U "$serv" | sed -u "s/^/got /" | tee -a "$fifo"

Now the following GNU Awk

BEGIN {
    serv = "/var/etc/openvpn/serv.sock"

    printf "status 3\n" |& "nc -U " serv

    printf "wrote status command into serv.sock\n"
    "nc -U " serv |& getline ans

    printf "ans = %s\n", ans
}

will give

$ gawk -f servsock.awk
wrote status command into serv.sock
ans = got status 3
xebeche
  • 905
  • 7
  • 20