Man*_*hat 4 bash pipe background-process for
我正在执行下面的脚本
LOGDIR=~/curl_result_$(date |tr ' :' '_')
mkdir $LOGDIR
for THREADNO in $(seq 20)
do
for REQNO in $(seq 20)
do
time curl --verbose -sS http://dummy.restapiexample.com/api/v1/create --trace-ascii ${LOGDIR}/trace_${THREADNO}_${REQNO} -d @- <<EOF >> ${LOGDIR}/response_${THREADNO} 2>&1
{"name":"emp_${THREADNO}_${REQNO}_$(date |tr ' :' '_')","salary":"$(echo $RANDOM%100000|bc)","age":"$(echo $RANDOM%100000|bc)"}
EOF
echo -e "\n-------------------------------" >> ${LOGDIR}/response_${THREADNO}
done 2>&1 | grep real > $LOGDIR/timing_${THREADNO} &
done
Run Code Online (Sandbox Code Playgroud)
一段时间后,如果我检查没有 bash 进程,它会显示 20(不是 1 或 21)
ps|grep bash|wc -l
Run Code Online (Sandbox Code Playgroud)
问题是由于我没有使用方括号“()”来包围内循环,所以不应该产生新的 shell 进程。我想避免在 CPU 使用率接近 100% 时创建新的 shell。我不知道这是否重要,但我正在使用 Cygwin。
因为您已将循环通过管道传输到 中grep
,所以它必须在子shell 中运行。Bash手册中提到了这一点:
管道中的每个命令都在其自己的子 shell 中执行,这是一个单独的进程(请参阅命令执行环境)
这是可能避免与lastpipe
外壳选项为最终在管道命令,而不是任何其他人。在任何情况下,您都将整个管道置于后台,这也创建了一个子外壳。
没有办法解决这个问题。您正在做的事情本质上确实需要单独的 shell 进程才能工作:即使忽略管道,创建后台进程也需要创建一个进程。
如果您的问题是 CPU 使用率,那是由一次运行所有内容引起的。如果删除&
之后的grep
,所有命令将按顺序运行,而不是同时运行。仍然会创建子shell(用于管道),但在这种情况下,这些本身并不是主要问题。如果您需要它们同时运行,增加的 CPU 使用率是您选择的权衡。