1

I am trying to write a Shell script to compile a c program and check if it prints "Hello World!" to stdout. This is what I have now. The second argument check in the diff is a file with only "Hello World!" in it.

#!/bin/sh
gcc -Wall hello.c -o hello
./hello > outfile
if diff outfile check >/dev/null ; then 
  echo Same
else
  echo Different
fi

My Ubuntu keeps showing this error after I try to run the script.

"./build.sh: 8: ./build.sh: Syntax error: "fi" unexpected (expecting "then")"

Please let me know what is wrong with my code.

  • Your script works fine -- how are you running it? Run as `"sh -x build.sh"` and post the output. Also post a hexdump on `check` (e.g. the output of `hexdump -Cv check`) – David C. Rankin Feb 04 '20 at 01:58
  • 3
    I suspect your script file has DOS/Windows line endings; see [this question](https://stackoverflow.com/questions/39527571/are-shell-scripts-sensitive-to-encoding-and-line-endings). – Gordon Davisson Feb 04 '20 at 02:05
  • Minor issue: You are discussing a POSIX shell script here, but use the _bash_ tag for your question. Please remove it, as there is nothing related to _bash_ here. – user1934428 Feb 04 '20 at 06:38

3 Answers3

3

As I said in a comment, I suspect your script file has DOS/Windows line endings; see this question.

Also, since the comparison you're making is just a single line, it's easy to do as a string comparison (rather than saving the strings to files, and using a file comparer like diff or cmp):

#!/bin/sh
gcc -Wall hello.c -o hello
if [ "$(./hello)" = 'Hello World!' ]; then 
  echo Same
else
  echo Different
fi

Notes: the $( ) is a "command substitution"; it runs the contents as a command, captures its output, and substitutes it into the command line at that point. The double-quotes around that prevent it from being split into "words" (i.e. "Hello" and "World!" being treated as separate words) and things that looks like filename wildcards being expanded into lists of matching files. (You should almost always put double-quotes around command and variable substitutions, because these effects tend to cause weird problems.)

Gordon Davisson
  • 118,432
  • 16
  • 123
  • 151
0

You can use cmp program to check whether the output file is what you've expected. Here is an example from my test script:

cmp "file.output" "file_cmp.output"

if [[ $? -eq 0 ]] ; then # this line checks if cmp exit value is 0 (everything is fine)
   echo "OK!"
else
   echo "ERROR!"
fi
jul3x
  • 16
  • 4
  • The `[[ ]]` condition syntax is not available in all shells (and specifically not in dash, which it looks like the asker is using). I recommend putting the command to be tested directly in the `if` condition (i.e. `if cmp ...; then`) rather than looking at `$?`. – Gordon Davisson Feb 04 '20 at 02:08
  • thanks, I did not know that this syntax is that rare ;) – jul3x Feb 04 '20 at 02:11
  • @jul3x : In general, you would not expect a statement in a programming language X to also work the same in a programming language Y, would you? It is not so much about rarity, but that you are using a language which simply is not very rich in constructs. – user1934428 Feb 05 '20 at 08:41
0

Use cmp instead of diff in scripts.

The simplest, using <(...) bash extension:

if cmp -s <(./hello) <(echo "Hello world!"); then 
   echo Same
else
  echo Different
fi
KamilCuk
  • 120,984
  • 8
  • 59
  • 111
  • @KamilCuk : The OP is using /bin/sh, not bash, so this won't be of use. – user1934428 Feb 04 '20 at 06:39
  • @user1934428 The question is tagged with bash, so from tags I assume it's available to OP. – KamilCuk Feb 04 '20 at 11:56
  • I know, that's why I told the OP to fix the tags, because it is confusing the way it is written. But in the question itself, we can see that he exclusively uses `sh`. Probably, the OP just does not know how to use the tags properly.... – user1934428 Feb 05 '20 at 08:39