Sudjeeni
Sudjeeni

Reputation: 1

Syntax error near unexpected token 'then' in shell script (Whitespaces are good)

Shebang is #!/bin/bash
for f in C:"\Users\Sudje\OneDrive\Documents\Aug**" do if [ "${f}" = "PimsShows.archive" ]; then ./mongorestore.exe -h 127.0.0.1:27017 --archive = "$f" --gzip fi; done

I get Syntax error near unexpected token 'then' in shell script. I looked at all the whitespaces already and they are good I think. What am I doing wrong?

Upvotes: 0

Views: 924

Answers (2)

Michael Veksler
Michael Veksler

Reputation: 8475

You should have either a newline or ; before the do.

#                                                  |
#                                                  v
for f in C:"\Users\Sudje\OneDrive\Documents\Aug**" ; do if [ "${f}" = "PimsShows.archive" ]; then ./mongorestore.exe -h 127.0.0.1:27017 --archive = "$f" --gzip;fi;done
#                                                  ^
#                                                  |

Or

for f in C:"\Users\Sudje\OneDrive\Documents\Aug**"
do 
   if [ "${f}" = "PimsShows.archive" ]
   then
      ./mongorestore.exe -h 127.0.0.1:27017 --archive = "$f" --gzip
   fi
done

The code does not do what you think it does. There are three issues.

One, the quoting of C:"\Users\Sudje\OneDrive\Documents\Aug**" precludes any glob-pattern expansion. You want the ** to be outside the quotes, like this: C:"\Users\Sudje\OneDrive\Documents\Aug\"**

Second, by default ** does not recurse into subdirectories. To do that, you must change the default behavior of bash by calling shopt -s globstar.

Third, the value of $f contains the full path, including the C: and all intermediate subdirectories, but you compare it to a filename without the whole path. You need something like "$(basename "$f")" instead of "${f}"

(EDIT: Added quotes over ${f} below, otherwise filenames with spaces will cause basename to fail)

shopt -s globstar
for f in C:"\Users\Sudje\OneDrive\Documents\Aug"**
do 
   if [ "$(basename "${f}")" = "PimsShows.archive" ]
   then
      ./mongorestore.exe -h 127.0.0.1:27017 --archive = "$f" --gzip
   fi
done

Note, I don't have bash for windows, so I am not 100% confident that basename over Windows-style path (with \) works well.

A more robust solution, instead of ** and shopt with basename is to use find:

find  "C:"\Users\Sudje\OneDrive\Documents\Aug" -iname "PimsShows.archive" -print0 | \
   xargs -0 -i ./mongorestore.exe -h 127.0.0.1:27017 --archive = {} --gzip

Upvotes: 2

Dominique
Dominique

Reputation: 17493

You forgot a semicolon after gzip, so the end of the if-clause is not recognised:

for f in C:"\Users\Sudje\OneDrive\Documents\Aug**" do 
  if [ "${f}" = "PimsShows.archive" ];
  then ./mongorestore.exe -h 127.0.0.1:27017 --archive = "$f" --gzip;
  fi; 
done

In top of this, you did not add a shebang in order to completely analyse this issue.

Upvotes: 0

Related Questions