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

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


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)

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

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

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).

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.

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

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


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)

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

I started with other answers that recommended the following:

CMD=$(cat << EOMCREATE 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...

however

echo $CMD will print the command in a single line

so in the end using:

CMD=$(echo $(cat << EOMCREATE 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.


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 \