从管道命令附加到数组变量 [英] Append to an array variable from a pipeline command

查看:114
本文介绍了从管道命令附加到数组变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个bash函数来获取所有git存储库,但是当我要将所有git存储库路径名存储到数组patharray时遇到了一个问题.这是代码:

I am writing a bash function to get all git repositories, but I have met a problem when I want to store all the git repository pathnames to the array patharray. Here is the code:

gitrepo() {
    local opt

    declare -a patharray
    locate -b '\.git' | \
        while read pathname
        do
            pathname="$(dirname ${pathname})"
            if [[ "${pathname}" != *.* ]]; then
            # Note: how to add an element to an existing Bash Array
                patharray=("${patharray[@]}" '\n' "${pathname}")
                # echo -e ${patharray[@]}
            fi
        done
    echo -e ${patharray[@]}
}

我想将所有存储库路径保存到patharray数组,但是我无法在由locatewhile命令组成的pipeline之外获取它. 但是我可以在pipeline命令中获取数组,如果没有注释,带注释的命令# echo -e ${patharray[@]}效果很好,那么我该如何解决该问题?

I want to save all the repository paths to the patharray array, but I can't get it outside the pipeline which is comprised of locate and while command.
But I can get the array in the pipeline command, the commented command # echo -e ${patharray[@]} works well if uncommented, so how can I solve the problem?

我已经尝试过export命令,但是似乎无法将patharray传递给管道.

And I have tried the export command, however it seems that it can't pass the patharray to the pipeline.

推荐答案

首先,最好使用array[${#array[*]}]="value"array+=("value1" "value2" "etc")附加到数组变量上,除非您希望变换整个数组(您不希望这样做). t).

First of all, appending to an array variable is better done with array[${#array[*]}]="value" or array+=("value1" "value2" "etc") unless you wish to transform the entire array (which you don't).

现在,因为运行了流水线命令在子流程中,在管道命令内部对变量所做的更改不会传播到外部.有几种解决方法(大多数列出在 Greg的BashFAQ/024 中):

Now, since pipeline commands are run in subprocesses, changes made to a variable inside a pipeline command will not propagate to outside it. There are a few options to get around this (most are listed in Greg's BashFAQ/024):

  • 改为通过stdout传递结果

  • 最简单的;您仍然需要这样做以从函数中获取值(尽管那里是返回适当变量的方法)
  • 通过使用\0作为分隔符,可以可靠地处理路径中的任何特殊字符(请参阅

  • the simplest; you'll need to do that anyway to get the value from the function (although there are ways to return a proper variable)
  • any special characters in paths can be handled reliably by using \0 as a separator (see Capturing output of find . -print0 into a bash array for reading \0-separated lists)

locate -b0 '\.git' | while read -r -d '' pathname; do dirname -z "$pathname"; done

或者简单地

locate -b0 '\.git' | xargs -0 dirname -z

避免在子进程中运行循环

  • 完全避免使用管道

  • avoid pipeline at all

i=0    #`unset i` will error on `i' usage if the `nounset` option is set
while IFS= read -r -d $'\0' file; do
  patharray[i++]="$(dirname "$file")"    # or however you want to process each file
done < <(locate -b0 '\.git')

使用lastpipe选项(Bash 4.2中的新增功能)-不在子进程中运行管道的 last 命令(中等:具有全局效果)

use the lastpipe option (new in Bash 4.2) - doesn't run the last command of a pipeline in a subprocess (mediocre: has global effect)

这篇关于从管道命令附加到数组变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆