如何在bash脚本中重写while循环以防止创建临时文件?

如何在bash脚本中重写while循环以防止创建临时文件?,bash,Bash,我认为生成临时文件可能会慢一些,如果用户按ctrl+c,临时文件将变成垃圾 这是我的原始代码 for f in bin/* ; do ldd $f 2>/dev/null | awk '{print $1}' done | sort -u | grep -v -e '^not$' -e 'ld-linux' > list.1 while read soname ; do process_so_name $soname done < list.1 bin/*中f的;做

我认为生成临时文件可能会慢一些,如果用户按ctrl+c,临时文件将变成垃圾

这是我的原始代码

for f in bin/* ; do
  ldd $f 2>/dev/null | awk '{print $1}'
done | sort -u | grep -v -e '^not$' -e 'ld-linux' > list.1
while read soname ; do
  process_so_name $soname
done < list.1
bin/*中f的
;做
ldd$f 2>/dev/null | awk'{print$1}'
完成| sort-u | grep-v-e'^not$'-e'ld linux'>列表。1
一边读我;做
进程\u so\u名称$soname
完成<列表1

是否可以删除临时文件列表。1?

只需在没有临时文件的情况下执行即可。将最后一次grep的结果导入while

您可以连接到SIGINT来检测Ctrl+C,但如果不需要,为什么还要担心呢?你还是不能和西格尔勾搭上

for f in bin/* ; do
  ldd $f 2>/dev/null | awk '{print $1}'
done | sort -u | grep -v -e '^not$' -e 'ld-linux' | while read soname ; do
  process_so_name $soname
done
要连接到SIGINT,请执行以下操作:

trap "echo SIGINT; rm -f tempfile; exit -1" INT
要连接到SIGTERM(请参见下面的注释),请执行以下操作:

trap "echo SIGINT; rm -f tempfile; exit -1" EXIT
比如@M

没有临时文件的另一种方法

function func_name(){
for f in bin/* ; do
ldd $f 2>/dev/null | awk '{print $1}'
done | sort -u | grep -v -e '^not$' -e 'ld-linux'
}

while read soname ; do
process_so_name $soname
done < <(func_name)
函数函数名(){
对于bin/*中的f;do
ldd$f 2>/dev/null | awk'{print$1}'
完成| sort-u | grep-v-e'^not$'-e'ld linux'
}
一边读我;做
进程\u so\u名称$soname

完成<以下内容对您有用吗

for f in bin/* ; do
  ldd $f 2>/dev/null | awk '{print $1}'
done | sort -u | grep -v -e '^not$' -e 'ld-linux' | xargs -n 1 process_so_name

除了@MihaiDanila的正确答案

如果不想在主循环中重用某些统计值,则必须对脚本重新排序并使用进程替换

total=0
已处理=0
一边读我;做
((总计=总计+1))
进程名称$soname&((已处理=已处理+1))
完成
使用管道的语法,如
。。。grep-v | while read soname
将在管道之后执行一个fork,因此主循环的环境将在末尾被丢弃


请参阅:
man-Len-Pless \+/^\\\\*进程\\\substitution$bash

我想您的意思是问“我可以重写此代码以便它不使用磁盘上的临时文件吗?”对吗?我相信您的问题的关键是
xargs
命令;请参见,您也可以设置陷阱
EXIT
,以确保陷阱在SIGTERM上运行,即“EXIT”命令,由于
set-e
和其他退出条件而中止。谢谢,我在答案中添加了您的建议。谢谢@MihaiDanila我喜欢所有三个答案,但您的答案提供了更多学习内容。紧凑,但与更详细的
while
相比,更难适应名称中带有空格的文件。要与原始代码匹配,请使用
-n1
选项xargs@MihaiDanila,要处理带有空格的文件,请使用
xargs-I{}process\u so\u name{}
@glennjackman-谢谢你的建议,我已经编辑了代码。@glennjackmanCorrect。在xargs手册页中,我还看到了很多关于如何使xargs上游的命令使用
\0
来分隔记录,以便允许xargs通过
-0
找到相同的记录的内容。我们的询问者不会出现这种复杂情况,因为他精确地要求一次只调用一个参数,而不是使用
xargs-n1
for f in bin/* ; do
  ldd $f 2>/dev/null | awk '{print $1}'
done | sort -u | grep -v -e '^not$' -e 'ld-linux' | xargs -n 1 process_so_name
total=0
processed=0
while read soname ; do
  ((total=total+1))
  process_so_name $soname && ((processed=processed+1))
done < <(
    for f in bin/* ; do
      ldd $f 2>/dev/null | awk '{print $1}'
    done |
      sort -u |
      grep -v -e '^not$' -e 'ld-linux'
)
printf "Total file %d, processed ok: %d, last filename: '%s'" \
    $total $processed $soname