【问题标题】:Bash: sourcing file executes code enclosed in quotesBash:源文件执行用引号括起来的代码
【发布时间】:2021-10-07 21:35:44
【问题描述】:

我有一个 bash 脚本,它接受一些选项的输入并做出相应的行为。 其中一个选项读取配置文件中的变量(如果存在)。尽管使用该选项并且只有该选项它也会打印出来

.shelter: line 2127: /usr/bin/install: Argument list too long

在一切之上。 下面是选项识别和下一个输出之间的代码(效果很好):

...
if [ "$1" = "status" ] ; then #1
if [[ -f .shelter ]] ; then  #2
    source .shelter
    if [ "$SHELTER" = "git" ] ; then #3
        echo "Shelter:  git"
    else 
        if [ "$SHELTER" = "bunker" ] ; then #4
            echo "Shelter: bunker"
        else 
            echo "Shelter: not set"
        fi #-4
    fi #-3
   
...

错误会在Shelter: 之前打印出来,但它不会与任何其他选项一起出现,因此它必须低于if [ "$1" = "status" ] ; then #1

脚本应该如何工作:

脚本在被询问时会创建一个文件,其中包含它从项目周围的文件中获取的一些变量。当用户询问这些变量用于填充那些相同的文件时。这意味着变量内容和文件内容必须始终完全相同,我认为复制进来和复制出去就可以做到这一点。我错了

注意事项:

第 2127 行是 "deprecated": "Moved to 'npm install @sideway/address'",所以我认为它可能是带引号的东西,但在打印错误的地方甚至没有使用该部分。 我的另一个选择是测试 .shelter 文件,但我不明白为什么它需要使用文件的内容来检查它的存在。 有没有办法强制脚本按原样处理变量的每个字符(比如一些自动反斜杠或一些“这些都是字符”核选项)?或者也许有其他方法来检查文件是否存在?或者甚至是我错过了什么?

如果您需要更多信息或有与该问题无关的建议,请在 cmets 中告诉我。

编辑:

我认为我需要更具体。文件.shelter 里面没有代码。看起来像这样

SHELTER='stuff'
PACKAGE='otherstuff'

它包含的内容是从 json 文件中复制出来的,并在 .shelter 文件中作为字符串输出。

第 2127 行是一条错误消息,但这只是因为它是从另一个文件中复制的。我真的不在乎我从中获取信息的文件中的内容,我只需要按原样返回纯文本。

也可以,.shelter 文件是自动生成的,但是自动生成不能输出文件中的任何错误。

给我带来问题的那一行只是一段 json 字符串,它可能说明如果包被弃用,npm 必须输出什么。

EDIT-2:

.shelter 的 2120 到 2140 行:

      "url": "https://github.com/sponsors/sindresorhus"
  }
},
"node_modules/@hapi/address": {
  "version": "2.1.4",
  "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz",
  "integrity": "sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ==",
  "deprecated": "Moved to 'npm install @sideway/address'"
},
"node_modules/@hapi/bourne": {
  "version": "1.3.2",
  "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-1.3.2.tgz",
  "integrity": "sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA==",
  "deprecated": "This version has been deprecated and is no longer supported or maintained"
},
"node_modules/@hapi/hoek": {
  "version": "8.5.1",
  "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.5.1.tgz",
  "integrity": "sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow==",
  "deprecated": "This version has been deprecated and is no longer supported or maintained"
},

【问题讨论】:

  • 错误在您的.shelter 代码中,而不是在这里。
  • 处理source .shelter时发现line 2127有错误;第一个问题是:what's at line 2127 of .shelter? 问题是如果正在获取其他文件或调用函数,则此行号(2127)不一定来自.shelter;错误消息还提到/usr/bin/install ...你能找到执行install的任何代码(在.shelter中,在.shelter来源的其他文件中,可能在source期间调用的函数中)吗?您可能还想在source .shelter 之前考虑set -xv 以获取更多详细信息(注意;会产生大量输出)
  • @markp-fuso 感谢set -xv 的建议,这真的很有用。我还用新信息编辑了问题
  • @FabioR。如果.shelter 没有代码并且只包含文本,那么您认为source .shelter 实际上是做什么的?这些分配代码。
  • 如果package.json 在某处包含单引号,echo "PACKAGE='$(cat package.json)'" >> .shelter 将产生语法错误并可能产生不可预知的副作用。

标签: string bash config


【解决方案1】:

在 cmets 中进行扩展的来回后,我们有:

  • .shelter 由其他脚本代码自动生成
  • .shelter 包含变量赋值列表
  • 用于填充.shelter 的命令之一是echo "PACKAGE='$(cat package.json)'",但是...
  • 由于外部引号,cat 被执行,结果被转储到 .shelter 导致以下内容被放置在 '.shelter` ...
  • PACKAGE='".... bunch of json data ... "Moved to 'npm install @sideway/address'"...' 内部单引号导致解析过程中出现问题,从而导致...
  • npm install @sidway/address'"...' 被作为命令处理,而不是 PACKAGE='...' 分配的一部分

如果目标是在source .shelter 期间填充PACKAGE 变量,那么:

echo "PACKAGE='$(cat package.json)'" >> .shelter     # outer double quotes causes the 'cat' command to be executed and the results dumped into .shelter

应替换为:

echo 'PACKAGE=$(cat package.json)' >> .shelter       # single quotes means no call to 'cat' and the entire line is written as a string into .shelter

现在当source .shelter 运行时,会发生以下情况:

PACKAGE=$(cat package.json)                          # at this point 'cat' is called and the results are stored in the 'PACKAGE' variable

当然,由于嵌入的单引号/双引号,从这里 OP 的脚本可能无法解析 PACKAGE 的内容,但这是下一个问答的问题(例如,OP 的脚本可能受益于使用 json-感知工具(例如,jq)将package.json 数据解析为可用变量)。

【讨论】:

  • 如果source .shelter 不再访问package.json,您可以使用printf 'PACKAGE=%q\n' "$(cat package.json)" >> .shelter 安全地嵌入整个文件。
猜你喜欢
  • 1970-01-01
  • 2010-09-12
  • 2011-02-14
  • 2021-10-08
  • 2010-12-09
  • 1970-01-01
  • 2011-08-27
  • 2010-12-13
相关资源
最近更新 更多