Lazyweb Request: Profiling Timer Expired?
Dear Lazyweb:
I have a bash script with a while loop that takes a long time to process. It restores file modification times for complicated reasons not worth discussing here. Removing some nonessential stuff, I have the following code (I know it could be rewritten to be elegant, or at least collapsed into a single line):
`` cat ./preserve_file_mod_times | while read x do filename=`echo $x|sed 's/|.*//g'` lastmod=`echo $x|sed 's/^.*|//g'` touch -t "$lastmod" "$filename" done ``
As the input file has gotten longer, the loop now frequently fails:
376 Profiling timer expired touch -t "$lastmod" "$filename"
I’ve googled this error and understand what it is (i.e. SIGPROF) but not how to fix or workaround it. Any hints?
Thanks!
Giuseppe Sacco Aug 14
What shell are you using? Has it been compiled with gprof? Anyway, I would try trapping the signal and ignoring it, as in:
trap “” SIGPROF
Bye,
Giuseppe
adam Aug 14
Using bash. Your fix worked, thanks!
adam Aug 14
(bash from Debian Stable — don’t know if it’s built with gprof or not)
Simon Aug 14
At the risk of ignoring your original comments on elegance.
Why not set “IFS” to “|”
I assume from the sed statement that “|” doesn’t occur in the data except as a delimiter.
IFS=”|”
while read filename lastmod
do
touch -t “$lastmod” “$filename”
done <test.txt
Markdown code indent not work
Eliminating 2N+1 processes which hopefully will speed it up somewhat.
Of course if other code in the loop relies on IFS you need to ensure it is scoped correctly.
Jan Hudec Aug 15
Even not using IFS, the
echo $x|sed ...
can be replaced with ${x#…} and ${x%…} constructs like:(and you can of course avoid the temporary variables, but they would be good for debugging). It should be faster and more portable — echo is not compatible between bash and dash.
Also I suggest using dash instead of bash if you can do without the couple extra bash features as dash seems to be quite a bit faster.
adam Aug 15
Great suggestions!
Run-times:
Original script (bash): 391 seconds
Original script (dash): 379 seconds
Original script, using Simon’s IFS trick (dash): 109 seconds
Jason Lewis Aug 16
By the way, back ticks “ are no longer recommended and one should use $() instead in bash. A moot point given Jan suggestion.