Shell 脚本 - 将输出重定向到文件,并且第一次运行时结果与预期不符

Shell 脚本 - 将输出重定向到文件,并且第一次运行时结果与预期不符

我已经重定向了命令的输出,该命令有时会返回 2 行、5 行.. 文件中的 100 行等.. 我将在 if 条件中使用此文件稍后检查其他一些条件..

奇怪的是 - 我需要多次执行脚本才能按预期获取数据。如果我第一次执行脚本,它只会返回任何内容。请您帮忙解释为什么这在第一次运行时没有给出预期结果

该代码适用于 AIX,如下:

df -gt | grep /home/prods/db2/ > /tmp/DISKREQ.TMP
if [[ $? -eq 0 ]]; then
        chmod 777 /tmp/DISKREQ.TMP
        cat /tmp/DISKREQ.TMP | awk '{print$6}' | awk 'length($0) == 22' > /tmp/DISKREQ.TMP
        cat /tmp/DISKREQ.TMP | while read line
        do
                        FSIZE_DISKREQ=`df -g | awk '$7 == "'$line'" {print $3;}'`
                        if [[ $FSIZE_DISKREQ -lt 2 ]]; then
                        echo
                         echo " Instance Home Directory $line = $FSIZE_DISKREQ "
                        else
                        echo
                                echo " Instance Home Directory $line "
                        fi
        done
else
echo
        echo "No Instance Home directory Mounted"
fi

答案1

cat /tmp/DISKREQ.TMP | awk '{print$6}' | awk 'length($0) == 22' > /tmp/DISKREQ.TMP

管道的组件是并行执行的。因此,该行并行执行三个命令:

  • cat /tmp/DISKREQ.TMP
  • awk '{print$6}'
  • awk 'length($0) == 22' > /tmp/DISKREQ.TMP

第一个命令是打开/tmp/DISKREQ.TMP以供读取。第三个命令/tmp/DISKREQ.TMP在执行其他操作之前先进行截断。根据时间的不同,cat可能有时间也可能没有时间至少读取文件的开头部分。

解决方案:不要写入与输入相同的文件。 (有更复杂、更脆弱的解决方案可以让您重用该名称;我不会给出一个解决方案,因为在这里做一些复杂的事情是没有意义的。)

df -gt | grep /home/prods/db2/ > /tmp/DISKREQ.TMP
if [[ $? -eq 0 ]]; then
    cat /tmp/DISKREQ.TMP | awk '{print$6}' | awk 'length($0) == 22' > /tmp/DISKREQ2.TMP
    cat /tmp/DISKREQ2.TMP | while read line

(不要使用chmod 777。这不会解决任何问题,反而会产生问题。)

不过,您不需要所有这些临时文件,因此您可以通过删除它们来完全回避问题。只需将 awk 链直接通过管道传输到 while 循环即可删除第二个临时文件。我还摆脱了无用的用途cat并将这两个awk脚本合并为一个。

df -gt | grep /home/prods/db2/ > /tmp/DISKREQ.TMP
if [[ $? -eq 0 ]]; then
    </tmp/DISKREQ.TMP awk 'length($6) == 22 {print $6}' | while read line
    do

您甚至可以完全摆脱awk并在循环中进行过滤while read;我将把它作为练习留给读者。

要删除第一个临时文件,需要稍微改变一下逻辑。如果找不到任何内容,while 循环体无论如何都不会运行,因为它将得到零行来处理,但在这种情况下您需要一些逻辑来显示消息。您可以在 awk 中grep使用指令。END

df -gt | grep /home/prods/db2/ |
awk 'length($6) == 22 {print $6}
     END {if (NR==0) print "No Instance Home directory Mounted"}' |
while read line; do …

您可以将grep呼叫与结合起来awk。 (供读者练习。)或者您可以在 shell 中进行整个过滤。我认为这/home/prods/db2/永远是第六栏的开始。

found=0
df -gt |
while read device total used available percent mountpoint; do
    [[ $mountpoint == /home/prods/db2/* ]] || continue
    ((++found))
    [[ ${#mountpoint} -eq 22 ]] || continue
done
if ((found == 0)); then echo "No Instance Home directory Mounted"; fi

相关内容