【问题标题】:Bash. stdout from background piped commands重击。来自后台管道命令的标准输出
【发布时间】:2016-09-19 07:38:26
【问题描述】:

我不知道如何恢复在后台启动的“管道”命令的标准输出。让我们解释一下。我有这个命令:

iface=$(airmon-ng start wlan0 2> /dev/null | grep monitor)

我想将所有内容发送到后台以使用 $! 恢复 pid,但是当我将 & 放在任何地方时,grep 停止工作并且 iface var 为空。任何想法?谢谢。

【问题讨论】:

  • 如果你把它放在后台,你希望iface在命令完成之前有什么值?
  • 当我执行airmon-ng start wlan0 时,它会产生很多行。然后我只想对其中的一行进行 grep,其中包含文本“monitor”。该示例是我需要的简化示例。当然,then 更复杂,我在该行中使用正则表达式来获取接口的确切名称,但不相关。这里的问题是如何将 var 放入该行并同时在后台执行 all 以获取带有 $! 的 pid! .感谢您的关注!
  • 我想我收集了你在做什么@你可以想象在airmon-ng完成之前尝试使用iface。在airmon-ng 完成之前,您希望它有什么价值?这是不是超级慢所以你需要在后台做?
  • 这个的主要目的是使用一个微调器函数,该函数在完成命令时绘制一些随着“工作”移动的字符。我只需要在后台启动命令,然后在该行之后使用我的微调器功能,该功能只需要处理我使用 $!完成后我想在“iface”中使用结果,这是以前从未有过的。不知道你是否明白我在尝试什么。谢谢。
  • 如果您没有与自己的微调器结婚,pv 会工作吗? iface=$(airmon-ng start wlan0 2> /dev/null | grep monitor | pv) 将打印一个状态栏并根据需要在iface 中为您提供stdout

标签: bash background pipe stdout


【解决方案1】:

如果您只想在等待grep 的输出时获得脚本仍在运行的状态,您可以使用现有的工具,如pv,它将向stderr 打印进度表,这样就不会干扰您捕获输出。

如果做不到这一点,您可以编写一个比我想象的 pv 解决方案慢的函数,但可以让您在每一行之后更新微调器

get_monitor() {
    printf ' ' >&2 # to put a first char there to backspace the spinner over
    while read -r line; do
        if [[ $line =~ monitor ]]; then
            printf '%s\n' "$line"
        fi
        update_spinner
    done < <(airmon-ng start wlan0 2>/dev/null)
}

sp_ind=0
sp_chars='/-\|'
sp_num=${#sp_chars}
update_spinner() {
    printf '\b%s' "${sp_chars:sp_ind++%sp_num:1}" >&2
}

iface=$(get_monitor)

或者你可以让你的后台命令写入一个临时文件并在喜欢之后得到答案

airmon-ng start wlan2 2>/dev/null >/tmp/airmon_out &
# your spinner stuff
iface=$(cat /tmp/airmon_out)

或者也许你甚至不再需要在变量中使用它,因为很多东西都知道如何对文件进行操作

【讨论】:

  • 哇...我稍微修改了微调器,但这个想法很棒。在职的。你这个摇滚老兄!
猜你喜欢
  • 2021-04-29
  • 1970-01-01
  • 2017-08-11
  • 1970-01-01
  • 2017-05-11
  • 2018-10-09
  • 1970-01-01
  • 2014-12-11
  • 2015-02-05
相关资源
最近更新 更多