bash脚本的奇怪行为

bash脚本的奇怪行为,bash,Bash,我编写了一个bash脚本,该脚本假设创建一些文件并写入它们。 不管怎么说,脚本做什么并不重要,关键是代码中有一条注释(在最后),它假设只将某些内容打印到屏幕上。如果我试着像那样运行它-程序不会在文件中写入输出,但是如果把这一行不作为注释(即删除“##”)那么它会工作-程序会将输出写入文件。 我真的试过了,但我不明白发生了什么。。。 如果您需要脚本的其余部分,或者需要更多关于它所说内容的解释 files=( `ls $artists` ) echo artists=%${files[*]}% fo

我编写了一个bash脚本,该脚本假设创建一些文件并写入它们。 不管怎么说,脚本做什么并不重要,关键是代码中有一条注释(在最后),它假设只将某些内容打印到屏幕上。如果我试着像那样运行它-程序不会在文件中写入输出,但是如果把这一行不作为注释(即删除“##”)那么它会工作-程序会将输出写入文件。 我真的试过了,但我不明白发生了什么。。。 如果您需要脚本的其余部分,或者需要更多关于它所说内容的解释

files=( `ls $artists` )
echo artists=%${files[*]}%
for file in ${files[*]}; do
    echo file= $file:
    lines=`wc -l $artists/$file | cut -d" " -f1`
    echo lines=$lines
    counter=0
    while read -a line; do
        if (( $counter==$lines ));then
            break;
        fi

        if [[ ! $line =~ [^[:space:]] ]] ; then
            continue
        fi
        rank=$(( ${line[3]}+$(( 5*${line[4]} )) ))
        echo  ${line[*]}
        echo rank = $rank
        echo  "${line[*]} $rank" >> $artists/$file
        let counter++
    done < $artists/$file

    ##cat  $artists/$file | tail -$lines
    cat $artists/$file | tail -$lines > $artists/$file
done
files=(`ls$artists`)
echo美工人员=%${files[*]}%
对于${files[*]}中的文件;做
echo file=$file:
行=`wc-l$artists/$file | cut-d”“-f1`
回音线=$线
计数器=0
读的时候——一行;做
如果(($counter==$line));然后
打破
fi
如果[!$line=~[^[:space:][]];然后
持续
fi
排名=$(${line[3]}+$((5*${line[4]})))
echo${line[*]}
回声等级=$rank
echo“${line[*]}$rank”>>$artists/$file
让我们算帐++
完成<$artists/$file
##cat$artists/$file | tail-$行
cat$artists/$file | tail-$lines>$artists/$file
完成

重定向到源文件会损坏它。改为重定向到临时文件,并在之后重命名。

cat$artists/$file | tail-$lines>$artists/$file

让我们考虑一下正在做什么。首先,您正在运行
cat
程序,这是不必要的。这可能会影响症状,但我对此表示怀疑

shell发现了
>$artists/$文件
。在运行
tail
程序之前,它会将文件截断为零字节。根据事件的确切顺序,
cat
将读取一个空文件

所以,不要这样做,试试这个:

if tail -$lines "$artists/$file" > "$artists/$file.$$"
then
    mv "$artists/$file.$$" "$artists/$file"
else
    echo "Unable to tail $artists/$file" >&2
fi
不需要
cat
。我们重定向到一个附加了PID($$)的临时文件名。如果
tail
有效,那么我们将临时文件重命名为所需的文件名,否则我们将向stderr(fd2)写入错误消息。如果失败,也可以考虑是否退出循环或退出程序。


防御性程序设计还要求我们将任何文件名变量放在双引号内,以防一些numpty在文件或目录名(程序文件)内添加空格

重定向到源文件将在下一个命令读取该文件之前截断该文件。既然您提到了,您不能创建临时文件,那么创建命名管道怎么样


您可以重新定向和读取管道,就像它们是文件一样。另外,你也可以同时做到这一点

描述一下剧本的目标是什么会很有帮助的。这就是问题所在。。。。无论如何,它是硬件和im不允许使用tmp文件。。。有什么建议吗?thnks.thnks但正如我所说的,不允许使用tmpfiles@rooster:为什么不呢?