Eu não entendo o motivo da complexidade adicional. O que você realmente quer é:
john hash.txt --format=[cat line 1 from johnformats] > johnout
john hash.txt --format=[cat line 2 from johnformats] >> johnout
john hash.txt --format=[cat line 3 from johnformats] >> johnout
etc.
Então, em um script, seria:
#!/bin/bash
johnformats=$1
johnout=$2
while read line ; do
john hash.txt --format="$line" >>$johnout
done < $johnformats
Não deve haver necessidade de adicionar a complicação dos filedescriptors addtional 3 e 4, e o "$(cat hash.txt)"
faz algo completamente diferente, adicionando hash.txt
como argumento.
É claro, a mensagem de erro sugere que hash
é usado como argumento, não hash.txt
que está no código acima e também sugere que o arquivo hash
não existe. Essas são coisas que você quer checar também.