如何将环境变量从字符串传递到bash命令

时间:2020-01-05 02:32:51

标签: bash

我有一个变量CrimeListFragment,它的格式是

$files = Get-ChildItem $srcdir -Filter *.txt | ? {$_.LastWriteTime -ge (Get-Date).Date}
$Job1 = Start-Job -ScriptBlock {
    foreach($file in $files[0..349]) {
    }
}

$Job2 = Start-Job -ScriptBlock {
    foreach($file in $files[350..$files.length]) {
    }
}

Wait-Job $Job1, $Job2
Receive-Job $Job1, $Job2

如何使用此命令在我运行的命令中设置环境变量AAAAAA='BBB=1 CCC=2 DDD=3' BBB(而无需将其永久导出到Shell)?也就是说,我想使用上面的方法执行与以下操作相同的操作:

CCC

...但是,当我尝试时:

DDD

...它尝试将# this works correctly: node is run with AAA, BBB, and CCC in its environment BBB=1 CCC=2 DDD=3 node index.js 作为命令运行,而不是将分配解析为要在# this does not work: AAA=1 is run as a command, so it causes "command not found" $AAA node index.js 的环境中设置的变量。

1 个答案:

答案 0 :(得分:3)

如果可以,请使用其他格式。

有几种更好的选择:

  • 一个数组。

    envvars=( AAA=1 BBB=2 CCC=3 )
    env "${envvars[@]}" node.js index.js
    
  • NUL分隔的流(用于将环境变量保存在文件中的理想格式,例如,这是操作系统用于/proc/self/environ的格式)。

    • 保存到文件:

      printf '%s\0' 'foo=bar' \
                    'baz=qux' \
                    $'evil=$(rm -rf /*)\'$(rm- rf ~)\'\nLD_LIBRARY_PATH=/tmp/evil.so' \
        > envvars
      

      ...或更简单(在Linux上):

      # save all your environment variables (as they existed at process startup)
      cp /proc/self/environ envvars
      
    • 从该文件还原并使用它:

      mapfile -d '' vars <envvars
      env "${vars[@]}" node.js
      

但是无论您做什么,都不要使用eval

还记得我在上面设置的evil环境变量吗?这是一个变量的很好的例子,该变量编写不正确的代码无法正确设置。如果您尝试通过eval运行它,它将删除所有文件。如果您尝试从换行符分隔(而不是NUL分隔符)的文件中读取文件,它将设置另一个LD_LIBRARY_PATH变量,该变量告诉操作系统从不受信任/不受信任的位置加载共享库。但这只是少数情况。还请考虑:

## DO NOT DO THIS
AAA='BBB=1 CCC=2 DDD="value * with * spaces"'
eval $AAA node foo.js

看起来很简单,对吧? eval所做的只是一点都不简单:

  • 首先,在启动eval之前,将扩展您的参数和glob。假设您的当前目录包含名为12的文件:

    'eval' 'BBB=1' 'CCC=2' 'DDD="value' '1' '2' 'with' '1' '2' 'spaces"' 'node' 'foo.js'
    
  • 然后,eval接受传递的所有参数,并将它们全部合并为一个字符串。

    eval "BBB=1 CCC=2 DDD="value 1 2 with 1 2 spaces" node foo.js
    
  • 然后从一开始就解析该字符串

    ...这意味着,如果没有一个名为1的文件(一个完全有效的文件名!),而没有一个名为$(rm -rf ~)的文件,那么您将有一个非常非常 < / em>糟糕的一天。