关于autoconf生成的shell脚本的一部分的许多问题

时间:2015-02-09 06:01:04

标签: bash shell

以下是shell脚本的代码段。 (它来自MPFR库的配置脚本,它以#!/ bin / sh开头。原始脚本长度超过17000行。在构建gcc时使用它。)

因为我在一小段代码中有很多问题,所以我在代码中嵌入了我的问题。请有人向我解释为什么代码是这样的?此外,虽然我有一个模糊的想法,但如果有人能解释这段代码的作用,我将不胜感激(我知道这很难,因为它只是一个大脚本的一部分)。

if { { ac_try="$ac_link"      
    # <---- question 1 : why is the first curly bracket used for if condition? (probably just for grouping and using the last return code)
    # <---- question 2 : Is this second bracket for locally used code(probably)?
case "(($ac_try" in           # <---- question 3 : what is this "((" symbol?
  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
  *) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5     # <---- question 4 : what is this >&5 redirection? I know >&{1,2,3} but not 5.
  (eval "$ac_link") 2>&5
    # <----- question 5 : why use sub-shell here? not to use eval result?
  ac_status=$?
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }; then :  # <---- question 6 : is this ':'(nop) here ?
    ....
    some commands
    ....
else
    ....
    some commands
    ....
fi

1 个答案:

答案 0 :(得分:3)

来自Bash手册页:

  

{list; }                 list只是在当前的shell环境中执行。名单                 必须以换行符或分号结尾。这是众所周知的                 作为一个团体命令。返回状态是退出状态                 名单。请注意,与元字符(和)不同,{和}是                 保留字,必须出现在允许保留字的地方                 被认可。因为它们不会导致单词中断                 必须通过空格或其他shell与列表分隔                 元字符。

{}只列出一些要运行的命令,非常类似于cmd1; cmd2; cmd3。例如,如果您撰写cmd1 ; cmd2 | cmd3,则表示{cmd1; cmd2;} | cmd3cmd1; {cmd2 | cmd3;}

{{ }}只是嵌套的命令列表,很简单:例如{cmd1; cmd2; {cmd3; cmd4;}; }

对于问题3,((只是在一个源字符串中,与以下模式匹配。如果您问为什么使用它,我们需要$ac_try的可能值来分析原因。老实说,我没有看到很多shell脚本故意在源字符串前添加((以匹配模式。

问题4, >&5:如果尚未创建文件描述符5(即在脚本的任何部分提到... =&gt;小心,你需要关心范围,一些代码在子shell中运行,这是计算的作为子shell上下文/范围),使用描述符5创建一个未命名的文件(好吧,临时文件,如果你愿意)。这个文件可以在脚本的其他部分用作输入。

例如,在我对另一个问题here的回答中,请参阅提及“交换STDIN和STDOUT”的部分。

对于问题5,eval,我不太确定,只是一个快速猜测(并且它取决于它所篡改的命令),为您提供一个示例,说明为什么子shell会产生一些差异:

cmd="Foo=1; ls"
(eval $cmd)   # this command runs in sub-shell and thus $Foo in current shell will not be changed.
eval $cmd     # this command runs in current shell and thus $Foo is changed, and it will affect all subsequent commands.

对于问题6,请仔细查看我在答案顶部提到的手册页,{}列表语法,需要最终;。即{cmd1; cmd2 ; }最后;是必需的。

---更新---

问题6:抱歉没看到冒号... :-) 这不是操作:见this link