bash 在unix中将多行,带引号的字符串作为单个命令行参数传递?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12576982/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 03:22:28  来源:igfitidea点击:

Pass a Multiline,Quoted string as a single command line argument in unix?

linuxstringbashunix

提问by Cookies

I just need to pass any HTML content as a command line argument which includes characters like ', " , ` and what not? How can I pass this as a single argument in unix?

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

回答by rici

If you were typing at the command line, you could use the following hack:

如果您在命令行中输入,则可以使用以下技巧:

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

The last thing is control-D (end of file)

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

To put that into a bash script, you can use a Here document:

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

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

That will work as long as the text is not exactly the characters EOF (and if it is, you just have to change EOF in both places to something else).

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

But I don't think either of those are what you want to do. I think you are trying to invoke a program from another program (in Lua). Unfortunately, Lua out-of-the-box does not provide any function which can do that. It only provides os.execute, which uses the shell (/bin/sh, not bash) to interpret the command line.

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

There was a nice implementation for Lua of spawnwritten by Mark Edgar, but I don't know if it is still maintained. Failing that, you can still use the second hack:

spawnMark Edgar 写的Lua 有一个很好的实现,但我不知道它是否还在维护。否则,您仍然可以使用第二个 hack:

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)        

回答by MrE

I was looking for an answer to the question but I don't really see it here, so here is the solution I ended up with (not I'm not passing HTML or things like that, but similar)

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

for example the psqltools takes commands that can be multi lines, but they need to be passed in a double quoted string.

例如,这些psql工具采用可以是多行的命令,但它们需要以双引号字符串形式传递。

I started with other answers that recommended the following:

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

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

but that doesn't work because the command is now missing the quotes, and using "$CMD" doesn't remove the newlines so it is passed as multiline still...

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

however

然而

echo $CMDwill print the command in a single line

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

so in the end using:

所以最后使用:

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"

actually wraps the line in double quotes, into a single line command.

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

I hope this is useful to others.

我希望这对其他人有用。

回答by fkl

If i understand your requirement correctly, you can pass any thing in double quotes from command line i.e. "". It would be treated as a single argument and received in the program as a string, which can be parsed according to needs.

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

Here is a c program

这是交流程序

#include <stdio.h>

int main(int c, char *argv[])
{
        printf("argument is %s\n", argv[1]);
        return 0;
}

On console, i compiled and ran it with

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

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

Output is

输出是

argument is

论点是

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

For special characters such as "" (double quotes), backslash \ etc. inside the argument, just prefix those with an extra escape sequence \

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

回答by Mark Lakata

This worked for me.

这对我有用。

Here's the multiline text in a file (setup.json), with internal double quotes for example:

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

{
   "fieldA": "foo"
}

and here's how to send it as a single argument:

以下是将其作为单个参数发送的方法:

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

Use the c program (other answer) from @fayyazkl to test it.

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