2

I have a bash script that contains the following:

MY_COMMAND="MY_PWD=`pwd`; export MY_PWD; MY_PWD_BASENAME=`basename $MY_PWD`; echo $MY_PWD_BASENAME"; export MY_COMMAND

When I source the script from the terminal, I get the following error:

basename: missing operand
Try `basename --help' for more information.

This indicates that the commands in MY_COMMAND are not executed in sequential order. What is happening here?

hek2mgl
  • 152,036
  • 28
  • 249
  • 266
Morad
  • 2,761
  • 21
  • 29

1 Answers1

5

The following line:

MY_COMMAND="MY_PWD=`pwd`; export MY_PWD; MY_PWD_BASENAME=`basename $MY_PWD`; echo $MY_PWD_BASENAME"

will not execute the following commands (as you may think):

MY_PWD=`pwd`
export MY_PWD
MY_PWD_BASENAME=`basename $MY_PWD`
echo $MY_PWD_BASENAME"

Instead it will expand the command substitutions

`pwd`
`basename $MY_PWD`

and replace them with their output. Since $MY_PWD is not set, basename will get executed without the required argument, like:

basename

That leads to the error.


Fix: I recommend to use $() instead of backticks for the command substitution. One benefit is that you can nest them:

MY_COMMAND="MY_PWD=$(pwd); export MY_PWD; MY_PWD_BASENAME=$(basename "$(pwd)"); echo $MY_PWD_BASENAME"

However, that's just the syntax fix. Generally I recommend to use a function like @chepner suggested

lib.sh

function basename_pwd() {
    basename "$(pwd)"
}

Use the function:

#!/bin/bash
source "lib.sh"
basename_pwd
hek2mgl
  • 152,036
  • 28
  • 249
  • 266