在bash中实现netcat

5

作为我正在编写的一个更大脚本的基础,我正在尝试在bash中实现一个基本的netcat客户端。我的当前脚本在技术上是可行的,它看起来像这样:

#!/bin/bash

exec 3<>/dev/tcp/$1/$2         

cat <&3 &                      
cat <&1 >3

这个问题的困扰在于它会留下一个“悬挂”的cat进程,需要手动杀死。但我无法找到一种自动化的方法来解决这个问题,而手动运行pkill cat似乎也不太方便。

3个回答

7

我已经接受Jeremy的答案为正确答案, 但是对于任何好奇的人, 这里是我最终使用的完整脚本:

#!/bin/bash

exec 3<>/dev/tcp/$1/$2         

control_c()
{
    kill $CAT_PID
    exit $?
}

trap control_c SIGINT

cat <&3 &                      
CAT_PID=$!
cat >&3

1
点赞您发布的可行解决方案。当人们这样做时,这非常棒! - Jeremy J Starcher
1
谢谢!我做了差不多一样的事情,但是使用pkill -P $$代替捕获PID,并在结尾处添加了一个额外的pkill -P $$来捕获客户端关闭的连接(这导致一个被放弃的cat会挂在那里一段时间)。 - Mark
1
在脚本末尾添加一个“等待”命令,以防止脚本在远程端发送响应之前退出。否则,当标准输入流关闭时,cat 命令将会被弃用。 - tylerl

4

这是一种可怕的方法,但你可以生成一个子shell并执行以下操作:

CAT1_PID=$$
echo CAT1_PID > /tmp/CAT1_PID
exec cat <&3 &

当然,如果多个副本运行此脚本,则会遇到竞态条件。

根据您的shell,您可以调用某种形式的exec并在PS列表中“重命名”cat。然后您就可以

pkill the_cat_that_ate_the_network

你知道在我使用control-c终止脚本时自动调用pkill的方法吗? - Mediocre Gopher
我已经有一段时间没有进行真正的脚本编写了,所以我必须依赖全能的谷歌。如果您正在使用 bash,那么可以尝试这个。Bash Trap最近我发现了许多不同的shell变体作为默认shell,所以请确保您的 #! 指向正确的位置。 - Jeremy J Starcher

0
只是一个后续的问题...
whois() {
        (
                exec 3<>/dev/tcp/whois.ripe.net/43
                echo "$*" >&3
                cat <&3
        )
}

万一你有一个非常简单的协议(比如WHOIS),我来给你提供一下。

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