【问题标题】:Read env variable with unescaped characters from file on ubuntu with bash使用 bash 从 ubuntu 上的文件中读取具有未转义字符的 env 变量
【发布时间】:2021-04-28 05:06:08
【问题描述】:

如何在 bash 中读取包含空格和可能需要转义的其他字符的环境变量?

我有一个文件 server.env

PUBLIC_KEY=ssh-rsa whatever+whatever+8whatever/whatever+p+whatever user@alans-MacBook-Pro.local

我正在尝试将此文件作为环境变量读入 bash 脚本:

export $(cat server.env | xargs)

我收到一个错误:

-bash: export: `user@alans-MacBook-Pro.local': not a valid identifier

好的,尝试引用 server.env 中的值:

PUBLIC_KEY='ssh-rsa whatever+whatever+8whatever/whatever+p+whatever user@alans-MacBook-Pro.local'
  • 同样的错误

双引号:

PUBLIC_KEY="ssh-rsa whatever+whatever+8whatever/whatever+p+whatever user@alans-MacBook-Pro.local"
  • 还有错误

我在这里错过了什么?

【问题讨论】:

    标签: bash ubuntu environment-variables


    【解决方案1】:

    Bash 提供了带有子字符串删除的参数扩展,这将允许您分离从server.env 文件读取的NAME=value 对,然后将exportNAME=value 对分开。

    您只需要一个简单的读取循环:

    #!/bin/bash
    
    while read -r line; do              ## read each line of server.env
        val="${line#*=}"                ## trim to 1st =, save in val
        export ${line%=$val}="$val"     ## remove =$val leaving name, export val with name
    done < server.env
    
    printf "%s\n" "$PUBLIC_KEY"         ## confirm
    

    使用/输出示例

    $ bash test.sh
    ssh-rsa whatever+whatever+8whatever/whatever+p+whatever user@alans-MacBook-Pro.local
    

    基本的参数扩展是:

    ${var#pattern}      Strip shortest match of pattern from front of $var
    ${var##pattern}     Strip longest match of pattern from front of $var
    ${var%pattern}      Strip shortest match of pattern from back of $var
    ${var%%pattern}     Strip longest match of pattern from back of $var
    

    注意: pattern 可以包含普通的 shell glob,例如 '*''?'

    实际上有几十个有用的参数扩展可以用于字符串操作。只需检查 "Parameter Expansion" 标题下的 man bash

    【讨论】:

    • 次要问题,如果val 包含元字符,%=$val 可能会失败。运行line='a=b[cd]e' val=${line#*=}; echo ${line%=$val},你会看到。它应该是%="$val"
    【解决方案2】:

    部分答案(不是export,因此该变量在 bash 的后续运行中不可用,仅在当前会话中可用):

    source server.env
    

    【讨论】:

    • 由于该文件不包含export,仅包含变量,您仍然需要循环遍历,如上所述。
    • 如果server.env 是有赋值的文件,并且赋值仍然没有被引用,它们将继续是语法错误(或者更险恶的东西,即运行你不打算运行的命令)。
    【解决方案3】:

    这里的问题是字段拆分仍然发生在空白处。

    你应该这样做:

    export "$(cat server.env)"
    

    (即添加双引号)。

    对于多个变量,循环遍历行:

    while read -r line
    do
        export "$line"
    done < server.env
    

    如果这是在一个名为 export.sh 的脚本中,那么您还需要 source 它以在当前进程中设置变量:

    source export.sh
    

    【讨论】:

    • 不幸的是,这不起作用,它将 SSH_KEY 设置为 ssh-rsa 并将其余部分分配给文件中的下一个 env 变量,搞砸了
    • 文件是否包含多个变量,应分别导出?
    • 是的,很抱歉没有指定这个
    • 好吧,不要一口气做,遍历行。
    猜你喜欢
    • 1970-01-01
    • 2020-03-18
    • 1970-01-01
    • 2019-07-12
    • 2020-06-13
    • 2020-09-02
    • 2020-08-24
    • 1970-01-01
    • 2013-03-07
    相关资源
    最近更新 更多