【问题标题】:Print all environment variables but skipping multiline variables打印所有环境变量但跳过多行变量
【发布时间】:2019-10-31 04:00:57
【问题描述】:

我想打印除某些变量之外的所有环境变量。

因此我在stackoverflow上找到了解决方案:Bash: loop through variables containing pattern in name

while IFS='=' read -r name value; do
    if [ ! "$name" = "SOMEVAR" -a ! "$name" = "SOMEOTHERVAR" ]; then
        echo "$name=$value"
    fi
done < <(env)

但是,如果我的环境变量包含换行符,这将不起作用,例如:

export SOMEVAR="some
text with
newlines"

使用上述解决方案,它将打印:

text with=
newlines=
PWD=/home/...
...

我还尝试使用空终止字符串和多行匹配sed

env -0 | sed -e '{N; s@SOMEVAR.*\x0@@ ; D}' | tr '\0' '\n'

但这会切断输出并且总是首先打印具有多行内容的变量的最后一行:

newlines
PWD=/home/...
...

有没有办法在打印多行环境变量时跳过它们?

【问题讨论】:

    标签: bash loops unix environment-variables multiline


    【解决方案1】:

    您几乎拥有它,您只需要使用读取命令和空分隔符循环 env -0 的输出,并使用正则表达式运算符排除变量

    while read -r -d '' line; do 
        [[ ! $line =~ ^(SOMEVAR|SOMEOTHERVAR)= ]] && printf '%s\n' "$line" 
    done < <(env -0)
    

    带有d ''read 命令意味着在空分隔符上分隔输入。 while 循环一直运行,直到最后一个定界行被解析。

    这只是打印所有变量,不包括你想避免的变量。为了进一步处理每一行,您可以解析出$line 变量以拆分key/value 对并相应地使用它。

    或者,如果您的意图是识别包含多行字符串的 任何 变量,则可以使用正则表达式将其排除为

    [[ ! $line =~ $'\n' ]] 
    

    【讨论】:

    • 感谢您的解决方案!只要其他变量不以SOMEVAR 开头,它就可以工作,例如SOMEVAR2 不会被打印。我改用表达式^(SOMEVAR|SOMEOTHERVAR)= 解决了这个问题。如果您同意,您可以将此添加到您的答案中吗?还要感谢使用多行内容过滤每个变量的替代解决方案!
    【解决方案2】:

    您可以使用 bash 内置 compgen-v 选项一起使用时输出所有环境变量名称,因此:

    compgen -v # prints all variable names
    

    现在您可以轻松地在循环中使用它来排除不需要的名称并打印其余部分:

    while read var; do
       echo "$var=${!var}"
    done < <(compgen -v | grep -vxFE '(SOMEVAR|SOMEOTHERVAR)')
    

    【讨论】:

    • 不幸的是,在我的环境中compgen -v 给我的变量是env 的两倍。例如BASH_ARGCLINESRANDOM 或 git 完成变量。尽管如此,它是一个不错的解决方案,我不知道compgen -v 做了类似于env 的事情,谢谢!
    猜你喜欢
    • 2021-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-29
    • 2023-02-17
    • 2011-09-09
    相关资源
    最近更新 更多