【问题标题】:How to use an environment variable inside a quoted string in Bash如何在 Bash 中的带引号的字符串中使用环境变量
【发布时间】:2010-10-24 20:12:21
【问题描述】:

我在 bash 脚本中尝试了以下各种形式:

#!/bin/bash
svn diff $@ --diff-cmd /usr/bin/diff -x "-y -w -p -W $COLUMNS"

但我无法获得正确扩展 COLUMNS 环境变量的语法。

我尝试了以下各种形式:

svn diff $@ --diff-cmd /usr/bin/diff -x '-y -w -p -W $COLUMNS'

svn diff $@ --diff-cmd /usr/bin/diff -x '-y -w -p -W ${COLUMNS}'

eval svn diff $@ --diff-cmd /usr/bin/diff -x "-y -w -p -W $COLUMNS"

建议?

【问题讨论】:

  • 那么这些例子在你的案例中产生了什么?你希望他们生产什么?
  • 脚本外的命令有效吗?
  • 你试过svn diff $@ --diff-cmd /usr/bin/diff -x "-y -w -p -W ""$COLUMNS"
  • 顺便说一句,使用$@ unquoted 使其与$* 完全相同——也就是说,它将"foo bar" 分成两个单独的参数,foobar。如果您想保留给您的原始参数列表,您需要"$@"

标签: bash quotes environment


【解决方案1】:

对于通过 Google 来这里寻找标题中提出的一般问题的答案的任何人(就像我一样),只是一个简短的说明/摘要。以下任何一项都可以访问引号内的 shell 变量:

echo "$VARIABLE"
echo "${VARIABLE}"

使用单引号是主要问题。根据Bash Reference Manual

将字符括在单引号 (') 中会保留引号内每个字符的字面值。单引号之间不能出现单引号,即使前面有反斜杠。 [...] 将字符括在双引号 (") 中会保留引号内所有字符的文字值,$`\ 以及启用历史扩展时的! 除外。字符 $ 和 ` 在双引号内保留其特殊含义(请参阅 Shell 扩展)。反斜杠仅在后跟以下字符之一时才保留其特殊含义:$`"\ 或换行符。在双引号内,删除后面跟有这些字符之一的反斜杠。没有特殊含义的字符前面的反斜杠保持不变。双引号可以用反斜杠在双引号中引用。如果启用,将执行历史扩展,除非出现在双引号中的 ! 使用反斜杠转义。 ! 前面的反斜杠不会被删除。 特殊参数*@ 在双引号中时具有特殊含义(参见Shell 参数扩展)。

在问题中提出的特定情况下,$COLUMNS 是一个具有非标准属性的特殊变量(参见上面 lhunath 的回答)。

【讨论】:

  • 在单引号的情况下,也许这种解决方法有帮助:'before'"$variable"'after'(如本答案所述:stackoverflow.com/a/13802438/2254346
  • 很好的答案!我在单引号中引用我的 env 变量时遇到了同样的问题。一旦我将单引号更改为双引号,我的 env 变量就会按预期扩展。
【解决方案2】:

注意COLUMNS 是:

  1. 不是环境变量。它是一个普通的bash参数,由bash自己设置。
  2. 收到SIGWINCH 信号后自动设置。

第二点通常意味着您的 COLUMNS 变量只会在您的 interactive shell 中设置,而不是 在 bash 脚本中。

如果您的脚本的stdin 已连接到您的终端,您可以通过询问终端来手动查找终端的宽度:

tput cols

并在您的 SVN 命令中使用它:

svn diff "$@" --diff-cmd /usr/bin/diff -x "-y -w -p -W $(tput cols)"

(注意:您应该引用 "$@" 并远离eval ;-))

【讨论】:

  • 感谢您的信息;知道发生了什么会给问题带来一种宣泄的感觉。
【解决方案3】:

如果不确定,您可能会在终端上使用“cols”请求,而忘记 COLUMNS:

COLS=$(tput cols)

【讨论】:

  • 无论出于何种原因,这是我能够在此页面上工作的唯一解决方案(截至美国东部时间 5 月 11 日 10:38)。谢谢
【解决方案4】:

你做对了,所以我猜还有其他问题(不是导出 COLUMNS ?)。

调试这些情况的一个技巧是创建一个专门的命令(编程语言人员的闭包)。创建一个名为 diff-columns 的 shell 脚本:

exec /usr/bin/diff -x -y -w -p -W "$COLUMNS" "$@"

只使用

svn diff "$@" --diff-cmd  diff-columns

通过这种方式,您的代码更易于阅读且模块化程度更高(自上而下的方法),并且您可以单独彻底地测试差异列代码(自下而上的方法)。

【讨论】:

  • 命令行在进程分叉之前被解析,所以不导出COLUMNS不可能是问题。
  • 他说他的代码是 bash 脚本的一部分,因此这可能是问题所在。
【解决方案5】:

以下脚本适用于$COLUMNS 的多个值。我想知道您是否没有在此呼叫之前设置COLUMNS

#!/bin/bash
COLUMNS=30
svn diff $@ --diff-cmd /usr/bin/diff -x "-y -w -p -W $COLUMNS"

您能否在脚本中回显$COLUMNS 以查看其设置是否正确?

【讨论】:

  • 嘘,嘶嘶声:未引用 $@ -- 将单个参数 "two words" 拆分为两个单独的参数,twowords。应该是 "$@" 以完全按照给定的方式传递参数列表。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-29
  • 1970-01-01
  • 2018-05-06
  • 2015-03-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多