Bash - 变量不在其他变量中评估

时间:2015-07-23 15:58:38

标签: linux bash shell unix

我写了一个简短的脚本,需要使用正则表达式找到一些文本。

我在while循环中递增一个计数器,这个计数器是另一个命令的一部分。不幸的是,这个命令总是与初始计数器一起运行。

这是我代码中的代码段:

function evaluate(data) {
  var newData = {};
  _.each(data, _.rearg(_.partial(_.set, newData), [1, 0]));
  return definedItemsOnly(newData);
}

2 个答案:

答案 0 :(得分:2)

封装代码的最佳实践方法(根据BashFAQ #50)具有以下功能:

get_last_commit() {
  git log remotes/origin/devel --pretty=oneline --pretty=format:%s \
    | sed -n "$(( $1 + 1)) p"
}

然后:

while (( counter < 5 )); do
  last_commit=$(get_last_commit "$counter")
  IFS=$'\n' read -r -d '' -a jira_id \
    < <(grep -o -P '[A-Z]{2,}-\d+' <<<"$last_commit") ||:
  [[ $jira_id ]] || break

  echo "This is the current  counter:  $counter"
  echo "This is the last commit $last_commit"
  echo "Found ${#jira_id[@]} jira IDs"
  printf '  %s\n' "${jira_id[@]}"

  (( counter++ ))
done

其他说明:

  • 此处使用read -a将JIRA ID读入数组;然后,您可以询问数组的长度(使用${#jira_id[@]}),从数组中展开特定条目(使用${jira_id[0]}获取第一个ID,第二个为[1],等等);将它们全部扩展到参数列表(使用"${jira_id[@]}")等
  • 非系统定义的shell变量名称中至少应包含一个小写字符。请参阅http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html上关于环境变量的POSIX规范的第四段,请记住环境变量和shell变量共享一个命名空间。遵循此练习可以防止您错误地覆盖系统变量。
  • $(( ... ))是POSIX标准的输入数学上下文的方法;没有前导(( ))的{​​{1}}是bash扩展名。
  • 虽然$[[ ]]内的代码不需要双引号来阻止全局扩展或字符串拆分,但在(几乎)所有其他情况下扩展应该使用双引号。
  • (( ))sed '2 p'更有效地获得第2行。

然而,即使这样做效率也远低于仅仅调用head -2 | tail -n 1一次并迭代其结果的效率。

git log

答案 1 :(得分:0)

Bash是一种过程语言,意味着它包含了一系列按顺序执行的步骤。

LAST_COMMIT=`...`是将变量LAST_COMMIT设置为命令值的步骤。您已将此步骤仅执行一次,这就是您反复看到相同值的原因。

如果您希望它再次为$COUNTER的新值执行,您可以将该语句放在循环中:

while
    LAST_COMMIT=`git log remotes/origin/devel --pretty=oneline --pretty=format:%s | head -${COUNTER} | tail -n 1`
    JIRA_ID=`echo $LAST_COMMIT | grep -o -P '[A-Z]{2,}-\d+' | xargs`
    [[ ! -z "$JIRA_ID" && $COUNTER -lt "5" ]]
do

    echo "This is the current  counter:  $COUNTER"
    echo "This is the last commit $LAST_COMMIT"
    COUNTER=$[COUNTER+1]
done
echo "this is the counter outside the loop $COUNTER"

由于循环中的步骤多次执行,LAST_COMMIT=`...`步骤也会多次执行,每次都使用$COUNTER的新值。