【问题标题】:Should I escape variables in bash script or not我是否应该在 bash 脚本中转义变量
【发布时间】:2020-01-02 19:00:35
【问题描述】:

我需要快速澄清一下:

这个是否相等

CASSANDRA_IP=00.000.00.00

CASSANDRA_USER=用户

CASSANDRA_PASSWORD=密码

#!/bin/bash

cqlsh "${CASSANDRA_IP}" -u "${CASSANDRA_USER}" -p "${CASSANDRA_PASSWORD}" -f command.cql

这个?

cqlsh 00.000.00.00 -u user -p 'password'

或者我必须在命令中分隔动态变量吗?

#!/bin/bash

cqlsh "${CASSANDRA_IP}" -u \'"${CASSANDRA_USER}"\' -p \'"${CASSANDRA_PASSWORD}"\' command.cql

【问题讨论】:

  • 第三个不正确,因为它在您传递的值中添加了文字单引号。第一个完全按照预期使用引用。第二个是等效的,因为 password 周围的单引号被视为 shell 语法的一部分。 (password'password' 产生相同的参数,因此使用引号是合法的,但没有必要。)
  • 前两个是一样的。一般规则是,如果要进行分词,则不应引用变量。如果您不希望发生分词,则应引用该变量。如果您不确定是否要进行分词,那么您几乎可以肯定不这样做,您应该引用该变量。
  • 为了突出 chep 所说的内容,请记住,当您以这种方式转义单引号时,您是在使它们 成为参数的一部分,而不是 参数的容器。每个人都告诉你引用你的变量的原因是为了保持参数的包含。转义任何东西都会删除(或至少改变)其原始功能。 cqlshrequire 一些任意字符(如 0x27)被添加到输入数据中,这将是非常令人惊讶的。有关引号转义的示例,请参阅 this

标签: bash shell command-line terminal


【解决方案1】:

命令行上传递的所有引号都由 shell 处理(在本例中为 bash)。在所有变量都展开后,生成的字符串作为参数传递给执行的程序,其中参数由命令行上的(不带引号的)空格分隔。

因此在你的例子中

cqlsh "${CASSANDRA_IP}" -u "${CASSANDRA_USER}" -p "${CASSANDRA_PASSWORD}" -f command.cql

等价于

cqlsh 00.000.00.00 -u user -p 'password' -f command.cql

相当于

cqlsh 00.000.00.00 -u user -p password -f command.cql

即shell 将调用程序 cqlsh 并传递 7 个参数

  1. 00.000.00.00
  2. -u
  3. user
  4. -p
  5. password
  6. -f
  7. command.cql

尽管如此,正确引用非常重要,因为 shell 如何处理变量扩展,最重要的是通过此规则(这适用于 bash,但也应该适用于大多数其他 shell):

  • 单引号 ' 中的字符串不受任何变量扩展的影响,并按字面意思传递
  • 双引号中的字符串"会进行变量扩展:扩展的最终结果将作为一个字符串传递给程序
  • 未加引号的变量将在命令行上展开,然后执行生成的命令行

大多数情况下,将变量括在双引号中并将它们不带引号传递的最终结果是相同的,但根据变量的值可能会有所不同,尤其是在包含空格字符时:在这种情况下,结果将是作为 多个 字符串而不是单个字符串传递给程序。例如

CASSANDRA_PASSWORD="my password" # password contains a space

cqlsh $CASSANDRA_IP -u $CASSANDRA_USER -p $CASSANDRA_PASSWORD -f command.cql

将被评估为

cqlsh 00.000.00.00 -u user -p my password -f command.cql

cqlsh 将使用 8 参数而不是预期的 7 来调用:

  1. 00.000.00.00
  2. -u
  3. user
  4. -p
  5. my
  6. password
  7. -f
  8. command.cql

cqlsh "$CASSANDRA_IP" -u "$CASSANDRA_USER" -p "$CASSANDRA_PASSWORD" -f command.cql

会正确评估为

cqlsh 00.000.00.00 -u user -p "my password" -f command.cql

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-01
    • 2019-09-17
    • 2012-05-18
    • 1970-01-01
    • 2021-11-04
    • 1970-01-01
    • 2015-08-17
    • 2017-06-04
    相关资源
    最近更新 更多