【问题标题】:Bash script for notification when internet is accessible可访问 Internet 时用于通知的 Bash 脚本
【发布时间】:2016-02-25 16:48:21
【问题描述】:

我编写了这个 bash 脚本,以便在可以访问互联网时发出通知,但我不明白正在发生的许多事情。这是脚本:

while ! ping 8.8.8.8 -c 1 2&> /dev/null ; do true; done;
  • -c 1 选项告诉ping 我只想发送一个数据包。
  • 2&> /dev/null 存在是因为我不想看到输出。
  • true 存在是因为 bash 不接受 do; 语法。
  • 终止条件是! ping ...,因为pingtimeout之前没有收到任何数据包时返回非零状态码。

预期的行为是当ping 成功时此循环结束并且终端仿真器将自动向我发送通知。


问题

  • 即使可以访问 Internet,此命令也不会结束。
  • 尝试用ctrl + C 终止命令不起作用。我认为它正在杀死子命令 ping 而不是整个命令。
  • 只有删除 2&> /dev/null 才能使一切正常,除了将输出写入终端的小问题。

问题

  1. 我的命令有什么问题?
  2. 终端仿真器对ctrl + C 的反应究竟如何?
  3. 为什么删除 2&> /dev/null 会起作用?

请注意,我已经有了转机。不过我还是想多了解一下bash

f() { while ! ping 8.8.8.8 -c 1 ; do true; done; }; f 2&> /dev/null

【问题讨论】:

  • 我的 ping 版本需要 ping -c 1 8.8.8.8 。 Pluse-uno 用于探索您的问题!祝你好运。

标签: bash shell terminal-emulator


【解决方案1】:

正确的重定向运算符是&>,而不是2&>。 2 被解析为 ping 的单独参数,并且由于 ping 2 永远不会成功,因此循环永远不会存在。

【讨论】:

  • * 我的错。我没有使用这种更冗长的语法2>&1。 * 你没有解释Ctrl + C 的问题。 Ctrl+C 是杀死 ping 命令而不是循环吗?因为根据您的建议 (&>),当没有网络时(当 ping 失败时),该命令是 ctrl-c-interrupt-able。
  • Ctrl+C 向当前前台作业发送中断,可能是ping,也可能是shell,具体取决于您实际键入的时间。
  • 这并不能真正解释发生了什么。修复重定向问题后,命令变为 ctrl-c-interupptible。如果您考虑到大部分时间将用于等待 ttl 过期。所以我的 Ctrl + C 捕捉到 shell 正在执行的短暂时刻的概率为空。
  • 没关系。将 8.8.8.8 更改为本地网络中未使用的地址后。使用 Ctrl + C 中断命令变得不可能了。我之前遇到的行为(在没有互联网时命令可中断)是因为 ping 由于网络无法访问而立即返回。现在目标地址可能可以到达,ping 等待完整的 TTL。因此,无法捕捉到 bash 运行的非常短暂的时刻。
【解决方案2】:

在这种循环中我通常会添加一个sleep 命令而不是true

while ! ping 8.8.8.8 -c 1 &> /dev/null ; do sleep 1; done;

这样您就可以在睡眠时使用Ctrl+C 并取消整个循环。

【讨论】:

  • 谢谢,但显然,while ! ping 8.8.8.8 -c 1 &> /dev/null ; do true; done; 是可中断的,所以我看不出使用睡眠的理由。 true 也更短:p.
  • 是的,但它对您的网络的攻击性较小:)。
  • 查看我对@chepner 回复的评论。我现在意识到睡眠功能的实用性。它增加了在单击 Ctrl + C 时运行 bash 的可能性。
【解决方案3】:

我认为更好的方法是在 ping 中设置 Timeout。

while ! ping -c 1 -W 2 8.8.8.8 >/dev/null 2>&1 ; do sleep 1 ; done

【讨论】:

    猜你喜欢
    • 2013-06-21
    • 2011-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多