kaligne
kaligne

Reputation: 3278

Bash function arguments not passed as expected

I have an unexpected behaviour in my script:

#!/bin/bash
checkFolders "first folder"

checkFolders() {
    checkEmptyVar $1 "folder to be copied"
}

checkEmptyVar() {
    echo "0: $0  1: $1   2: $2"
    [[ $(isNotEmpty $1) = false ]] && (echo "Specify a path for $2") && exit
    echo "post exit"
}

The function checkEmptyVar echoes the following:

0: ./lcp.sh  1: folder to be copied   2: 

I expected to have passed "folder-to-be-copied" as $1of checkEmptyVar, what is happening?

Upvotes: 2

Views: 2271

Answers (2)

chepner
chepner

Reputation: 532313

You have numerous problems:

  1. $0 is not the first argument to a function; $1 is. $0 is the name of the current script.
  2. You must quote parameter expansions to prevent them from being split into multiple words on embedded whitespace.
  3. Functions must be defined before they are used.

The correct script is

#!/bin/bash


checkFolders() {
    checkEmptyVar "$1" "folder to be copied"
}

checkEmptyVar() {
    [[ $(isNotEmpty "$1") = false ]] && echo "Specify a path for $2" && exit
    echo "post exit"
}

checkFolders "first folder"

Further, it would be better to have isNotEmpty return a non-zero value instead of outputting the string false, so that you could write

checkEmptyVar () {
    if isNotEmpty "$1"; then
        echo "Specify a path for $2" >&2   # Use standard error, not standard output
        exit 1
    fi
    echo "post exit"
}

(I suspect you could replace isNotEmpty with [[ -n $1 ]] anyway.)

Upvotes: 3

Etan Reisner
Etan Reisner

Reputation: 81052

This script isn't doing what you think it is. Your function definitions are happening too late.

When you call checkFolders on the first line you are calling a version of that function from the pre-existing environment and not the one defined later in that script.

If you run command -V checkFolders from the shell you are running this script from I expect you'll get output somewhat like:

checkFolders is a function
checkFolder ()
{
    checkEmptyVar "folder to be copied"
}

though anything is possible there.

You should also always quote variables when you use them to prevent the shell from word-splitting their contents.

Without doing that when you call checkFolders "first folder" that ends up calling checkFolders first folder "folder to be copied" which isn't what you want at all.

Invert the order of your functions and calls and fix your variable quoting and you should see what you expect.

Upvotes: 1

Related Questions