Bash:源文件执行用引号引起来的代码

Bash: sourcing file executes code enclosed in quotes

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

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

最重要的是。 下面是选项识别和下一个输出之间的代码(工作正常):

...
if [ "" = "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 [ "" = "status" ] ; then #1

脚本应该如何工作:

The scripts when asked creates a file containing some variables it takes from files around the project. When user asks those variables are used to fill those same files. This means that variables content and files content must be the exact same all the time, i thought that copying in and copying out would have done exactly that. I was wrong

考虑因素:

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

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

编辑:

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

SHELTER='stuff'
PACKAGE='otherstuff'

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

第2127行是一条错误信息,只是因为它是从其他文件复制过来的。我真的不在乎我从中获取信息的文件中有什么,我只需要原样的纯文本和 return 原样。

也是的,.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 由其他脚本代码自动生成
  • .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='...' 赋值的一部分

如果 objective 要在 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

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