1

I have a script that I'm writing to automate running specific tests with a promela model.

The user must supply the promela model and another file with the ltl properties they wish to run against the model.

I read in the file line by line using the following:

while read line; do 
  do_something()
end < $PROPERTIES

do_something() is more complicated, but the main problem I'm having is that eventually I want to invoke the following

spin -run -m100000 -f $line $PROMELAFILE >> $OUTFILE

The final command should look like the following

spin -run -m100000 -f '[] true' file.pml >> out.txt

The final command does work as intended from the command line. The quotes are absolutely necessary for the -f option to work properly.

The issue is the $line variable, when its read from the file, it looks like the following

' [] true '

it can also look like

" [] true "

which are semantically equivalent.

However, I keep getting the following error

unexpected EOF while look for matching `"'
syntax error: unexpected end of file

This error occurs whether its single quotes or double quotes

This makes me think that when $line is expanded, there's something that I don't understand about bash and the use of ' and ".

Any help/understanding that you can provide would be very helpful. Thank you!

washa3
  • 11
  • 3
  • Always, **always** quote your expansions (unless you know the extra parsing steps that happen on unquoted expansions and you explicitly want those steps to happen). `-f "$line"`, not `-f $line`. `"$PROMELAFILE"`, not `$PROMELAFILE`. `>>"$OUTFILE"`, not `>> $OUTFILE` (granted, removing the space is style, not correctness). – Charles Duffy Nov 03 '20 at 00:21
  • And don't put quotes in your data. Literal quotes (ones that are data) cannot and do not substitute for syntactic quotes (ones that are syntax). The lines in your file should just look like `[] true`; no quotes of any kind, unless you want those quotes to be passed to your `spin` program as data. – Charles Duffy Nov 03 '20 at 00:21
  • See [BashFAQ #50](http://mywiki.wooledge.org/BashFAQ/050) for an explanation of how to avoid issues that stem from the same misunderstanding. – Charles Duffy Nov 03 '20 at 00:22
  • 1
    ...as for the error given in the question body, the exact code given in the question won't cause an unexpected EOF from bash -- there must be something else you aren't showing us. – Charles Duffy Nov 03 '20 at 00:24
  • I could have been more clear, the quotes are absolutely necessary for the command, the -f option takes arguments of the form ' ltl_expression '. – washa3 Nov 03 '20 at 00:30
  • Unless you run `-f "' [] true '"`, with _both_ literal and syntactic quotes, you only need syntactic ones. – Charles Duffy Nov 03 '20 at 00:35
  • That is to say, when you run `someapplication -f ' [] true '`, the single-quotes **aren't actually passed to your application**. Instead, they're used **by the shell itself** to determine where each argument string begins and ends, and discarded after that use is complete. – Charles Duffy Nov 03 '20 at 00:35
  • Remember: At the operating system level (on UNIX), argument vectors are arrays of C strings. An application isn't given a command line with quotes still intact, it's given an array of strings that was parsed out of that command line (if it was started by a shell at all; if it was started from a programming language with direct access to the `execv` syscall there may have never _existed_ a command line with quotes in the first place). – Charles Duffy Nov 03 '20 at 00:37
  • To restate that a little differently: `./somecommand "argument one" "argument two"` becomes an array of three C strings. The first one -- `argv[0]` -- is `somecommand`; the second one is `argument one`, the second one is `argument two`. They're the exact same strings you'd get from, say, `./somecommand argument\ one argument\ two`, for example, or `./somecommand argument" "one argument' 'two`; the application being run has no way to tell the difference. – Charles Duffy Nov 03 '20 at 00:39
  • ...so, your program's documentation may tell you that it wants `someprogram -f 'string here'`, but that documentation is lying (or, more kindly, oversimplified). The application can't tell that you used single quotes at all; it can just tell that `string here` is passed as a single argument, as opposed to being split apart into multiple arguments as would be the case if it weren't quoted. – Charles Duffy Nov 03 '20 at 00:40
  • ...so, while I closed this as a duplicate of a question that asks how to use quotes from a file to generate an argument list, _if each line from the file is supposed to become exactly one argument to `spin`_, you shouldn't need to use the advice in that linked duplicate. Just take the quotes out of your data file (yes, I know you think you need them), and _add_ quotes to your shell syntax, so it's something akin to `while IFS= read -r line; do spin -run -m100000 -f "$line" "$PROMELAFILE" >>"$OUTFILE"; done` – Charles Duffy Nov 03 '20 at 00:45
  • ...re: why the `IFS=` and `-r` on the `read`, see [BashFAQ #1](http://mywiki.wooledge.org/BashFAQ/001), which goes into the intricacies of iterating over an input file line-by-line. – Charles Duffy Nov 03 '20 at 00:47
  • ...and btw, consider using http://shellcheck.net/ to validate your code; it should be able to point very quickly at whatever syntax issue is causing the unexpected EOF. – Charles Duffy Nov 03 '20 at 00:48
  • As a very high-level overview of how bash command lines are parsed, you might find https://stuff.lhunath.com/parser.png useful -- it shows how the shell consumes and discards quotes when determining how to split strings into individual words. – Charles Duffy Nov 03 '20 at 00:53

0 Answers0