I am writing a script to run a few different PHYLIP programs and have encountered something strange: I am temporarily unable to rename output files immediately after running a PHYLIP program. Here is some code that demonstrates the problem and my hacked solution:
###### RUN DNAML ON INPUT FILE ######
# CREATE INPUT FILE
mv infile data.dat # CHANGE FILE NAME FROM "infile"
echo data.dat > input # CREATE FILE, "input" WITH FILE NAME
echo I >> input # ADD OPTION "I" TO SET FORMAT TO "SEQUENTIAL"
echo Y >> input # ADD OPTION "Y" TO ACCEPT CHANGES
# RUN DNAML
/Users/kendalls/phylip-3.695/exe/dnaml < input > screenout &
echo "Ran Dnaml"
# CHANGE OUTPUT FILE NAMES
#mv outfile outfile.dnaml
mv outfile outfile.dnaml # THIS COMMAND FAILS AND RETURNS AN ERROR MESSAGE IF THE LINE ABOVE IS COMMENTED OUT
mv outtree outtree.dnaml
The error message this produces is:
mv: rename outfile to outfile.dnaml: No such file or directory
This error only appears for the first renaming command after running a PHYLIP program and I get an identical error if I try to rename the "outtree" file first. I have also tried using the "cp" command instead of "mv" but get the same error. Furthermore, this error appears with every PHYLIP program I have tried.
My best guess for why this happens is that somehow the PHYLIP program keeps the output files open after it finishes running and my initial attempt to renaming the file coerces PHYLIP program to close the output files. Does anyone know for sure how to explain this bug? Also welcome any suggestions on how to re-write my script.
If you uncomment the first line, outfile becomes outfile.dnaml so the second line can't find outfile anymore and the error should be the correct result. The fact that you get the error for the first one indicates that the file is probably not created by the time you reach the mv command. This is most likely because you're backgrounding the dnaml program so that you get to renaming the file before the program has finished running. On Linux this should be safe as long as you don't move the file across filesystems and you're sure that the program writing to the file doesn't close and reopens it in the meantime. Or in your case that the program has created the file by the time you get to it.
I had no idea what "backgrounding" was - I just copied that line of code from an older script someone else wrote. I solved the problem by adding "wait" after every PHYLIP command. Now my code runs without errors and looks like this:
The
&
sign at the end of a command sends the command to the background so that it doesn't interact with the terminal anymore. This means you get access to the terminal again without waiting for the command to finish. Your addition of 'wait' just counteracts&
. So just remove the & and you won't need the wait command which, by the way, normally requires the ID of the process to wait for (without it, it waits for all currently active child processes which could be problematic in a more complex pipeline).Alternatively he could change it to
&&
instead of&
, although I presume not having anything there is the same than having&&
..