如何编写一个linux bash脚本,告诉我哪些计算机在我的局域网中处于打开状态?

Dum*_*ner 32 linux bash ping

如何编写一个linux bash脚本,告诉我哪些计算机在我的局域网中处于打开状态?

如果我可以将其作为输入提供一系列IP,这将有所帮助.

dbr*_*dbr 77

我建议使用nmap的ping-scan标志,

$ nmap -sn 192.168.1.60-70

Starting Nmap 4.11 ( http://www.insecure.org/nmap/ ) at 2009-04-09 20:13 BST
Host machine1.home (192.168.1.64) appears to be up.
Host machine2.home (192.168.1.65) appears to be up.
Nmap finished: 11 IP addresses (2 hosts up) scanned in 0.235 seconds
Run Code Online (Sandbox Code Playgroud)

也就是说,如果你想自己写(这很公平),我就是这样做的:

for ip in 192.168.1.{1..10}; do ping -c 1 -t 1 $ip > /dev/null && echo "${ip} is up"; done
Run Code Online (Sandbox Code Playgroud)

..以及上述命令的每一位的解释:

生成IP地址列表

您可以使用{1..10}语法生成数字列表,例如..

$ echo {1..10}
1 2 3 4 5 6 7 8 9 10
Run Code Online (Sandbox Code Playgroud)

(它也用于东西等是有用的mkdir {dir1,dir2}/{sub1,sub2}-这使得dir1dir2,每个都包含sub1sub2)

因此,要生成IP列表,我们会做类似的事情

$ echo 192.168.1.{1..10}
192.168.1.1 192.168.1.2 [...] 192.168.1.10
Run Code Online (Sandbox Code Playgroud)

循环

要在bash中循环某些内容,请使用for:

$ for thingy in 1 2 3; do echo $thingy; done
1
2
3
Run Code Online (Sandbox Code Playgroud)

Ping操作

接下来,ping .. ping命令与不同的操作系统,不同的发行版/版本(我目前使用OS X)有所不同

默认情况下(再次,在OS X版本上ping),它将ping到中断,这对此不起作用,因此ping -c 1只会尝试发送一个数据包,这应该足以确定机器是否已启动.

另一个问题是超时值,在这个版本的ping上似乎是11秒.它使用-t标志更改.一秒应足以查看本地网络上的计算机是否存活.

所以,我们将使用的ping命令是..

$ ping -c 1 -t 1 192.168.1.1
PING 192.168.1.1 (192.168.1.1): 56 data bytes

--- 192.168.1.1 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss
Run Code Online (Sandbox Code Playgroud)

检查ping结果

接下来,我们需要知道机器是否回复了..

&&如果第一个成功,我们可以使用运算符运行命令,例如:

$ echo && echo "It works"

It works
$ nonexistantcommand && echo "This should not echo"
-bash: nonexistantcommand: command not found
Run Code Online (Sandbox Code Playgroud)

好,所以我们可以做..

ping -c 1 -t 1 192.168.1.1 && echo"192.168.1.1 up!"

另一种方法是使用ping中的退出代码.如果有效,则ping命令将以退出代码0(成功)退出,如果失败则退出非零代码.在bash中,您将获得最后一个带有变量的命令退出代码$?

所以,要检查命令是否有效,我们会做..

ping -c 1 -t 1 192.168.1.1;
if [ $? -eq 0 ]; then
    echo "192.168.1.1 is up";
else 
    echo "ip is down";
fi
Run Code Online (Sandbox Code Playgroud)

隐藏ping输出

最后一件事,我们不需要看平输出,所以我们可以重定向stdout/dev/null>重定向,例如:

$ ping -c 1 -t 1 192.168.1.1 > /dev/null && echo "IP is up"
IP is up
Run Code Online (Sandbox Code Playgroud)

要重定向stderr(丢弃ping: sendto: Host is down消息),您可以使用2>- 例如:

$ errorcausingcommand
-bash: errorcausingcommand: command not found
$ errorcausingcommand 2> /dev/null
$
Run Code Online (Sandbox Code Playgroud)

剧本

所以,结合所有......

for ip in 192.168.1.{1..10}; do  # for loop and the {} operator
    ping -c 1 -t 1 192.168.1.1 > /dev/null 2> /dev/null  # ping and discard output
    if [ $? -eq 0 ]; then  # check the exit code
        echo "${ip} is up" # display the output
        # you could send this to a log file by using the >>pinglog.txt redirect
    else
        echo "${ip} is down"
    fi
done
Run Code Online (Sandbox Code Playgroud)

或者,使用该&&方法,在单行中:

for ip in 192.168.1.{1..10}; do ping -c 1 -t 1 $ip > /dev/null && echo "${ip} is up"; done
Run Code Online (Sandbox Code Playgroud)

问题

它很慢..每个ping命令大约需要1秒钟(因为我们将-t timeout标志设置为1秒).它一次只能运行一个ping命令.显而易见的方法是使用线程,这样你就可以运行并发命令,但这超出了你应该使用bash的...

"Python线程 - 第一个例子"解释了如何使用Python线程模块编写多线程ping'er ..虽然在那时,我会再次建议使用nmap -sn..

  • ***慢拍*** (4认同)
  • `for ip in 192.168.1.{1..10}; do ping -c 1 -t 1 $ ip>/dev/null && echo"$ {ip} up up"&done; wait` (2认同)
  • 更新:`nmap -sP`现已弃用.`nmap -sn`是获取相同输出的当前选项. (2认同)

Tib*_*Ana 14

在现实世界中,您可以使用nmap来获得所需内容.

nmap -sn 10.1.1.1-255
Run Code Online (Sandbox Code Playgroud)

这将ping 10.1.1.1到10.1.1.255范围内的所有地址,并让您知道哪些地址的答案.

当然,如果您实际上想要将此作为bash练习,您可以为每个地址运行ping并解析输出,但这是另一个故事.


chb*_*urd 10

假设我的网络是10.10.0.0/24,如果我在广播地址上运行ping,就像

ping -b 10.10.0.255
Run Code Online (Sandbox Code Playgroud)

我将从该网络上的所有计算机得到答案,这些计算机没有阻止其ICMP ping端口.

64 bytes from 10.10.0.6: icmp_seq=1 ttl=64 time=0.000 ms
64 bytes from 10.10.0.12: icmp_seq=1 ttl=64 time=0.000 ms 
64 bytes from 10.10.0.71: icmp_seq=1 ttl=255 time=0.000 ms 
Run Code Online (Sandbox Code Playgroud)

所以你只需要提取第4列,例如awk:

ping -b 10.10.0.255 | grep 'bytes from' | awk '{ print $4 }'

10.10.0.12:
10.10.0.6:
10.10.0.71:
10.10.0.95:
Run Code Online (Sandbox Code Playgroud)

好吧,你会得到重复,你可能需要删除':'.

来自评论的编辑:-c选项限制了自脚本结束以来ping的数量,我们也可以限制自己的唯一IP

ping -c 5 -b 10.10.0.255 | grep 'bytes from' | awk '{ print $4 }' | sort | uniq
Run Code Online (Sandbox Code Playgroud)


d0k*_*d0k 8

还有fping:

fping -g 192.168.1.0/24
Run Code Online (Sandbox Code Playgroud)

要么:

fping -g 192.168.1.0 192.168.1.255
Run Code Online (Sandbox Code Playgroud)

或仅显示活着的主机:

fping -ag 192.168.1.0/24
Run Code Online (Sandbox Code Playgroud)

它并行ping主机,因此扫描速度非常快.我不知道包含fping在其默认安装中的发行版,但在大多数发行版中,您可以通过包管理器获取它.