Another one I can't find an answer for, and it feels like I've gone mad.
I have a BASH script using a for loop to run a complex command (many protein sequence alignments) on a lot of files (~5000). The loop produces statements that will execute when given alone (i.e. copy-pasted from the error message to the command prompt), but which return "no such file or directory" inside the loop. Script below; there are actually several more arguments but this includes some representative ones and the file arguments.
#!/bin/bash
# Pass directory with targets as FASTA sequences as argument.
# Arguments to psiblast
# Common
db=local/db/nr/nr
outfile="/mnt/scratch/psi-blast"
e=0.001
threads=8
itnum=5
pssm="/mnt/scratch/psi-blast/pssm."
pssm_txt="/mnt/scratch/psi-blast/pssm."
pseudo=0
pwa_inclusion=0.002
for i in ${1}/*
do
filename=$(basename $i)
"local/ncbi-blast-2.2.23+/bin/psiblast\
-query ${i}\
-db $db\
-out ${outfile}/${filename}.out\
-evalue $e\
-num_threads $threads\
-num_iterations $itnum\
-out_pssm ${pssm}$filename\
-out_ascii_pssm ${pssm_txt}${filename}.txt\
开发者_运维技巧-pseudocount $pseudo\
-inclusion_ethresh $pwa_inclusion"
done
Running this scripts gives "<scriptname> line <last line before 'done'>: <attempted command> : No such file or directory. If I then paste the attempted command onto the prompt it will run.
Each of these commands takes a couple of minutes to run.try without the quotes. and you forgot some slashes.
for i in ${1}/*
do
filename=$(basename $i)
local/ncbi-blast-2.2.23+/bin/psiblast \
-query "${i}" \
-db "$db" \
-out "${outfile}/${filename}.out" \
-evalue "$e" \
-num_threads "$threads" \
-num_iterations "$itnum" \
-out_pssm "${pssm}/$filename" \
-out_ascii_pssm "${pssm_txt}/${filename}.txt" \
-pseudocount "$pseudo" \
-inclusion_ethresh "$pwa_inclusion"
done
The behavior you're observing will occur if there are spaces in the filenames you're iterating over. For this reason, you'll want to properly quote your filenames, as in the following minimal example:
#!/bin/bash
for i in *
do
filename="$(basename "$i")"
command="ls -lah '$filename'"
echo "filename=$filename"
echo "Command = $command"
eval "$command"
done
Adding quotes to filenames will not help when using a for loop. To overcome this, I've always done something similar to the following example whenever I needed to loop over filenames:
ls -1 directory | { while read line; do echo $line; done; }
精彩评论