11

I am getting this one when I open a terminal session:

sh: error importing function definition for `read.json'

sh: error importing function definition for `ts-project'

sh doesn't like these functions because they look like:

read.json(){
   ::
}

and

ts-project(){
   ::
}

the real question is - why is sh touching/interpreting these files? I am on MacOS and seen this before, it's such a mystery. I would think only bash would be loading these files.

update: bash and sh are nothing out of the ordinary. when I type bash into the terminal, I get this:

alex$ bash
beginning to load .bashrc
finished loading .bashrc
bash-3.2$ 

when I type sh in the terminal, I get this:

alex$ sh
sh: error importing function definition for `read.json'
sh: error importing function definition for `ts-project'
sh-3.2$ 
  • 1
    Perhaps /bin/sh is bash on that system? – Jeff Schaller Aug 26 at 18:04
  • 1
    none of them source each other, I discovered that was a bad practice the hard way. however, ~/.profile is sourcing a shared bash file, so maybe sh is what sources the .profile file? – Alexander Mills Aug 26 at 18:17
  • 1
    The information about having a ~/.profile file that sources the shared file seems important to me. – Jeff Schaller Aug 26 at 18:27
  • 3
    What I meant by /bin/sh being bash is that it's possible that it's symlinked or hardlinked to bash. Bash then emulates sh, but also sources ~/.profile. I just don't know how OSX packages sh and bash. – Jeff Schaller Aug 26 at 18:30
  • 3
    They're built from the same bash source, the one with STRICT_POSIX, the other without it. – mosvy Aug 26 at 22:18
20

That error happens when bash masquerading as a POSIX shell tries to import those functions from the environment, not when loading them by interpreting a file like ~/.bashrc or such. Simplified example:

foo.bar(){ true; }; export -f foo.bar; bash --posix -c true
bash: error importing function definition for `foo.bar'

I was expecting bash not to load functions from the environment when in posix mode, but it does, and only complains when their names contain funny characters.

Notice that bash will also run in posix mode when the POSIXLY_CORRECT or POSIX_PEDANTIC environment variable is set, or when it was compiled with --enable-strict-posix-default / STRICT_POSIX.

This latter seems to be the case for /bin/sh on MacOS (look here for PRODUCT_NAME = sh), where I expect this error to also trigger when using library functions like popen(3) or system(3).

  • 3
    The fix: don't export functions in the environment. It's the bash anti-feature that led to (or rather, simply was) Shellshock and it should have been removed, but wasn't because people are foolishly using it. Don't be one of them. – R.. Aug 27 at 12:14
  • The fact that bash imports functions even when called as sh is what made the shellshock/bashdoor vulnerability a lot worse. – Stéphane Chazelas Aug 27 at 13:53
  • See also SHELLOPTS=posix and -o posix for other ways to enable the posix mode. – Stéphane Chazelas Aug 27 at 13:59
  • Also note that set -a / set -o allexport also causes bash to export all functions (and if invoked as sh, causes POSIXLY_CORRECT to be set and exported!) – Stéphane Chazelas Aug 27 at 14:04
  • (sh -a causes POSIXLY_CORRECT to be set and exported; set -a after sh without -a was started doesn't export POSIXLY_CORRECT because it was set before -a was in effect). – Stéphane Chazelas Aug 27 at 14:13
5

To answer the part about why read.json and ts-project are not portable function names:

According to POSIX, a function definition must be named by

a word consisting solely of underscores, digits, and alphabetics from the portable character set. The first character of a name is not a digit.

Also known as an identifier, in C lingo. Or in regex: [_a-zA-Z][0-9_a-zA-Z]*

  • But POSIX doesn't forbid implementations from accepting other names for functions, so bash didn't have to impose those restrictions when in POSIX mode. function names share the same namespace as command arguments, so there's no reason to accept just anything (like zsh/rc/fish...) – Stéphane Chazelas Aug 27 at 18:45
  • @StéphaneChazelas: I know, but what does it mean to be in POSIX mode, if not "shed all extensions", as in "not silently accept them"? – user2394284 Aug 28 at 7:50
  • @user2394284 it certainly doesn't mean that in bash, or it would not import functions from the environment while in POSIX mode, which is not required by the POSIX spec ;-) – mosvy Aug 28 at 9:55
  • @mosvy: Yeah, it's evident that bash failed somewhere along the way – I would say at being a plain POSIX shell, which would be a bug. – user2394284 Aug 28 at 17:18
0

So what caused it was I am sourcing some bash scripts in my ~/.bashrc file like so:

for f in "$HOME/.oresoftware/bash/"*; do
   . "$f"
done;

so I just changed it to:

for f in "$HOME/.oresoftware/bash/"*; do
  if [[ "$(basename "$0")" != 'sh' ]]; then
      # source only if not using sh
      . "$f"
  fi
done;

so in theory if it's called by sh then it won't try to source those files, but not sure if this work 100% of the time.

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.