为什么sh(不是bash)抱怨.bashrc中定义的函数?


11

打开终端会话时,我得到了这个:

sh:导入“ read.json”的函数定义时出错

sh:导入“ ts-project”的函数定义时出错

sh不喜欢这些功能,因为它们看起来像:

read.json(){
   ::
}

ts-project(){
   ::
}

真正的问题是-为什么要sh触摸/解释这些文件?我在MacOS上,以前曾经看过,这真是个谜。我认为只有bash会加载这些文件。

更新:bash和sh并没有什么不同。当我在终端中输入bash时,得到以下信息:

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

当我sh在终端输入时,得到以下信息:

alex$ sh
sh: error importing function definition for `read.json'
sh: error importing function definition for `ts-project'
sh-3.2$ 

1
也许/ bin / sh 在该系统上 bash?
杰夫·谢勒

1
他们俩都没有相互寻找资源,我发现这是一种艰难的做法,很难做到。但是,〜/ .profile正在获取共享的bash文件,那么sh,.profile文件的来源可能是什么?
亚历山大·米尔斯

1
在我看来,有关拥有〜/ .profile文件来获取共享文件的信息似乎很重要。
杰夫·谢勒

3
我所说的/ bin / sh是bash的意思是它可能与bash链接或硬链接。然后Bash模仿sh,但也模仿〜/ .profile。我只是不知道OSX如何打包sh和bash。
杰夫·谢勒

3
它们是从相同的bash来源构建的,一个带有STRICT_POSIX,另一个没有。
mosvy

Answers:


20

bash伪装成POSIX shell尝试从环境中导入这些函数时,而不是通过解释诸如此类的文件来加载它们时,就会发生该错误~/.bashrc。简化示例:

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

我曾期望bash在posix模式下从环境中加载函数,但确实如此,并且仅在其名称包含有趣字符时抱怨。

请注意,bash当设置了POSIXLY_CORRECTPOSIX_PEDANTIC环境变量或使用--enable-strict-posix-default/ 编译时,它也将以posix模式运行STRICT_POSIX

后者似乎适用/bin/sh于MacOS(在此处查看PRODUCT_NAME = sh),我希望在使用类似popen(3)或的库函数时也会触发此错误system(3)


3
解决方法:不要在环境中导出功能。导致(或者更简单地说,是)Shellshock的是bash的反特征,应该将其删除,但这并不是因为人们愚蠢地使用了它。不要成为其中之一。
R .. GitHub STOP HELPING ICE

该庆典进口功能,即使是所谓的事实sh是什么让弹震/ bashdoor漏洞很多糟糕。
斯特凡Chazelas

另请参见SHELLOPTS=posix以及-o posix有关启用posix模式的其他方式。
斯特凡·查泽拉斯19'Aug

另请注意,set -a/ set -o allexport还会导致bash导出所有函数(如果以调用sh,将导致POSIXLY_CORRECT设置和导出!)
StéphaneChazelas 19年

sh -a导致POSIXLY_CORRECT设置和导出;未开始set -a后将不导出,因为它在生效之前已设置)。sh-aPOSIXLY_CORRECT-a
斯特凡·查泽拉斯19'Aug

5

要回答关于为什么read.jsonts-project不是可移植函数名称的部分:

根据POSIX,一个函数定义必须命名

仅由可移植字符集中的下划线,数字和字母组成的单词。名称的第一个字符不是数字。

在C语言中也称为标识符。或在正则表达式中:[_a-zA-Z][0-9_a-zA-Z]*


但是POSIX并不禁止实现接受函数的其他名称,因此bash 在POSIX模式下不必强加这些限制。函数名称与命令参数共享相同的名称空间,因此没有理由仅接受任何内容(例如zsh/ rc/ fish...)
StéphaneChazelas 19年

@StéphaneChazelas:我知道,但是如果不“放弃所有扩展名”,例如“不静默接受它们”,处于POSIX模式意味着什么?
user2394284

@ user2394284,这当然并不意味着in bash,或者在POSIX模式下它不会从环境中导入功能,这不是POSIX规范所必需的;-)
mosvy

@mosvy:是的,很明显,bash在此过程中失败了–我要说的是使用普通的POSIX shell,这将是一个错误。
user2394284

0

所以造成这种情况的原因是我在〜/ .bashrc文件中采购了一些bash脚本,如下所示:

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

所以我只是将其更改为:

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

因此,从理论上讲,如果它被调用,sh它将不会尝试获取那些文件,但是不确定是否可以100%地工作。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.