使用 Bash 编程进行 Netcat TCP 编程

7

我正在尝试使用纯粹的bash脚本进行基础TCP客户端通信。我可以使用netcat,因此我迄今为止编写了以下循环:

nc 10.0.0.104 4646 | while read line
do
   if [ "$line" == '{"cmd": 1}' ]
   then
      # Send text back to the TCP server
      echo '{"error": 0}'
   fi
done

脚本可以成功连接到我正在使用的服务器应用程序,但我很难弄清楚如何将文本发送回netcat进程。
1个回答

6

如果您使用Bash≥4,可以使用coproc

#!/bin/bash

coproc nc { nc 10.0.0.104 4646; }

while [[ $nc_PID ]] && IFS= read -r -u${nc[0]} line; do
    case $line in
        ('{"cmd": 1}')
            printf >&${nc[1]} '%s\n' '{"error": 0}'
            ;;
        (*)
            printf >&2 '%s\n' "Received line:" "$line"
            ;;
    esac
done

这样可以避免使用临时的fifo。没有coproc,我猜唯一的选择就是显式地使用fifo了。以下是一个例子:

#!/bin/bash

mkfifo fifo_in

while IFS= read -r line; do
    case $line in
        ('{"cmd": 1}')
            printf '%s\n' '{"error": 0}'
            ;;
        (*)
            printf >&2 '%s\n' "Received line:" "$line"
            ;;
    esac
done < <(nc 10.0.0.104 4646 < fifo_in) > fifo_in

对于此任务,您需要管理fifo的创建和删除:您需要使用 mktemp 创建一个临时目录,在其中创建fifo,然后使用trap命令使脚本在退出时清理所有内容。


/dev/tcp

如果您的Bash已经编译了网络重定向支持,则可以完全摆脱nc,以及fifos和协处理器:

#!/bin/bash

# open TCP connection, available on file descriptor 3
exec 3<> /dev/tcp/10.0.0.104/4646 || exit

while IFS= read -r -u3 line; do
    case $line in
        ('{"cmd": 1}')
            printf >&3 '%s\n' '{"error": 0}'
            ;;
        (*)
            printf >&2 '%s\n' "Received line:" "$line"
            ;;
    esac
done

这很可能是最甜美的解决方案!


1
很好的东西。如果 O.P. 不能使用 bash 4,这些功能在 ksh 中已经存在了几年。但这取决于可用的 ksh 版本,但值得测试。O.P. 可以避免在生产环境中安装新的东西。祝大家好运。 - shellter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接