如何在 bash 中访问名称中有空格的环境变量?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18468397/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 06:24:16  来源:igfitidea点击:

How can you access an environment variable that has a space in its name in bash?

bashjenkins

提问by Spycho

Running envreturns "Clear Workspace=true". How can I access it in bash? FYI, it's coming from a Jenkins Parameterized Build parameter name. ${Clear Workspace}does not appear to work.

运行env返回“Clear Workspace=true”。如何在 bash 中访问它?仅供参考,它来自 Jenkins 参数化构建参数名称。${Clear Workspace}似乎不起作用。

Also, how is Jenkins even able to create this environment variable? Running Clear Workspace=truein bash obviously doesn't work as it tries to run the "Clear" command with an argument of "Workspace=true".

另外,Jenkins 是如何创建这个环境变量的?Clear Workspace=true在 bash 中运行显然不起作用,因为它试图运行带有“Workspace=true”参数的“Clear”命令。

I could of course make the job parameter name Clear_Workspace, but it's presented in a form to the user, so I'd rather not. Also, the Maven Build Plugin for Jenkins has several parameter names with spaces in them, so it must be possible to access them somehow.

我当然可以将作业参数命名为 Clear_Workspace,但它以一种形式呈现给用户,所以我宁愿不这样做。此外,Jenkins 的 Maven 构建插件有几个参数名称中带有空格,因此必须可以以某种方式访问​​它们。

采纳答案by Stephen Connolly

You can simulate this bit of fun with the envcommand

您可以使用以下env命令模拟这种乐趣

env Clear\ Workspace=true bash

That will give you a shell with the environment variable set.

这将为您提供一个带有环境变量集的外壳。

A hacky way to get the environment variable value back out is:

获取环境变量值的一种hacky方法是:

declare -p Clear\ Workspace | sed -e "s/^declare -x Clear Workspace=\"//;s/\"$//" 

Other than that you'd need to use either a native code program or a scripting language to pull it out, e.g.

除此之外,您需要使用本机代码程序或脚本语言将其拉出,例如

ruby -e "puts ENV['Clear Workspace']"

Which is much less hacky... also if you don't have ruby

哪个不那么hacky...如果你没有红宝石

perl -e 'print "$ENV{\"Clear Workspace\"}\n";'

also

python -c 'import os; print os.environ["Clear Workspace"]'

And here is a native code version:

这是一个本机代码版本:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char **argv, char **envp) 
{
  char **env;
  char *target;
  int len;
  if (argc != 2) 
  {
    printf("Syntax: %s name\n", argv[0]);
    return 2;
  }
  len = strlen(argv[1]);
  target = calloc(len+2,sizeof(char));
  strncpy(target,argv[1],len+2);
  target[len++] = '=';
  target[len] = '0';
  for (env = envp; *env != 0; env++) 
  {
    char *thisEnv = *env;
    if (strncmp(thisEnv,target,len)==0)
    {
      printf("%s\n",thisEnv+len);
      return 0;
    }
  }
  return 1;
}

回答by glenn Hymanman

bash is not the only language that can manipulate the environment:

bash 不是唯一可以操纵环境的语言:

$ perl -e '$ENV{"Clear Workspace"}="true"; system "env"' | grep Clear
Clear Workspace=true

If you're in a shell, you can always parse the output of env(untested)

如果您在 shell 中,您始终可以解析env(未经测试)的输出

value=$(env | while IFS="=" read -r var value; do
                  if [[ $var = "Clear Workspace" ]]; then
                      echo "$value"
                      break
                  fi
              done )

回答by coffeebreaks

Java supports passing environment variables with spaces in names to processes. Here's an example that proves it:

Java 支持将名称中带有空格的环境变量传递给进程。这是一个证明这一点的例子:

Given /tmp/test

给定 /tmp/test

#!/bin/sh
env > /tmp/test.out

and Test.java

和 Test.java

import java.util.*;
import java.io.*;

public class Test {
    public static void main(String[] args) throws Exception     {
        ProcessBuilder pb = new ProcessBuilder("/tmp/test");
        Map<String, String> env = pb.environment();
        env.put("a b", "true");
        pb.directory(new File("/tmp"));
        Process p = pb.start();
    }
}

run

> javac Test.java
> java Test
> grep "a b" /tmp/test.out 
a b=true

Jenkins uses the same functionality to start processes.

Jenkins 使用相同的功能来启动进程

For you to access those from a pure shell, without using python, ruby, etc however, I am not sure. I haven't been able to achieve it yet.

对于您从纯 shell 访问这些内容,而不使用 python、ruby 等,我不确定。我还没有能够实现它。

You may wish to convert those to variable without spaces as those have better portability guarantee.

您可能希望将它们转换为没有空格的变量,因为它们具有更好的可移植性保证。

回答by Robin Philip

The Following command will return the value of the environment variable " Clear Workspace":

以下命令将返回环境变量“ Clear Workspace”的值:

set | grep "Clear Workspace" | awk -F'=' '{print $NF}'

You can assign to another variable without space and use for your purpose :

您可以分配给另一个没有空格的变量并用于您的目的:

export Clear_Workspace=\`set | grep "Clear Workspace" | awk -F'=' '{print $NF}'\`

Give a try.

试一下。

回答by devnull

Jenkins is probably creating somethingother than an environment variable.

詹金斯可能正在创建环境变量以外的东西

You cannot have spaces in environment variables. Quoting http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html:

环境变量中不能有空格。引用http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html

Environment variable names used by the utilities in the Shell and Utilities volume of IEEE Std 1003.1-2001 consist solely of uppercase letters, digits, and the '_' (underscore) from the characters defined in Portable Character Set and do not begin with a digit.

IEEE Std 1003.1-2001 的 Shell 和 Utilities 卷中的实用程序使用的环境变量名称仅由大写字母、数字和可移植字符集中定义的字符中的“_”(下划线)组成,并且不以数字开头.