我写了一个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
答案 0 :(得分:2)
重定向到源文件会损坏它。改为重定向到临时文件,然后重命名。
答案 1 :(得分:0)
cat $artists/$file | tail -$lines > $artists/$file
让我们考虑一下这是做什么的。首先,您正在运行cat
程序,这是不必要的。它可能会影响症状,但我对此表示怀疑。
shell发现了> $artists/$file
。在运行tail
程序之前,它会将文件TRUNCATE为零字节。根据事件的确切顺序,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(fd 2)。如果失败,您可能还会考虑是否要退出循环或退出程序。
防御性编程还要求我们将任何文件名变量放在双引号内,以防一些numpty在文件或目录名(Program Files)中放入空格。
答案 2 :(得分:0)
重定向到源文件将在下一个命令读取文件之前截断该文件。由于您提到过,您无法创建临时文件,如何创建命名管道。
您可以像管文件一样重新定向和读取管道。另外,你可以并行完成。