You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Bash后台运行的while循环中导出变量?

问题根源

当你将while循环后台运行(加&)时,该循环会在子shell中执行。子shell与父shell拥有完全独立的环境变量空间,子shell内修改或export的变量无法反向传递给父shell——这就是updates变量始终为空的原因。

解决方案

方案1:用文件存储变量值(最简便)

通过文件作为中间介质,子shell将更新数写入文件,其他需要读取的地方从文件获取:

#!/bin/bash

# 定义存储更新数的临时文件
UPDATE_FILE="/tmp/arch_updates_count"
echo 0 > "$UPDATE_FILE"  # 初始化内容

# 后台循环检查更新并写入文件
while true; do
  if ping -q -c 1 -W 1 ping.eu > /dev/null; then
    updates=$(yay -Qu | wc -l)
  else
    updates=0  # 网络不通时设为0
  fi
  echo "$updates" > "$UPDATE_FILE"
  sleep 600
done &

# 示例:父脚本中读取当前更新数
echo "当前待更新包数量:$(cat "$UPDATE_FILE")"

# 若需实时监控,可添加循环读取
# while true; do
#   echo "实时更新数:$(cat "$UPDATE_FILE")"
#   sleep 300
# done

方案2:将变量处理逻辑移入后台进程

如果你的业务逻辑不需要在父shell中执行,直接把使用updates的代码放到后台循环内:

#!/bin/bash

while true; do
  updates=$(ping -q -c 1 -W 1 ping.eu > /dev/null && yay -Qu | wc -l)
  # 在这里直接处理updates,比如写入日志、发送通知
  echo "$(date '+%Y-%m-%d %H:%M:%S') 待更新包数:$updates" >> /var/log/update_check.log
  # notify-send "系统更新提醒" "共有 $updates 个包可更新"
  sleep 600
done &

方案3:用命名管道实现进程通信(适合复杂场景)

通过命名管道(FIFO)实现子shell与父shell的实时数据传递:

#!/bin/bash

# 创建命名管道
FIFO="/tmp/update_fifo"
mkfifo "$FIFO"

# 后台循环写入更新数到管道
while true; do
  updates=$(ping -q -c 1 -W 1 ping.eu > /dev/null && yay -Qu | wc -l)
  echo "$updates" > "$FIFO"
  sleep 600
done &

# 父shell读取管道内容并处理
while read -r updates < "$FIFO"; do
  echo "收到更新数:$updates"
  # 在这里添加你的业务逻辑
done

# 脚本退出时清理管道
trap 'rm -f "$FIFO"' EXIT

内容的提问来源于stack exchange,提问作者David

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 11:22:18