David McCabe
David McCabe

Reputation: 127

bash shell issue with echo call from custom function

I'm in the process (v.painful) of learning the bash language and I'm fighting with the code below. Any explanation for it's current behaviour would be greatly appreciated.

code

#!/usr/bin/env bash

function useless
{
    echo "$1"
    return 0
}

function call-and-report
{
    TEST_CRITERIA="$1"
    
    if $TEST_CRITERIA
    then
        echo "passed"
    else
        echo "failed"
    fi
}

call-and-report $(useless  "Hello World")

issue

I'm expecting the following console output:

Hello World
passed

Instead I'm seeing the following output:

./../test.sh: line 13: Hello: command not found
failed

Upvotes: 0

Views: 570

Answers (2)

mivk
mivk

Reputation: 14824

In your example, $(useless "Hello World") will return

Hello World

So you are calling your call-and-report function with 2 arguments:

call-and-report Hello World

And in that function, you take the first one, Hello into your variable.

Then you do if Hello, which generates the error because indeed, Hello is not a command, so it neither succeeds nor fails.

Upvotes: 1

Barmar
Barmar

Reputation: 780724

$(command) executes command and then substitutes its standard output into the command line. So whatever useless prints is not printed on the terminal, it's substituted back into the calling command line.

So your last command becomes:

call-and-report Hello World

Then inside call-and-report, $1 is Hello, and you assign that to TEST_CRITERIA. When you do

if $TEST_CRITERIA

is equivalent to

if Hello

This tries to execute Hello as a command. Since there's no such command, you get an error.

If you want to test if there's anything in $TEST_CRITERIA, you need to use the test command, also available as [.

if [ -n "$TEST_CRITERIA" ]

Note that since you didn't quote $(useless "Hello World") each word that it outputs becomes a separate argument to call-and-report.

If you want the value of $TEST_CRITERIA printed on the terminal, you need to do that explicitly in call-and-report.

function useless
{
    echo "$1"
    return 0
}

function call-and-report
{
    TEST_CRITERIA="$1"
    echo "$TEST_CRITERIA"

    if [ -n "$TEST_CRITERIA" ]
    then
        echo "passed"
    else
        echo "failed"
    fi
}

call-and-report "$(useless  "Hello World")"

Upvotes: 2

Related Questions