Shell 编程,避免临时文件

rah*_*hmu 9 shell scripting ksh

我经常编写遵循相同模式的 KSH shell 脚本:

  • (1) 从一个或多个命令中检索输出
  • (2) 使用 grep|cut|awk|sed 格式化并打印到屏幕或文件

为了做到这一点,我经常将 (1) 的输出存储在一个临时文件中,然后对该文件进行 (2) 中的格式化。

以该代码为例:

TMPFILE=file.tmp

# If tmpfile exists rm it.
[ -f $TMPFILE ] && rm -f $TMPFILE

for SERVICE in $(myfunc); do
    getInfo $SERVICE > $TMPFILE # Store raw output in the TMPFILE

    # I retrieve the relevant data from the TMPFILE
    SERV_NAME=$(head -1 $TMPFILE | sed -e 's/ $//')
    SERV_HOSTNAME=$(grep HOSTNAME $TMPFILE | cut -d "=" -f2)
    SERV_ARGS=$(grep Arguments $TMPFILE | cut -d ":" -f2)

    print $SERV_NAME $SEP $SERV_HOSTNAME $SEP $SERV_ARGS
    rm -f $TMPFILE #rm the TMPFILE in vue of next iteration
done
Run Code Online (Sandbox Code Playgroud)

有没有办法使用管道、重定向和诸如此类的东西来避免每次将文件写入磁盘?

如果有帮助,我正在使用 ksh 版本 M-11/16/88i

roz*_*acz 9

你的代码对我来说看起来像是一个完全合理的使用临时文件的例子。我会留下:坚持这种方法。唯一真正需要改变的是创建临时文件的方式。使用类似的东西

 TMP=$(tempfile)
Run Code Online (Sandbox Code Playgroud)

或者

 TMP=$(mktemp)
Run Code Online (Sandbox Code Playgroud)

或者至少

 TMP=/tmp/myscript_$$
Run Code Online (Sandbox Code Playgroud)

这样您就不会轻易预测名称(安全性)并排除同时运行的多个脚本实例之间的干扰。

  • @roz 不,你没有抓住重点。在完成任何扩展之前,shell 中的变量赋值被识别,并且字段拆分*不*为变量赋值完成。因此,`var=$(echo很多空格); echo "$var"` 很好,应该产生“大量空格”作为输出。没有人提到的真正警告是命令替换删除所有尾随换行符。这在这里不是问题,只有当你有一个损坏的 `mktemp` 时才重要,它创建了带有尾随换行符的文件名。如果需要,通常的解决方法是 `var=$(echo command with trailing newline; echo x); var=${var%x}`。 (3认同)
  • 迂腐地,变量赋值不需要引号。 (2认同)

l0b*_*0b0 5

你可以使用一个变量:

info="$(getInfo $SERVICE)"
SERV_NAME="$(head -1 $TMPFILE <<<"$info" | sed -e 's/ $//')"
...
Run Code Online (Sandbox Code Playgroud)

来自man ksh

<<<word       A  short  form of here document in which word becomes the
              contents of the here-document after any parameter  expan-
              sion,  command  substitution, and arithmetic substitution
              occur.
Run Code Online (Sandbox Code Playgroud)

优点包括:

  • 启用并行执行。
  • 根据我的经验,这比临时文件快很多。除非您有太多的数据以至于最终要交换,否则它应该快几个数量级(除非 HD 缓存缓冲区,对于小数据量可能同样快)。
  • 其他进程或用户不能弄乱您的数据。

  • 猜猜 bash 如何实现 here-strings 和 here-docs。`sleep 3 &lt;&lt;&lt;"here string" &amp; lsof -p $! | grep 0r` → `sleep 30251 anthony 0r REG 253,0 12 263271 /tmp/sh-thd-7256597168 (deleted)` — 是的,它使用临时文件。 (3认同)
  • @rozcietrzewiacz:谷歌搜索 [`man ksh`](http://www.manpagez.com/man/1/ksh/)。那里肯定提到过。 (2认同)