【问题标题】:Pass a Multiline,Quoted string as a single command line argument in unix?将多行,带引号的字符串作为unix中的单个命令行参数传递?
【发布时间】:2012-09-16 14:50:16
【问题描述】:

我只需要将任何 HTML 内容作为命令行参数传递,其中包括诸如 '、" 、` 之类的字符等等?如何在 unix 中将其作为单个参数传递?

【问题讨论】:

    标签: linux string bash unix


    【解决方案1】:

    如果我正确理解您的要求,您可以在命令行中用双引号传递任何内容,即“”。它将被视为单个参数,并在程序中作为字符串接收,可以根据需要进行解析。

    这是一个c程序

    #include <stdio.h>
    
    int main(int c, char *argv[])
    {
            printf("argument is %s\n", argv[1]);
            return 0;
    }
    

    在控制台上,我编译并运行它

    $ gcc args.c
    $ ./a.out "<img src=\"image.png\" onload='alert(/loaded/)' />"
    

    输出是

    参数是

     <img src="image.png" onload='alert(/loaded/)' />
    

    对于参数中的“”(双引号)、反斜杠\等特殊字符,只需在前面加上一个额外的转义序列\

    【讨论】:

    • 好吧!如果我的论点类似于 怎么办?这还能用吗?
    • 会的。我刚刚通过一个程序进行了验证。将其发布在解决方案中。完成
    • 有许多字符出现在双引号字符串中时需要转义,包括双引号本身。请注意,在image.png 周围打印出的字符串不带引号。如果您将其作为 ./a.out "&lt;img src=\"image.png\" onload='alert(/loaded/)' /&gt;" 运行,则双引号将包含在参数中。
    • 你必须为程序指定一种解释字符的方法。这里没有特殊的编码。所以我认为没有任何办法。为什么需要一个?
    • 另请注意,换行符的处理方式因外壳而异。在 csh 和 csh 变体中,换行符是特殊字符,必须转义,而在 bourne shell 中,换行符前面的 `` 是可选的。
    【解决方案2】:

    如果您在命令行输入,您可以使用以下 hack:

    some_program -some_option some_argument "$(cat)"
    any text you like with ` or " or $ or < or whatever
    ^D
    

    最后一件事是control-D(文件结束)

    要将其放入 bash 脚本,您可以使用 Here 文档:

    some_program -some_option some_argument "$(cat <<'EOF'
    any text you like with ` or " or $ or < or whatever
    EOF
    )"
    

    只要文本不完全是字符 EOF(如果是,您只需将两个地方的 EOF 都更改为其他内容),这将起作用。

    但我认为这两种方法都不是你想做的。我认为您正试图从另一个程序(在 Lua 中)调用一个程序。不幸的是,开箱即用的 Lua 不提供任何可以做到这一点的功能。它只提供os.execute,它使用shell(/bin/sh,不是bash)来解释命令行。

    Mark Edgar 为 spawn 编写了一个很好的 Lua 实现,但我不知道它是否仍在维护。如果做不到这一点,你仍然可以使用第二个技巧:

    require("os")
    
    function call_with_arg(prog, rawtext)
      return os.execute(prog.." \"$(cat <<'EOF'\n"..rawtext.."\nEOF\n)\"")
    end
    local html =
      [=[<html><body><img src="image.png" onload='alert("loaded")'/></body></html>]=]
    
    call_with_arg("echo >somefile.txt", html)        
    

    【讨论】:

      【解决方案3】:

      我一直在寻找问题的答案,但在这里我并没有真正看到,所以这是我最终得到的解决方案 (不是我没有传递 HTML 或类似的东西,而是类似的)

      例如,psql 工具接受可以是多行的命令,但它们需要在双引号字符串中传递。

      我从其他推荐以下内容的答案开始:

      CMD=$(cat << EOM
      CREATE TABLE mytable
              (
                id bigint NOT NULL,
                sid bigint NOT NULL,
                obs timestamp without time zone NOT NULL,
                rcv timestamp without time zone NOT NULL,
                uid bigint NOT NULL,
                CONSTRAINT pkey PRIMARY KEY (id)
              )
      EOM
      )
      
      sudo -u postgres psql db -c $CMD
      

      但这不起作用,因为该命令现在缺少引号,并且使用 "$CMD" 不会删除换行符,因此它仍然作为多行传递...

      然而

      echo $CMD 将在一行中打印命令

      所以最后使用:

      CMD=$(echo $(cat << EOM
      CREATE TABLE mytable
                  (
                    id bigint NOT NULL,
                    sid bigint NOT NULL,
                    obs timestamp without time zone NOT NULL,
                    rcv timestamp without time zone NOT NULL,
                    uid bigint NOT NULL,
                    CONSTRAINT pkey PRIMARY KEY (id)
                  )
      EOM
      ))
      
      sudo -u postgres psql db -c "$CMD"
      

      实际上将行用双引号括起来,变成一个单行命令。

      我希望这对其他人有用。

      【讨论】:

        【解决方案4】:

        这对我有用。

        这是文件中的多行文本 (setup.json),例如带有内部双引号:

        {
           "fieldA": "foo"
        }
        

        以下是如何将其作为单个参数发送:

        setup=$(cat setup.json)
        ./my_util "$setup"
        

        使用来自@fayyazkl 的 c 程序(其他答案)来测试它。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-08-10
          • 1970-01-01
          • 2019-11-20
          • 1970-01-01
          • 1970-01-01
          • 2015-04-11
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多