bash:function+;来源+;宣布=繁荣
这里有一个问题: 在我的bash脚本中,我想通过一些检查来获取几个文件的源代码,因此我有:bash:function+;来源+;宣布=繁荣,bash,function,Bash,Function,这里有一个问题: 在我的bash脚本中,我想通过一些检查来获取几个文件的源代码,因此我有: if [ -r foo ] ; then source foo else logger -t $0 -p crit "unable to source foo" exit 1 fi if [ -r bar ] ; then source bar else logger -t $0 -p crit "unable to source bar" exit 1 fi # ...
if [ -r foo ] ; then
source foo
else
logger -t $0 -p crit "unable to source foo"
exit 1
fi
if [ -r bar ] ; then
source bar
else
logger -t $0 -p crit "unable to source bar"
exit 1
fi
# ... etc ...
我天真地尝试创建一个函数,它可以:
function safe_source() {
if [ -r $1 ] ; then
source $1
else
logger -t $0 -p crit "unable to source $1"
exit 1
fi
}
safe_source foo
safe_source bar
# ... etc ...
但是这里有一个障碍
如果其中一个文件foo
,bar
等具有全局--
--它将有效地成为:
function safe_source() {
# ...
declare GLOBAL_VAR=42
# ...
}
因此,全局变量变为局部变量
问题:
bash中的别名似乎太弱了,所以我必须展开上面的函数并重复我自己的操作,还是有更优雅的方法
。。。是的,我同意Python、Perl、Ruby会让我的生活更轻松,但在使用遗留系统时,人们并不总是有权选择最好的工具。
函数内部的declare
会使变量成为该函数的局部变量<代码>导出影响子进程的环境,而不是当前或父环境
您可以在函数中设置变量的值,并在事后执行
declare-r
、declare-i
或declare-ri
。是的,Bash的'eval'命令可以实现这一点“eval”不是很优雅,有时很难理解和调试使用它的代码。我通常会尽量避免,但Bash通常会让您别无选择(比如引发您的问题的情况)。你必须权衡自己使用“eval”的利弊
“评估”的一些背景
如果您不熟悉“eval”,它是一个Bash内置命令,希望您将字符串作为参数传递给它eval’在当前shell上下文和作用域中以命令的形式动态解释和执行字符串。下面是一个常见用法(动态变量赋值)的基本示例:
有关更多信息和示例,请参阅高级Bash脚本指南:
解决你的“源头”问题
要让“eval”处理您的寻源问题,您首先要重写函数“safe_source()”。“safe_source()”不应实际执行命令,而应在STDOUT上将命令打印为字符串:
function safe_source() { echo eval " \
if [ -r $1 ] ; then \
source $1 ; \
else \
logger -t $0 -p crit \"unable to source $1\" ; \
exit 1 ; \
fi \
"; }
此外,您还需要稍微更改函数调用,以实际执行“eval”命令:
`safe_source foo`
`safe_source bar`
(顺便说一句,这些是反勾号/反引号。)
工作原理
简言之:
- 我们将函数转换为命令字符串发射器
- 我们的新函数发出一个“eval”命令调用字符串
- 我们的新backticks在子shell上下文中调用新函数,将函数输出的“eval”命令字符串返回到主脚本
- 主脚本在主脚本上下文中执行backticks捕获的“eval”命令字符串
- “eval”命令字符串在主脚本上下文中重新解析并执行“eval”命令字符串,运行整个if-then-else块,包括(如果文件存在)执行“source”命令
- 整个IF-THEN-ELSE块变成了一个完整的双引号字符串,每行末尾的反斜杠“隐藏”了换行符
- 一些shell特殊字符(如“')已被反斜杠转义,而其他(“$”)未被转义
- “echo eval”已在整个命令字符串前面加上前缀
- 额外的分号已附加到执行命令以终止它们的所有行,这是(现在隐藏的)新行最初执行的角色
- 函数调用已包装在反勾号中
echo eval ' if [ -r <INCL_FILE> ] ; then source <INCL_FILE> ; else logger -t <SCRIPT_NAME> -p crit "unable to source <INCL_FILE>" ; exit 1 ; fi '
echo eval'如果[-r];则为震源;否则记录器-t-p crit“无法震源”;退出1;fi'
然后,在主上下文中,主脚本执行以下操作:
eval if '[' -r <INCL_FILE> ']' ';' then source <INCL_FILE> ';' else logger -t <SCRIPT_NAME> -p crit '"unable' to source '<INCL_FILE>"' ';' exit 1 ';' fi
eval if'['-r']'';then source';else logger-t-p crit''canable'to source''”;'exit 1';'fi
最后,同样在主上下文中,eval命令执行这两个命令(如果存在):
'[' -r <INCL_FILE> ']'
source <INCL_FILE>
'['-r']'
来源
祝你好运。回答有点晚,但现在
declare
支持一个-g
参数,该参数使变量成为全局变量(当在函数中使用时)。同样适用于源文件
如果需要全局(读取导出)变量,请使用:
declare -g DATA="Hello World, meow!"
如果您使用
export
而不是declare
,可能会起作用。我在简化。实际上我使用了declare-r
(只读),有时使用declare-ri
(只读,整数)当我放弃<代码>声明>代码>的时候,我也可以在需要时使用<代码> Read Ong/<代码>,但是我找不到一个替代的代码>声明-i <代码>。BTW,<代码>声明-X/COD>在一个函数中仍然是一个局部的。你真的需要使用<代码>声明-I/代码>,它的使用是不可变的吗?我可以考虑忽略它,因为我很确定,对于您试图用声明:)实现的目标,没有一个解决方案。我想您的意思是(Python、Perl、Ruby)将使您的生活不再简单,我想您的意思是将函数命名为safe而不是save source():)红牛的一个副作用,也许?
'[' -r <INCL_FILE> ']'
source <INCL_FILE>
declare -g DATA="Hello World, meow!"