Bash。来自后台管道命令的标准输出

4

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

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

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

如果你将它放在后台,你期望在命令完成之前iface会有什么值? - Eric Renouf
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - OscarAkaElvis
我认为我理解你正在做什么,但如果你试图将输出分配给一个变量,并且在将其存储在“iface”之前没有等待输出完成,那么你可能会尝试在“airmon-ng”完成之前使用“iface”。在“airmon-ng”完成之前,你期望它具有什么值?这个过程非常缓慢,所以你需要在后台执行吗? - Eric Renouf
这个程序的主要目标是使用一个旋转函数,它会在命令完成时绘制一些移动的字符。我只需要在后台启动命令,然后在那一行之后使用我的旋转函数,该函数只需要处理我使用 $! 获取的进程 ID,等到它完成后,我想在 "iface" 中使用结果,但不是在此之前。不确定你是否理解我试图表达的意思。谢谢。 - OscarAkaElvis
如果你不是特别喜欢自己的旋转器,那么 pv 可以工作吗?iface=$(airmon-ng start wlan0 2> /dev/null | grep monitor | pv) 将会打印一个状态栏,并将 stdout 存储在 iface 中,就像你想要的那样。 - Eric Renouf
pv不是一个选项。我需要脚本尽可能地安装并工作。无论如何,谢谢。 - OscarAkaElvis
1个回答

0

如果你只想知道脚本是否在等待 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)

或许你甚至不再需要将它存储在变量中,因为很多东西都知道如何操作文件


哇...我稍微修改了一下旋转器,但这个想法真是太棒了。正常工作。你太棒了,伙计! - OscarAkaElvis

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