使用 shell 脚本中的一次打开/关闭操作将数据附加到文件

使用 shell 脚本中的一次打开/关闭操作将数据附加到文件

我需要调整我的 shell 脚本并多次写入$log。反复打开和关闭文件会导致运行时间增加。

我怎样才能一次性将所有内容(包括echo脚本中定义的所有语句)写入文件?

#!/bin/sh
log="loadlog.log"

for i in {1..10}
do
   n=$((100*$i))
   echo "## Users=$i  requests=$n ##" >> $log     
   ab -n $n -c $i  http://mainserver.com/index.html  >>  $log
   ssh root@mainserver cat /proc/loadavg >> $log
   echo "======" >> $log
done

答案1

我不确定,但我猜你只想打开日志文件进行一次写入,是吗?

如果是这样,您需要使用子 shell,输出到 STDOUT,并将其发送到外部的日志文件。

#! /bin/bash
log="loadlog.log"

(
for i in {1..10}; do
    n=$((100*$i))

    echo "## Users=$i  requests=$n ##"

    ab -n $n -c $i  http://mainserver.com/index.html

    ssh root@mainserver cat /proc/loadavg

    echo "======"
done
) >> $log

另外,我建议你对代码风格做一些调整——它难以阅读。而且,你需要使用,#!/bin/bash因为你在循环中使用了特定于 bash 的构造。

答案2

使用exec带有重定向的命令会将该重定向应用于整个脚本。因此,您可以将所有 stdout 重定向到附加到日志文件:

#!/bin/sh
log="loadlog.log"

exec 1>>$log

for i in {1..10}
do
   n=$((100*$i))
   echo "## Users=$i  requests=$n ##"
   ab -n $n -c $i  http://mainserver.com/index.html
   ssh root@mainserver cat /proc/loadavg
   echo "======"
done

如果您仍想向用户发送内容,您可以先复制 stdout:

#!/bin/sh
log="loadlog.log"

exec 3>&1     # file descriptor 3 is now stdout
exec 1>>$log

for i in {1..10}
do
    # ...
   echo "======"                  # this line will be appended to the log file
   echo "completed loop $i" >&3   # this line will be displayed to user
done

exec 1>&3     # fd 1 restored to stdout
exec 3>&-     # fd 3 is closed

echo "stdout now restored"

相关内容