Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux Bash-变量不在其他变量中计算_Linux_Bash_Shell_Unix - Fatal编程技术网

Linux Bash-变量不在其他变量中计算

Linux Bash-变量不在其他变量中计算,linux,bash,shell,unix,Linux,Bash,Shell,Unix,我写了一个简短的脚本,需要使用正则表达式查找一些文本 我在while循环中递增一个计数器,这个计数器是另一个命令的一部分。不幸的是,此命令总是与初始计数器一起运行 下面是我的代码片段: COUNTER=1 LAST_COMMIT=`git log remotes/origin/devel --pretty=oneline --pretty=format:%s | head -${COUNTER}` JIRA_ID=`echo $LAST_COMMIT | grep -o -P '[A-Z]{2,

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

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

下面是我的代码片段:

COUNTER=1
LAST_COMMIT=`git log remotes/origin/devel --pretty=oneline --pretty=format:%s | head -${COUNTER}`
JIRA_ID=`echo $LAST_COMMIT | grep -o -P '[A-Z]{2,}-\d+' | xargs`

while [[ ! -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"

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

LAST\u COMMIT=`…`
是将变量
LAST\u 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
的新值

封装代码的最佳实践方法(根据)是使用以下函数:

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


您只需运行一次命令。初始值为
$COUNTER
。如果需要使用不同的值运行它,则需要再次运行它。
LAST\u COMMIT
JIRA\u ID
在设置后都不会更改。另外,
| xargs
在那里可能毫无意义,因为它只是
/bin/echo
;每次需要获取新的
LAST\u COMMIT
值时,都需要运行该命令。在循环之前不止一次。每次你想要获得一个新的
JIRA\u ID
值(来自一个新的
LAST\u COMMIT
值)时,都会发生同样的事情。@AlG No.糟糕。这里甚至根本不需要eval。您还可以告诉
git log
直接输出多少个条目,而不需要
head
。每次你的
计数器
递增时,这将从
git log
中获得越来越多的输出行,我认为这不是你想要的。(我还认为,
--pretty=format
正在重写
--pretty=oneline
,因此您可能不需要两者。)我认为这是一种解决方法,因为如果第一次提交包含JIRA ID,则while不应运行,如果我不需要,请更正wrong@user3502786我没有注意到,但它仍然是相同的概念。您需要循环中的语句。我已经更新了。所以我们需要在这里复制一个代码,这是不正确的good@user3502786你在哪里看到重复代码?while中的条件应该是,除非Jira ID为空,否则继续循环,计数器<5只是为了演示,我不想得到无限循环。顺便问一下,您建议如何避免使用xargs
应该是,
?你错过了什么。无论如何,请参见
[[$jira_id]]| | break
,如果
jira_id
在分配后一直为空,则它将停止循环。将该条件放入
本身意味着您永远不会进入循环开始,因为变量在循环的第一次迭代运行之前是空的!是的,但我不能使用计数器<5作为循环终止,因为我不知道需要扫描多少个提交,然后使用
而不是true
。这就是我的想法,避免xargs怎么样
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
while IFS= read -r -u 3 last_commit; do
  IFS=$'\n' read -r -d '' -a jira_id \
    < <(grep -o -P '[A-Z]{2,}-\d+' <<<"$last_commit") ||:
  [[ $jira_id ]] || continue
  echo "Found ${#jira_id[@]} jira IDs"
  printf '  %s\n' "${jira_id[@]}"
done 3< <(git log remotes/origin/devel --pretty=oneline --pretty=format:%s)