Sidd Singal
Sidd Singal

Reputation: 656

Executing Linux commands with double quotes

So I am trying to figure out this weird behavior.

$ hello hello           
-ksh: hello: not found [No such file or directory]
$ "hello hello"
-ksh: hello hello: not found [No such file or directory]
$ echo hello hello
hello hello
$ `echo hello hello`
-ksh: hello: not found [No such file or directory]
$ echo \"hello hello\"
"hello hello"
$ `echo \"hello hello\"`
-ksh: "hello: not found [No such file or directory]

The 2nd and 6th commands are the most relevant to my question. If I run that second command "hello hello", then it will evaluate that as one big argument. However, if I try to run that last command

`echo \"hello hello\"`

then it shoud have the same behavior? But it is seeing "hello as its own independent word. Can some explain this and how I can get that 6th command to work like the 2nd command, such that it evaluates "hello hello" as one whole statement?

(This has a more practical application, but this was the smallest example I could produce).

Thank you in advance!

EDIT: I see I got a downvote, so I'll be more concrete about what problem I am running into.

rcli4 6379 keys AAA* | sed -e "s/.*/'&'/" | while read line; do rcli4 6379 get $line; done

Note that rcli4 is just an alias for redis-cli -p. I keep getting a

(error) ERR wrong number of arguments for 'get' command

which is due to the quotation marks being parsed incorrectly. I've tried different combinations of things like adding more quotes, removing that sed statement, etc. to no avail, but I think being able to solve my original hello hello problem will give me enough insight on how to fix my specific problem.

Upvotes: 0

Views: 525

Answers (1)

John1024
John1024

Reputation: 113854

Inside a quoted string, a quote is just another character. It has no special power.

If I understand the problem correctly as it is stated in the edit, the solution is to quote $line inside the do-loop, not before it. Thus, try:

rcli4 6379 keys 'AAA*' | while read -r line; do rcli4 6379 get "$line"; done

Without the double quotes around $line, the shell would perform word splitting and pathname expansion on the contents of line. You don't want either. Double-quotes suppresses both.

Also, we added the -r option to read. This prevents read from doing backslash processing on the contents of line.

Lastly, we put single-quotes around the database key glob AAA*. Without quotes, the shell will interpret AAA* as a file glob and will perform pathname expansion on it. If there happen to be files in the current directory matching that glob, the results will be unexpected and unwanted. If the bash option nullglob is set, the result will be not what you want regardless of what files are in the current directory.

Upvotes: 1

Related Questions