![]() |
Strange problem with redirection
I'm very new to all this, so I'm sure it's something obvious.
There's a program that is packaged with Archlinux called rankmirrors that takes a repository mirror list (in /etc/pacman.d) and returns a list of sorted mirrors based on speed. I glanced at a BASH scrpting tutorial and came up with this: :
#!/bin/bashWhere the /etc/pacman.d consists of the files: :
$ ls /etc/pacman.dFor some reason, the script deletes all the mirrors in each file and leaves an empty file with the header "Mirror file generated by rankmirrors on $date" where $date is obviously the date. However, when I run rankmirrors on a script and redirect the output to a differently named file like so: :
$ rankmirrors current > current.newEverything works normally. What am I doing wrong? |
You realize you're redirecting the output to the same file?
|
Quote:
|
That presumes synchronized read/write or adequate buffering, both of which are implementation dependent. Have you established that a hand-implementation of:
$ rankmirrors current > current.new is equivalent to: rankmirrors $mirror > $mirror ?? |
from man bash:
Quote:
|
Yup, it does. The filename is passed as an argument to the command, and the shell will set itself up for I/O redirection right at the start so by the time rankmirrors starts the file will have been stomped.
I don't know enough about shell programming to be honest (terrible, I need to learn but never get around to it because I use Perl for virtually all my scripting so my knowledge of bash scripting is restricted to extremely simple scripts and tweaking existing ones). Would it be possible to write rankmirrors to read its input from standard input rather than a file identified on the command line so you could do one of: :
rankmirrors < $mirror > $mirrorUnfortunately I'm not actually certain this would fix the issue! Also, I'm not sure if this is helpful but I've been known to find it useful that Linux will not obliterate a deleted file until everything using it has closed it - is there any way to open it for input, delete it, and then open it for writing? That way the old and new versions can co-exist with the old version visible only to code that has already opened it. The deletion of the old one only really happens when you close it that way, but it has no name so the new and old don't collide. If I was a bit less lazy I'd have actually checked to see if any of this works, but I'm not - hopefully something I've said here is of some use to you! |
Actually, my solution in the end was to redirect the output to a different file:
:
rankmirrors $mirror > ${mirror}_newand then to rename it following the sorting operations: :
mv ${mirror}_new $mirrorWhile of course first making a ${mirror}.bak of every file first. :) Thanks for all the advice. I've actually just purchased O'Reilly's "Classic Shell Scripting" which covers Awk, Sed, and Bash in detail. I figured it was about time. :) |
Yeah, I think I should get a copy of that too.
|
| All times are GMT -5. The time now is 10:42 AM. |
Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC