reve_etrange
reve_etrange

Reputation: 2571

BASH statements execute alone but return "no such file" in for loop

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.

Upvotes: 1

Views: 2311

Answers (3)

musashiXXX
musashiXXX

Reputation: 4452

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; }

Upvotes: 0

RTBarnard
RTBarnard

Reputation: 4444

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

Upvotes: 0

ghostdog74
ghostdog74

Reputation: 342463

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

Upvotes: 2

Related Questions