Reputation: 665
i wrote a bash script that suppose to create some files and write to them. anyway it doesnt really matter what the script does, the thing is - there is a comment in the code (at the end) which suppose only to print something to screen. and if I try to run it like that- the program doesnt write output in the files, but if put this line not as a comment (i.e remove the '##' ) then it works- the program writes the ouput to files. I reallly tried but i dont understand whats going on... If u need the rest of the script, or some more explanation about what it does just say.
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
Upvotes: 1
Views: 126
Reputation: 77185
Redirecting to the source file will truncate the file before the next command reads it. Since you mentioned, you cannot create temporary files, how about creating named pipes.
You can re-direct and read from pipes just like they are files. Plus you can do that in parallel.
Upvotes: 0
Reputation: 44434
cat $artists/$file | tail -$lines > $artists/$file
Let's consider what that is doing. First you are running the cat
program, which is unnecessary. It might affect the symptoms, but I doubt it.
The shell has spotted the > $artists/$file
. It will TRUNCATE the file to zero bytes before running the tail
program. Depending on the exact order of events, cat
will be reading an empty file.
So, don't do that, try this instead:
if tail -$lines "$artists/$file" > "$artists/$file.$$"
then
mv "$artists/$file.$$" "$artists/$file"
else
echo "Unable to tail $artists/$file" >&2
fi
No need for cat
. We redirect to a temporary filename which has the PID appended ($$). If the tail
worked then we rename the temporary file to the filename required, otherwise we write an error message to stderr (fd 2). You might also consider if you want to break out of the loop or exit the program if this fails.
Defensive proramming also demands that we place any filename variables inside double quotes, in case some numpty has put whitespace inside a file or directory name (Program Files).
Upvotes: 0
Reputation: 799490
Redirecting into the source file will damage it. Redirect to a temporary file instead, and rename it after.
Upvotes: 2