我遇到了困扰我一整天的大问题。
我有许多函数文件,它们具有基于用途的各种功能,即。SSH、日志记录等。
我有一个脚本,可以在其中将错误添加到全局错误数组中。我有一个错误陷阱,它调用另一个“exit_functions”文件中的脚本。
在这个 exit_functions 文件中,我做了很多事情,但我遇到问题的部分是一个循环,它运行这个数组并拉出实际上是命令的数组元素。这些命令是函数文件之一中的函数,这些函数文件已包含在调用脚本中,使用普通的 . /path/to/functions_file 语法。
我的所有其他功能(例如日志记录等)都在 exit_functions 文件中工作,只是这些特定功能无法调用。我收到一个错误:
/functions/exit_functions: line 109: closeSSHTunnel /tmp/ssh_tunnel_iA0yj.lck: No such file or directory
现在,killSSHTunnel 是一个函数,它位于以前包含的函数文件中,就像包含其他函数文件一样。我只使用数组中的这些函数调用得到这个错误。
我不确定我是否正确描述了它 - 如果我可以提供任何其他信息,请告诉我。
编辑下面的完整功能代码:
/functions/exit_functions 文件: exitTrap (){ local LCL_SCRIPT_ERROR
if [ $ERR_COUNT_EXIT_FUNCT -gt 0 ]; then
for LCL_SCRIPT_ERROR in "${ERROR_ARRAY[@]}"; do
case $LCL_SCRIPT_ERROR in
SVN_IMPORT ) # match the SVN_IMPORT error name and search for specific commands to run
exitMsg "$LCL_SCRIPT_ERROR; 111"
executeErrorActions $LCL_SCRIPT_ERROR
exitScript 111
;;
* ) exitMsg "$LCL_SCRIPT_ERROR; 255"
exitScript 255
;;
esac
done
fi
}
所以我的测试代码引入了一个错误状态,最终调用了上面的函数(exitTrap)。它已经填充了一个名为 ERROR_ARRAY 的数组。
因此,executeErrorActions 函数(也在 /functions/exit_functions 中)循环关联数组 ERROR_ACTION_ARRAY,寻找一个名为(在此测试中)SVN_IMPORT的键。当它找到这个键时,它正在寻找一个以 ':' 分隔的字符串。每个分隔部分将是一个单独的命令,当出现这种错误情况时我要运行它。在我的测试中,我有一个简单的条目(没有分隔符): *closeSSHTunnel /tmp/ssh_tunnel_iA0yj.lck*
现在,使用下面的函数,当我不包含 IFS= 和未设置 IFS 之间的部分时,它可以正常工作,而是只使用下面有双注释哈希的单行。一旦我引入 IFS 分隔符来分解字符串,我就会得到错误:
/functions/exit_functions:第 109 行:closeSSHTunnel /tmp/ssh_tunnel_iA0yj.lck:没有这样的文件或目录
executeErrorActions (){
if [ ! $# -eq 1 ]; then
return 1
fi
local ERROR_NAME=$1
local ERROR_ACTION
#ERROR_KEY="SVN_IMPORT"
for ERROR_ACTION in ${!ERROR_ACTION_ARRAY[@]}; do
#echo KEY: $i VALUE: ${ERROR_ACTION_ARRAY[$i]}
if [ $ERROR_NAME == $ERROR_ACTION ]; then
##$(${ERROR_ACTION_ARRAY[$ERROR_ACTION]})
IFS=":"
for i in ${ERROR_ACTION_ARRAY[$ERROR_ACTION]}; do
$i
done
unset IFS
return 0
fi
done
}
这是使用两个“:”分隔的命令、上面相同的closeSSHTunnel函数和一个简单的ls -la调用的测试运行的 set -x 输出。我使用 addError 函数调用将这些添加到 ERROR_ACTION_ARRAY 中,如下所示:
addError SVN_IMPORT closeSSHTunnel $SSH_TUNNEL_LCK_FILE:ls -la
这是 set -x 输出:
+ executeErrorActions SVN_IMPORT
+ '[' '!' 1 -eq 1 ']'
+ local ERROR_NAME=SVN_IMPORT
+ local ERROR_ACTION
+ for ERROR_ACTION in '${!ERROR_ACTION_ARRAY[@]}'
+ '[' SVN_IMPORT == SVN_IMPORT ']'
+ IFS=:
+ for i in '${ERROR_ACTION_ARRAY[$ERROR_ACTION]}'
+ 'closeSSHTunnel /tmp/ssh_tunnel_iA0yj.lck'
/functions/exit_functions: line 116: closeSSHTunnel /tmp/ssh_tunnel_iA0yj.lck: No such file or directory
+ for i in '${ERROR_ACTION_ARRAY[$ERROR_ACTION]}'
+ 'ls -la'
/functions/exit_functions: line 116: ls -la: command not found
+ unset IFS
+ return 0
请注意其中一个说“没有这样的文件或目录”,而另一个说“找不到命令”。现在是第 2 天,试图解决这个问题!
我的结论是 IFS 更改和字符串分解导致问题。
编辑 2
如果我稍微移动 IFS 调用并在循环内的 ':' 字符上终止 IFS,然后在执行调用后再次建立它,一切正常!!!!!!
for ERROR_ACTION in ${!ERROR_ACTION_ARRAY[@]}; do
#echo KEY: $i VALUE: ${ERROR_ACTION_ARRAY[$i]}
if [ $ERROR_NAME == $ERROR_ACTION ]; then
#$(${ERROR_ACTION_ARRAY[$ERROR_ACTION]})
IFS=$':'
for i in ${ERROR_ACTION_ARRAY[$ERROR_ACTION]}; do
unset IFS
$i
IFS=$':'
done
unset IFS
return 0
fi
done
谁能解释一下?