![set -a 后无法在 bash 中导入一些简单函数?](https://linux22.com/image/181822/set%20-a%20%E5%90%8E%E6%97%A0%E6%B3%95%E5%9C%A8%20bash%20%E4%B8%AD%E5%AF%BC%E5%85%A5%E4%B8%80%E4%BA%9B%E7%AE%80%E5%8D%95%E5%87%BD%E6%95%B0%EF%BC%9F.png)
我有一个文件,/tmp/variables.sh
其中设置如下函数和变量:
#!/bin/bash
set -a
foo=bar
reader() { "/users/avnamn/bin/reader4" "$@" ; }
pricer() { "/users/avnamn/bin/pricer" "$@" ; }
sget() { "/users/avnamn/bin/sget17" "$@" ; }
sourced=yes
/tmp/script.sh
和一个如下所示的脚本:
#!/bin/bash
if [[ "$sourced" != "yes" ]]
then
source "$(dirname "$0")/variables.sh"
fi
在 bash 中我运行:
$ cd "/tmp/"
$ source ./variables.sh
$ ./script.sh
shell 的响应如下:
bash: error importing function definition for `/users/avnamn/bin/pricer'
bash: error importing function definition for `/users/avnamn/bin/sget'
pricer
为什么导入and会遇到麻烦sget
,但导入却没有呢reader
?
答案1
使用set -a
(又名set -o allexport
)bash
导出所有功能除了变量之外还声明了此后。
错误提示bash
不能进口/users/avnamn/bin/pricer
一个名为, not 的函数pricer
。
最有可能在运行之前source ./variables.sh
,您已经运行过(可能在启动文件之一中):
alias pricer=/users/avnamn/bin/pricer
所以当source
阅读时:
pricer() { "/users/avnamn/bin/pricer" "$@" ; }
它通过别名扩展转换为:
/users/avnamn/bin/pricer() { "/users/avnamn/bin/pricer" "$@" ; }
(顺便说一下,它创建了一个递归调用自身的函数)。
您可以在 中定义具有此类名称的函数bash
,但bash
不允许您导出它。如果您尝试过export -f /users/avnamn/bin/pricer
,bash
会报告:
bash: line <n>: export: /users/avnamn/bin/pricer: cannot export
还是用allexport
, 函数是尽管如此,它仍然被导出(您可能会认为这是一个错误),但在该环境中调用的后续shell 将拒绝导入它,因此您在运行时会收到启动新调用的bash
消息。./script.sh
bash
bash 的导出函数功能是一个非常危险的功能(尤其是在有此功能的系统上sh
!bash
),应谨慎使用。
该allexport
功能也非常危险(尤其是bash
还导出功能)并且您会不是想要在交互式 shell 中执行操作。
在这里,如果想将多个变量导出到环境而不必export
显式调用,我建议您这样做:
set -o allexport
A=1
B=2
...
set +o allexport
(并确保您没有在该代码部分声明函数)。
别名是 csh 中没有函数的可怜人的函数。在类似 Korn 的 shell 中,它仅对无法使用函数完成的事情有用,即当您想要进行一些代码转换而不是定义一些新命令时。在大多数情况下,最好还是避免使用它们。