我有一个 bash 脚本,我在其中连续从文本文件读取主机和端口并创建连接以检查状态。
我的代码是:
while IFS=";" read -r host ports
do
eval "arr=($ports)"
for port in "${arr[@]}";
do
echo "connecting to $host on port $port" >> output.txt
timeout 5s telnet $host $port
exit_status=$?
if [[ $exit_status -eq 124 ]]; then
echo "$host on $port has timed out" >> output.txt
else
telnet $host $port >> output.txt
fi
echo "---------------------------------------------" >> output.txt
done
done < "$1"
首先if
是检查连接是否超时。这按预期工作。
else
在-中telnet $host $port
,我检查连接是否没有超时,然后telnet
进入远程主机以查看连接是否超时成功的或者拒绝。
但是,当连接成功的, 剧本退出突然吐出:
Escape character is '^]'.
Connection closed by foreign host.
我希望它写入输出文件,“连接成功”并继续读取 $1 的剩余部分。
当连接被拒绝时,脚本不会退出;它按预期工作——它继续从 $1 读取并继续运行指令。
我也遇到了无法使用的情况netcat
。
答案1
作为罗艾玛指出,telnet 命令将吸收您已重定向到while
循环中的 stdin 输入。因此,一旦其中一个 telnet 连接成功,您的while
循环就会结束,因为telnet
您期望输入的其余输入被吞噬while
。
该问题的直接解决方案是重定向telnet
的输入,最简单的是从 /dev/null 重定向,如下赛勒斯评论: telnet host port >> output.txt < /dev/null
。
为了区分成功的连接和(可能延迟超过 5 秒)拒绝的连接,我捕获了 telnet 命令的输出并检查了“ Connected to
”消息。如果该消息存在,我们就假设成功;否则:失败。
对脚本的主要更改是:
telnet
从 /dev/null重定向两者的 stdin- 引用所有变量
- 捕获并检查
else
输出telnet
以进行比较
更新后的脚本:
#!/bin/bash
while IFS=";" read -r host ports
do
eval "arr=($ports)"
for port in "${arr[@]}";
do
echo "connecting to $host on port $port" >> output.txt
timeout 5s telnet "$host" "$port" < /dev/null
exit_status=$?
if [[ "$exit_status" -eq 124 ]]; then
echo "$host on $port has timed out" >> output.txt
else
output="$(telnet "$host" "$port" 2>&1 < /dev/null)"
case $output in
(*Connected\ to\ *)
echo "connection is successful to $host $port" >> output.txt
;;
(*)
echo "connection was refused to $host $port" >> output.txt
;;
esac
fi
echo "---------------------------------------------" >> output.txt
done
done < "$1"
答案2
这两个telnet
命令都会尝试读取$1
文件的剩余部分,无论它是什么。因此,您的循环的执行次数可能会意外减少。
我不确定您希望提供什么输入telnet
。
顺便说一句,如果您安装了它,最好使用netcat
(有时称为nc
)。它不会解决更改输入问题,但它通常是这种脚本交互的更好工具。
答案3
我使用类似的东西,但它用于远程访问。如果我能让重定向正常工作,那就更干净了。
偏僻的:
ssh -q USERNAME@HOSTSERVER 'echo -e "\x1dclose\x0d" | telnet REMOTESERVER PORT'|grep Connected>/dev/null && printf "PASSED\n"||printf "FAILED\n"
当地的:
echo -e "\x1dclose\x0d" | telnet REMOTESERVER PORT|grep Connected>/dev/null && printf "PASSED\n"||printf "FAILED\n"