问题描述
我正在清理我的所有配置文件,以使它们尽可能可读.我一直在寻找在导出~/.bashrc
文件中的路径时使用引号的样式指南:
I'm in the process of cleaning up all my config files in an attempt to make them as readable as possible. I've been looking for a style guide on the use of quotes while exporting paths in, for example, a ~/.bashrc
file:
export PATH="/users/me/path:$PATH"
vs
export PATH=/users/me/path:$PATH
Google 外壳样式指南建议避免使用路径名引号.相比之下,很多流行的点文件存储库(例如Zach Holman的在此)使用引号.在路径中使用引号是否有优势?
The Google shell style guide suggests avoiding quotes for path names. In contrast, a lot of the popular dotfiles repos (such as Zach Holman's here) use quotes. Are there any situations when it is an advantage to use quotes in the path?
推荐答案
tl;博士
为安全起见,请双引号:在所有情况下,它都适用于所有类似POSIX的外壳.
如果要添加基于~
的路径,请选择性地保留~/
不带引号的,以确保扩展~
;例如:export PATH=~/"bin:$PATH"
.
或者,只需在单个双引号字符串内使用$HOME
:export PATH="$HOME/bin:$PATH"
If you want to add a ~
-based path, selectively leave the ~/
unquoted to ensure that ~
is expanded; e.g.: export PATH=~/"bin:$PATH"
.
Alternatively, simply use $HOME
inside a single, double-quoted string:export PATH="$HOME/bin:$PATH"
注意:以下内容适用于 bash
,ksh
和zsh
,但不适用于(大部分)严格符合POSIX的外壳,例如dash
;因此,在定位/bin/sh
时,必须将export
的RHS放在双引号中.
NOTE: The following applies to bash
, ksh
, and zsh
, but NOT to (mostly) strictly POSIX compliant shells such as dash
; thus, when you target /bin/sh
, you MUST double-quote the RHS of export
.
- 双引号是 可选,仅当RHS的 literal 部分(要分配的值)不包含空格或其他外壳元字符时.
- 所引用的变量的值是否包含空格/元字符无关无关紧要-参见下文.
- 同样:使用
export
时,与sh
有关系,因此请始终在其中双引号.
- Double-quotes are optional, ONLY IF the literal part of your RHS (the value to assign) contains neither whitespace nor other shell metacharacters.
- Whether the values of the variables referenced contain whitespace/metacharacters or not does not matter - see below.
- Again: It does matter with
sh
, whenexport
is used, so always double-quote there.
在这种情况下无需双引号就可以逃脱的原因是,像POSIX的shell中的 variable-assignment 语句与 arguments 传递给 commands ,如第2.9.1节:
The reason you can get away without double-quoting in this case is that variable-assignment statements in POSIX-like shells interpret their RHS differently than arguments passed to commands, as described in section 2.9.1 of the POSIX spec:
-
具体地说,即使执行了初始分词 ,它也仅适用于未扩展(原始)RHS(这就是为什么您要做需要用 literals 中的空格/元字符引用),而不是引用其结果.
Specifically, even though initial word-splitting is performed, it is only applied to the unexpanded (raw) RHS (that's why you do need quoting with whitespace/metacharacters in literals), and not to its results.
此仅适用于形式为
的真正赋值语句所有类似于POSIX的外壳中的<name>=<value>
,即,如果变量名称前没有命令名称;请注意,其中包括对命令的前缀赋值,以为其定义临时环境变量,例如foo=$bar cmd ...
.This only applies to genuine assignment statements of the form
<name>=<value>
in all POSIX-like shells, i.e., if there is no command name before the variable name; note that that includes assignments prepended to a command to define ad-hoc environment variables for it, e.g.,foo=$bar cmd ...
.在其他命令上下文中的赋值 应该始终加双引号.
Assignments in the context of other commands should always be double-quoted, to be safe:
-
使用
sh
(在(大多数情况下)严格符合POSIX的外壳程序中,例如dash
)中,将export
的赋值视为常规命令,而foo=$bar
部分被视为内置export
的第一个参数,因此也照常进行处理(也受制于结果的分词).
(POSIX没有指定任何其他涉及(显式)变量分配的命令;declare
,typeset
和local
是非标准的扩展名).
With
sh
(in a (mostly) strictly POSIX-compliant shell such asdash
) an assignment withexport
is treated as a regular command, and thefoo=$bar
part is treated as the 1st argument to theexport
builtin and therefore treated as usual (subject to word-splitting of the result, too).
(POSIX doesn't specify any other commands involving (explicit) variable-assignment;declare
,typeset
, andlocal
are nonstandard extensions).
bash
,ksh
,zsh
与POSIX可以理解的偏差是,也将分配逻辑扩展到export foo=$bar
和typeset/declare/local foo=$bar
.换句话说:bash
,ksh
,zsh
,export/typeset/declare/local
命令中的就像 assignments 一样对待,因此不必严格引用..bash
,ksh
,zsh
, in an understandable deviation from POSIX, extend the assignment logic toexport foo=$bar
andtypeset/declare/local foo=$bar
as well. In other words: inbash
,ksh
,zsh
,export/typeset/declare/local
commands are treated like assignments, so that quoting isn't strictly necessary.- 令人惊讶的是,
dash
,它也选择实现了 non -POSIXlocal
内置,不向其扩展分配逻辑;但是,它与其export
行为一致.
- Perhaps surprisingly,
dash
, which also chose to implement the non-POSIXlocal
builtin, does NOT extend assignment logic to it; it is consistent with itsexport
behavior, however.
传递给
env
的赋值(例如env foo=$bar cmd ...
)也可以作为命令参数进行扩展,因此需要双引号-除zsh
以外.Assignments passed to
env
(e.g.,env foo=$bar cmd ...
) are also subject to expansion as a command argument and therefore need double-quoting - except inzsh
.- 在这方面,
env
与ksh
和bash
中的export
行为不同是由于以下事实:env
是外部实用程序,而export
是内置的 shell .
(对于未加引号的变量引用,zsh
的行为根本上与其他shell的行为不同.)
- That
env
acts differently fromexport
inksh
andbash
in that regard is due to the fact thatenv
is an external utility, whereasexport
is a shell builtin.
(zsh
's behavior fundamentally differs from that of the other shells when it comes to unquoted variable references).
波浪号(
~
)扩展在真正赋值语句中发生:Tilde (
~
) expansion happens as follows in genuine assignment statements:- 除了
~
不需要被引用以外,它通常也仅适用于:- 如果整个 RHS为
~
;例如.:-
foo=~ # same as: foo="$HOME"
- In addition to the
~
needing to be unquoted, as usual, it is also only applied:- If the entire RHS is
~
; e.g.:foo=~ # same as: foo="$HOME"
- 如果
~
以字符串开头或以不带引号的:
- 如果
~
后跟不带引号的/
. - 例如,
foo=~/bin # same as foo="$HOME/bin"
foo=$foo:~/bin # same as foo="$foo:$HOME/bin"
- if
~
starts the string or is preceded by an unquoted:
- if
~
is followed by an unquoted/
. - e.g.,
foo=~/bin # same as foo="$HOME/bin"
foo=$foo:~/bin # same as foo="$foo:$HOME/bin"
示例
此示例说明,在
bash
,ksh
和zsh
中,即使使用export
,您也可以不用双引号而忽略,但是我不这样做推荐.This example demonstrates that in
bash
,ksh
, andzsh
you can get away without double-quoting, even when usingexport
, but I do not recommend it.#!/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'
这篇关于我应该在环境路径名中使用引号吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
- If the entire RHS is
-
- 如果整个 RHS为
- Again: It does matter with
- 同样:使用