【问题标题】:bash - escape variable SSH command without altering itbash - 转义变量 SSH 命令而不改变它
【发布时间】:2019-02-07 11:44:32
【问题描述】:

我正在使用文件内容作为参数的 bash 脚本中运行命令。这里是一个简化的例子:

USER=$(<$fileA)
PASSWORD=$(<$fileB)
wget -u $USER -p $PASSWORD

但是,用户可以将文件的内容设置为任何值。我认为我需要逃避这一点,但我不知道该怎么做,尤其是在 $PASSWORD 不会被改变的情况下。否则密码显然不起作用。

谢谢

【问题讨论】:

  • 你不应该使用变量名USER——它是由shell预先填充的当前用户的用户名,并且改变它可能会混淆任何期望它具有该值的东西。有一堆全大写的变量具有特殊的含义,所以最好为变量使用小写或混合大小写的名称,以避免可能的冲突。
  • 如果您执行该行,则用户名和密码会暴露给碰巧登录到您计算机的任何人(通过 /proc//cmdline, for example, or with even less work through the ps` 命令)。使用 curl,您可以创建不那么不安全的命令行:echo user|cat "$fileA" "$fileB"|paste -sd:|curl -K- http://www.example.com

标签: bash variables command-line escaping


【解决方案1】:

您可能只需要在变量周围添加引号。

wget -u "$USER" -p "$PASSWORD"

如果您碰巧在变量末尾捕获了换行符,您可能希望将其删除:

wget -u "${USER%$'\n'}" -p "${PASSWORD%$'\n'}"

${var} 语法等同于$var,但花括号允许使用 bash 操作变量。通过在结束大括号前添加%$'\n'% 表示删除文本$'\n',这意味着删除尾随换行符(如果有)。

在最坏的情况下,您可能会收到换行符和回车符(如果文件是由 Windows 中的文本编辑器生成的),但您也可以处理它:

wget -u "${USER%%[$'\n'$'\r']*}" -p "${PASSWORD%%[$'\n'$'\r']*}"

这一次,搜索到的文本是 [$'\n'$'\r']*,意思是“第一个换行符 (\n) 或回车符 (\r) 以及后面的所有内容”,%% 运算符表示“删除最长的序列最后”。

【讨论】:

  • 最后一个(用于 DOS/Windows 行结尾)不起作用 - 模式 [$'\n'$'\r'] 仅匹配单个字符(回车符或换行符),而不是它们的序列。它实际上是一个 glob 模式而不是正则表达式,所以你不能只在末尾添加 * 来匹配多个实例。你可以用extglob...
  • 我不认为"${USER%$'\n'}" 会从command substitution $(...) strips trailing newlines 开始做任何事情。
  • @GordonDavisson 感谢您的更正。我编辑了答案。
  • @PesaThe 你是对的,但最终我不知道 OP 是否会使用 $() 来捕获输入,在这种情况下,答案可能会很有趣。另外,它使转换到以下参数替换更容易。
  • @vdavid 也关心[$'\n'$'\r']*。它不会删除尾随的换行符或回车符。它 not 是一个正则表达式,实际上它会删除 anything 直到字符串中出现的第一个 \n\r。试试看:var=$'abc\ndef\n123\n'。正如 Gordon 建议的那样,您可以使用 extglob${var%%+([$'\n\r'])}
猜你喜欢
  • 1970-01-01
  • 2013-05-29
  • 2021-01-28
  • 2017-01-24
  • 2014-09-20
  • 2018-11-22
  • 2020-05-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多