Bash脚本中后台命令输出赋值变量并同步写入文件问题
嘿,我来帮你搞定这个Bash脚本的问题——循环里给变量赋值、写入文件,还有nohup记录缺失的坑我都踩过,给你梳理清楚解决方案:
问题拆解与解决办法
首先说变量无值的核心问题:你第一次写法变量为空,大概率是因为命令跑到子shell里执行了(比如用了管道|、后台&或者()括号),Bash里子shell的变量是不会回传给父shell的,所以父shell里的变量自然是空的。
正确的变量赋值写法(避免子shell丢变量)
假设你的三个命令是cmd1、cmd2、cmd3,直接在当前shell里捕获命令输出就不会丢变量:
#!/bin/bash # 替换成你的循环条件,比如 while true; do 或者 for i in {1..10}; do while [ 你的循环条件 ]; do # 用$()捕获命令的单行输出,直接在当前shell赋值变量 var1=$(cmd1) var2=$(cmd2) var3=$(cmd3) # 所有变量都拿到值后,统一写入文件 echo "var1: $var1 | var2: $var2 | var3: $var3" >> result.txt done
如果你的命令需要后台运行(比如要并行执行),那得用临时文件+wait来同步,避免子shell丢变量:
#!/bin/bash while [ 你的循环条件 ]; do # 三个命令后台运行,输出写入临时文件 cmd1 > temp_var1.txt & cmd2 > temp_var2.txt & cmd3 > temp_var3.txt & wait # 必须等三个后台命令都跑完,再读临时文件 # 从临时文件读取内容到变量 var1=$(cat temp_var1.txt) var2=$(cat temp_var2.txt) var3=$(cat temp_var3.txt) # 写入结果并清理临时文件 echo "var1: $var1 | var2: $var2 | var3: $var3" >> result.txt rm temp_var1.txt temp_var2.txt temp_var3.txt done
解决nohup.out无后台记录的问题
你第二种写法能拿到变量,但nohup.out没内容,大概率是脚本里的输出被你自己重定向走了(比如>> result.txt),nohup默认只接管脚本没显式重定向的stdout和stderr。
有两种办法让后台命令的输出写入nohup.out:
办法1:让命令输出同时到变量和nohup.out
用tee命令把命令的输出同时传给变量和nohup.out:
#!/bin/bash while [ 你的循环条件 ]; do # 2>&1把错误也转成标准输出,tee同时写入nohup.out和传递给$()捕获 var1=$(cmd1 2>&1 | tee -a nohup.out) var2=$(cmd2 2>&1 | tee -a nohup.out) var3=$(cmd3 2>&1 | tee -a nohup.out) echo "var1: $var1 | var2: $var2 | var3: $var3" >> result.txt done
办法2:让nohup接管脚本所有输出
运行脚本时显式把脚本的所有输出重定向到nohup.out,这样脚本里的所有命令输出都会进来:
nohup ./your_script.sh > nohup.out 2>&1 &
如果是用后台命令+临时文件的写法,也可以让命令输出同时到临时文件和nohup.out:
#!/bin/bash while [ 你的循环条件 ]; do # 用进程替换,让命令输出同时写入临时文件和nohup.out cmd1 > >(tee temp_var1.txt nohup.out) 2>&1 & cmd2 > >(tee temp_var2.txt nohup.out) 2>&1 & cmd3 > >(tee temp_var3.txt nohup.out) 2>&1 & wait var1=$(cat temp_var1.txt) var2=$(cat temp_var2.txt) var3=$(cat temp_var3.txt) echo "var1: $var1 | var2: $var2 | var3: $var3" >> result.txt rm temp_var1.txt temp_var2.txt temp_var3.txt done
最后再划个重点
- 变量空:别在子shell里赋值变量,要么直接用
$()在当前shell捕获,要么用临时文件+wait处理后台命令。 - nohup.out无记录:要么让命令输出显式写入nohup.out,要么运行脚本时让nohup接管所有输出。
内容的提问来源于stack exchange,提问作者mrigs13
相关产品推荐
相关产品推荐

