15

In my Bash script, I have a function to return 0 or 1 (true or false) for the later main function's condition.

function1 () {
    if [[ "${1}" =~ "^ ...some regexp... $" ]] ; then
        return 1
    else
        return 0
    fi
}

Then in my main function:

main () {
    for arg in ${@} ; do
        if [ function1 ${arg} ] ; then
            ...
        elif [ ... ] ; then
            ...
        fi
    done
}

However, when I ran this script it always gave me an error message:

[: function1: unary operator expected

How can I fix this?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
GJ.
  • 870
  • 5
  • 9
  • 26
  • 1
    Note that, at least in bash version 4, you should not quote the regular expression: doing so forces simple string matching -- [documented here](http://www.gnu.org/software/bash/manual/bashref.html#index-g_t_005b_005b-57). Also, you should use `for arg in "$@"` with the quotes, or simpler `for arg; do ...` – glenn jackman May 14 '12 at 16:26
  • 1
    You should put your regex in a variable. `pattern='^ ...some regexp... $'; if [[ $1 =~ $pattern ]]`. Note that inside double square brackets, it's not necessary to quote variables and as glenn said, the regex (variable) should never be quoted. – Dennis Williamson May 14 '12 at 16:58
  • The canonical may be *["unary operator expected" error in Bash if condition](https://stackoverflow.com/questions/13617843/)* – Peter Mortensen Oct 05 '21 at 16:40

1 Answers1

33

You are making the common mistake of assuming that [ is part of the if command's syntax. It is not; the syntax of if is simply

if command; then
    ... things which should happen if command's result code was 0
else
    ... things which should happen otherwise
fi

One of the common commands we use is [ which is an alias for the command test. It is a simple command for comparing strings, numbers, and files. It accepts a fairly narrow combination of arguments, and tends to generate confusing and misleading error messages if you don't pass it the expected arguments. (Or rather, the error messages are adequate and helpful once you get used to it, but they are easily misunderstood if you're not used.)

In your main function, the call to [ appears misplaced.  You probably mean

if function "$arg"; then
    ...
elif ... ; then ...

By the way, for good measure, you should also always quote your strings. Use "$1" not $1, and "$arg" instead of $arg.

The historical reasons for test as a general kitchen sink of stuff the authors didn't want to make part of the syntax of if is one of the less attractive designs of the original Bourne shell. Bash and zsh offer alternatives which are less unwieldy (like the [[ double brackets in bash, which you use in your function1 definition), and of course, POSIX test is a lot more well-tempered than the original creation from Bell Labs.

As an additional clarification, your function can be simplified to just

function1 () {
    ! [[ "$1" =~ "^ ...some regexp... $" ]]
}

That is, perform the test with [[ and reverse its result code. (The "normal" case would be to return 0 for success, but maybe you are attempting to verify that the string doesn't match?)

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • those ... represent script after ${1}, and in my actual script i carefully split my script and brackets with one space. so i don't think it is the problem with that – GJ. May 14 '12 at 15:23
  • no, my function 1 actually checks if that $1 is matching some kind of regular expression. and my function 1 just works fine standing alone. so what i think is that there is some problem with the condition in my main function – GJ. May 14 '12 at 15:27
  • Oh, sorry, missed the error in `main`. Thanks for the hint. The basic analysis still holds; `[` is not what you think it is. – tripleee May 14 '12 at 15:36
  • Thanks! i shouldn't use the brackets within my conditions of main. thanks! – GJ. May 14 '12 at 15:41
  • I repurposed this answer at http://stackoverflow.com/a/36371520/874188 which is a more focused question. If you were linked here, perhaps click through to the newer question. – tripleee Apr 02 '16 at 09:44