#!/usr/bin/env bash
# or ksh or zsh - but NOT /bin/sh!
# Create env. variable with whitespace and other shell metacharacters
export FOO="b:c &|<> d"
# Extend the value - the double quotes here are optional, but ONLY
# because the literal part, 'a:`, contains no whitespace or other shell metacharacters.
# To be safe, DO double-quote the RHS.
export FOO=a:$foo # OK - $FOO now contains 'a:b:c &|<> d'
4条答案
按热度按时间p4rjhz4m1#
向@gniourf_gniourf和@chepner致敬,感谢他们的帮助。
tl;dr
为安全起见,请使用双引号:它可以在所有情况下工作,可以跨所有类似POSIX的shell。
如果要添加一个基于
~
的路径,* 选择性地 * 保留~/
* 不加引号 * 以确保~
被扩展;例如:export PATH=~/"bin:$PATH"
。请参阅以下有关变量赋值中~
扩展的规则。或者,只需在单个双引号字符串中使用
$HOME
:export PATH="$HOME/bin:$PATH"
注意:以下内容适用于**
bash
、ksh
和zsh
**,但不适用于(大多数情况下)严格符合POSIX的shell,如dash
;因此,当您以/bin/sh
为目标时,您必须将export
的RHS用双引号引起来。[1]export
时,它 * 确实 * 与sh
有关,所以总是在那里使用双引号。在这种情况下,您可以不使用双引号,原因是类POSIX shell中的variable-assignment 语句对它们的RHS * 的解释 * 与传递给 * 命令*的 * 参数 * 不同,如POSIX规范的第2.9.1节所述:
<name>=<value>
在 * 所有 * 类POSIX shell **中,即,如果在变量名之前 * 没有命令名 *;注意,这包括对命令的赋值 * 前置 *,以为其定义特定环境变量,例如X1 M16 N1 X。*其他命令 * 上下文中的赋值 * 应始终用双引号引起来,以确保安全:
sh
(在(大多数)严格遵循POSIX的shell中,如dash
),带有export
的赋值被视为 * 常规命令 *,而foo=$bar
部分被视为export
内置的 * 第一个参数 *,因此被视为正常(也受 result 的分词限制)。(POSIX没有指定任何其他涉及(显式)变量赋值的命令;
declare
、typeset
和local
是非标准 * 扩展 *)。bash
,ksh
,zsh
,与POSIX有一个可以理解的偏差,将赋值逻辑扩展到export foo=$bar
和typeset/declare/local foo=$bar
。换句话说:*在bash
、ksh
、zsh
、export/typeset/declare/local
中,命令被视为 * 赋值 ,因此不一定需要加引号。local
builtin[2]的dash
并没有向其扩展赋值逻辑;然而,这与其export
行为一致。env
的赋值语句(例如env foo=$bar cmd ...
)也会作为命令参数进行扩展,因此需要双引号-zsh
除外。env
与ksh
和bash
中的export
的行为不同,这是因为env
是一个 * 外部实用程序 *,而export
是一个 *shell内置 *。(当涉及到未引用的变量引用时,
zsh
的行为 * 从根本上 * 与其他shell不同)。*颚化符(
~
)扩展在 * 真正 * 赋值语句中发生如下:~
需要像往常一样被 unquoted 之外,它还仅适用于:~
;例如:~
开头或前面有 unquoted:
~
后面跟着 * 不带引号的 */
,则为。x1米55英寸1x
foo=$foo:~/bin # same as foo="$foo:$HOME/bin"
个示例
此示例说明在
bash
、ksh
和zsh
中,即使使用export
,也可以 * 不 * 使用双引号,但 * 我不建议 * 使用双引号。[1]正如@gniourf_gniourf所指出的:使用
export
来 * 修改 *PATH
的值是可选的,因为一旦变量被标记为导出,就可以使用常规赋值(PATH=...
)来更改其值。也就是说,您仍然可以 * 选择 * 使用
export
,以便明确地导出正在修改的变量。[2]@gniourf_gniourf声明POSIX标准的未来版本可能会引入
local
内置。rbpvctlc2#
当我在docker .env文件中设置环境路径名时,我使用了上面的这些答案,并得到了一些信息。我把这些信息放在这里,供其他寻找如何为docker定义环境变量的人参考。
Docker compose从.env文件中读取环境变量,该文件位于运行Docker compose的同一文件夹中,如下所述https://docs.docker.com/compose/env-file.
但是,docker compose需要定义不带引号的环境变量,而不是用引号将值括起来,除非引号是值的一部分。
引号没有特殊处理(即,它们将是瓦尔的一部分,您已收到警告;)
我试图设置绝对路径的
NODE_PATH=./src
,以便在docker部署的react应用程序中工作,但我把它写成了NODE_PATH="./src"
。b4qexyjb3#
test 123
是UNIX上的有效路径名。请尝试它将返回:
甚至
它将返回
它回答了你的问题吗?
老实说,我不会遵循这样的第四方 * 风格指南 *。虽然我很惊讶,甚至谷歌广告这样错误的建议。
我会跟着:
(to小心延长)
ezykj2lf4#
与路径无关,但与https://stackoverflow.com/a/48411223相同,我在docker compose的上下文中也得到了位。
我的.env文件中有一个标记env变量,类似于
并且得到了无效登录凭据错误,因为容器中的
MY_TOKEN
值是abc&123
。实际的令牌要长得多,所以很难发现问题。成功了。