Search code examples
bashevalsubshell

Subshell in a function cannot find basic bash commands when called from another function


I have the following bash script (this is a simplified version of a more complex script).

#!/usr/bin/env bash
set -x

function execute() {
    `$1` # same as $($1), gives "command not found" as do all the following:
    # $1 # or ${1}
    # eval "$1"
    # eval $1

    # This gives "No such file or directory" even though it *is* there...
    #"$1"
}

function runCommand() {
    PATH="${1}"
    execute "chmod 777 ${PATH}"
}

execute "chmod 777 ${1}"
runCommand "$1"

#EOF

When I run it I get the following output:

+ execute 'chmod 777 build.test-case.sh'
++ chmod 777 build.test-case.sh
+ runCommand build.test-case.sh
+ PATH=build.test-case.sh
+ execute 'chmod 777 build.test-case.sh'
++ chmod 777 build.test-case.sh
./build.test-case.sh: line 5: chmod: command not found

So chmod works when the execute function is called directly but fails when it is called from another function, even though the debug output seems to be exactly the same...

Can anyone explain this behaviour?


Solution

  • The problem is that you are overwriting the PATH variable, which contains the paths to the directories where the binaries are, like the chmod one, so that's why it can't find it.

    If you use another variable, instead of the PATH one, for your runCommand() function, it should work, like this:

    function runCommand() {
        VAR="${1}"
        execute "chmod 777 ${VAR}"
    }