BASH - determine when file is no longer written to
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
BASH - determine when file is no longer written to
Im writing a script that rips a CD and encodes the WAV-files to MP3. Thats kind of basic.
What I wanted to do was to have several instances of encoders running parallell with the ripping. That went kind-of alright.
It then starts to rip all tracks. Another script is on a look-out for WAV-files and assignes them to the encoder (making sure there is no more than 3 encoders running at the same time).
My problem is to determine when a WAV-file is completly ripped. I was trying to use 'lsof' but it reports 'in use by icedax' for all WAV-files until the ripping process is completed.
Is there a way to make sure the WAV-file I assign to an encoder is complete?
I know I could use icedax and ripp one track at-a-time but I want to beat the application Grip and rip-encode faster.
I'm also intrerested in all kinds of ideas regarding my scripting. Im kind of new at BASH and need all tips i can get .
function what_time() {
TIME=$(date +%H:%M:%S)
}
function send_agent() {
# is there job in stack
if [ "${STACK[$POINTER]}" != "" ]; then
NO_JOBS=$(jobs | wc -l)
# if current jobs are fewer than 3...
if [ $NO_JOBS -lt 3 ]; then
what_time; echo "$TIME : found ${STACK[$POINTER]} and a free slot..."
./agent ${STACK[$POINTER]} &
let "POINTER=$POINTER+1"
fi
fi
}
TRACKS=$(cat audio.cddb | grep TTITLE | wc -l)
STACK=[]
POINTER=1
COUNTER=1
while (($POINTER <= $TRACKS)); do
while (($COUNTER <= $TRACKS)); do
NO=$(printf "%02i" $COUNTER)
FILE="audio_$NO.wav"
if [ -f $FILE ]; then
STACK[$COUNTER]=$FILE
#echo ${STACK[$COUNTER]}
let "COUNTER=$COUNTER+1"
fi
send_agent
done
send_agent
done
Let me suggest an idea on a conceptual level; take it or leave it.
1. Script enters a loop where it rips to wav files, one at a time.
2. After each wav file is ripped (within the loop), a bg job is submitted to encode that particular wav to mp3.
Make sense? This will ensure that each wav is ripped before you start encoding it. It also means that the ripper can continue while encoding jobs run.
Since ripping is likely to be an IO-bound process, you may find that there is no improvement in overall performance, and there may actually be a net loss, due to cache flushing and/or additional seeking. I don't know that bash has fine enough control over process monitoring to do what you are trying to accomplish. Using something slightly more sophisticated such as perl, which would allow you you fork an arbitrary number of processes, and then do waitpid() on each of them would be a more refined method. My opinion.
--- rod.
EDIT: macemoneta has just pointed out that Bash can indeed do what I suggested as a good reason to use perl.
Thank you all for your responses.
anomie) I know I could rip one track at the time. That would give me control over when that track is ripped and start encoding. It is slower though to rip track 1,2,3,4... than it is to rip --bulk. With bulk-ripping i rip one cd in about 2 minutes.
macemoneta) About PIDs. Since a run icedax with the --bulk parameter there is no sence in waiting for that job to finish. It would be the same as to first rip and then encode. My idea was to encode WAV-files on the fly while the ripping was still in progress.
theNbomr) Yes, ripping in parallell is no god idea. But encoding is and that is what i am doing. I keep three instances of lame-encoders running i parallell. I find (on my machine) that this increases encoding-speed. If I would run, like ten instances of encoders it would encode the pool of WAV-files slower.
If there is no way to make sure icedax --bulk is finnished with, say audio_01.wav - i would have to do as anomie says: rip one track, start encoding it while i rip track2 (and so on).
Possibly I can use filesize from the info-files icedax produces to determine if a WAV-file is done but I would prefer a system-call like "hello file, are you beeing written to? No!? Ok, i will now encode you and then kill you!"
I read all your posts, as well as the posts of everyone else. I understand them all, but I suspect you do not. Either that, or you are not communicating what you want clearly.
Grip is simply scheduling and dispatching highly optimized standalone rippers and encoders (which you can configure as you please). The idea that you will somehow "beat" this makes the basic premise weak.
I chose to assume you want to learn how to schedule and dispatch processes in your own code; but according to you, that's not what you want. So I now have to assume that you don't really know what you want. Can you clarify?
I like Grip. I use it. I'm aware of it (as i mention in my first posting).
It was the inspiration for me to try and optimize the rip-encoding process.
Even if i run my scripts rip- and encode parts in sequence i beat grip. That's because
1) i rip bulked
2) i have three encoders working (not 1 as grip).
The only thing missing now is to establish WHEN (in bulk ripping, running as ONE process) each WAV-file is completed so i can start encoding and NOT WAIT for the process to finish.
English is not my natural language it's challanging for me to express myself as well as i can in my native tongue. I'm sorry if this is making it hard for you (and others) to understand me.
I also realize my previous post might have sounded rude. I won't blame that on language-problems. It was more of a babelesque frustration-problem.
I know there is a solution for what im after and ill keep trying and report back here when i find it.
cheers.
Grip is somewhat better than just bulk ripping, in that you can exclude tracks you don't want, and the tracks are automatically labeled from freedb.org (or your favorite track database site).
To run multiple encoders on grip:
Config->Encode->Options and increase the number of CPUs. From the grip documentation at the site I linked to above: "This value specifies the number of simultaneous encode processes to run." In your case, set number of CPUs to 3 for three concurrent encoders.
macemoneta: I wasn't aware of that option in grip. That took away most of the entusiasm i had about his. And just as I realized the solution to my problem -> Since ripping is done in sequence, if audio_02.wav exists audio_01.wav must be done. So all i had to do was NOT to add the most recent WAV-file to the que until that file was the FINAL one.
Well... i think I'll program it anyway (you know... this was just a mind-exercise to begin with, like most of my small projects).
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.