0

I keep getting this error: syntax error near unexpected token 'done' but I don't understand why.

I tried adding dos2unix *.sh after #!/bin/sh, but that just gave me an error that said no such file or directory in addition to the "done" error.

This is a .sh file. I'm very new to writing scripts. Help?

I'm running

sh thisfile.sh program_input input

on linux

edit I added some quotations around the variables- same error

#!/bin/sh
fst=$1
input=$2
while read line
do
    result=$(cat "$line" | program "$fst")
    if [ "$result" = "" ];
    then
        printf "$line\t=>\t *none* 0\n"
    else
        printf "$line\t=>\tyes\n"
    fi
done < "$input"

"$input" is just four rows of words like "they" "can" "fish" "they" "can" "take" "table"

If I run cat "$line" | program "$fst" it works fine

note if I take out everything in the loop and just printf $line it gives the same "done" syntax error

7
3

syntax error near unexpected token 'done' is the error Bash gives when it sees the reserved word done without a matching do before it. It has nothing to do with quotes, but most likely a lot to do with your file having DOS/Windows-style CRLF line endings. The carriage return (CR, \r) is seen by the shell as a regular character, so it doesn't see the reserved word do, but do\r instead. On the other hand, on the last line it does recognize done, since it's separated from the line end, and the CR there with that space.

Run the script file itself through dos2unix. Don't add the dos2unix command in the script file.

1
  • This was the issue. I was trying to run it in the script file and just getting errors, but running the file through dos2unix fixed everything. Thank you! – iamjane Oct 26 '20 at 20:07
1

I would use

#!/bin/sh
program_input="$1"
input="$2"
cat "$input" | while read line
do
    result=$(echo "$line" | program -sli "$program_input")
    if [ "$result" = "" ] 
    then
        printf "$line\t=>\t *none* 0\n"
    else
        printf "$line\t=>\tyes\n"
    fi
done
  • result=$( ... ) is prefered over result=... (backquote)

the command

echo -e `"$line"\t=>\tyes`

means :

  • execute "$line"\t=>\tyes
  • redirecting output from "$line" = to yes
  • and echo -e whatever result (result should be empty, either stdout caught in yes or stderr uncaught).

Is that what you want ?

purist might object about useless use of cat as

cat "$input" | while read file
do

done

can be replace by

while read file
do

done < "$input"

however if while loop is too many line, it might not be easy to guess what while is reading.

2
  • I will edit my question with my changes and the input files- I am still getting the same error with these changes. – iamjane Oct 26 '20 at 19:23
  • This didn't answer my question, but you did help me format and understand my code better, so thank you! – iamjane Oct 26 '20 at 20:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.