1

I have a file at /tmp/variables.sh which set functions and variables like this:

#!/bin/bash
set -a
foo=bar
reader() { "/users/avnamn/bin/reader4" "$@" ; }
pricer() { "/users/avnamn/bin/pricer" "$@" ; }
sget() { "/users/avnamn/bin/sget17" "$@" ; }
sourced=yes

and a script at /tmp/script.sh which looks like this:

#!/bin/bash
if [[ "$sourced" != "yes" ]]
then
source "$(dirname "$0")/variables.sh"
fi

In bash I run:

$ cd "/tmp/"
$ source ./variables.sh
$ ./script.sh

and the shell responds like this:

bash: error importing function definition for `/users/avnamn/bin/pricer'
bash: error importing function definition for `/users/avnamn/bin/sget'

Why would it have trouble importing pricer and sget, but not reader?

  • You probably also have some aliases for pricer and sget. – Stéphane Chazelas Oct 15 at 13:05
  • Nicely caught, I did indeed have aliases to those in my bash_profile. Can you override those when setting a function? Or maybe the easiest thing is just to give the functions new names. – DisplayName Oct 15 at 13:09
4

With set -a (aka set -o allexport) bash exports all functions declared thereafter in addition to variables.

The error indicates that bash can't import a function called /users/avnamn/bin/pricer, not pricer.

Most likely before running source ./variables.sh, you had run (possibly in one of your startup files):

alias pricer=/users/avnamn/bin/pricer

So when source read:

pricer() { "/users/avnamn/bin/pricer" "$@" ; }

It was transformed by the alias expansion to:

/users/avnamn/bin/pricer() { "/users/avnamn/bin/pricer" "$@" ; }

(which by the way creates a function that calls itself recursively).

You can define a function with such a name in bash, but bash won't let you export it. If you tried export -f /users/avnamn/bin/pricer, bash would report:

bash: line <n>: export: /users/avnamn/bin/pricer: cannot export

Still with allexport, the function is exported nonetheless (which you might argue is a bug), but subsequent bash shells invoked in that environment will refuse to import it, hence the message you get upon running ./script.sh which starts a new bash invocation.

The exported function feature of bash is a very dangerous one (especially on systems where sh is bash!), it should be used sparingly.

The allexport feature is also quite dangerous (especially in bash which also exports functions) and something you would not want to do in an interactive shell.

Here, if want to export a number of variables to the environment without having to call export explicitly, I'd recommend you do:

set -o allexport
  A=1
  B=2
  ...
set +o allexport

(and make sure you don't declare functions in that section of code).

Aliases were the poor man's functions in csh that didn't have functions. In Korn-like shells, it's only useful for things that can't be done with functions, that is when you want to do some code transformation as opposed to defining some new command. They're also best avoided in most cases.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.