简体   繁体   中英

Executing command in bash with argument with space in it

I have a problem with executing some of the commands using bash. Let's say I have a simple bash script:

#!/bin/bash
cmd="sh -c \"ls\""
$cmd

This works all fine. However, if I alter the argument for the command to contain space:

#!/bin/bash
cmd="sh -c \"ls -a\""
$cmd

then it throws -a": 1: -a": Syntax error: Unterminated quoted string error. It seems that bash correctly noticed open quote, but it stops looking for closing quote on a first space. If I change $cmd to echo $cmd it returns sh -c "ls -a" as expected. If I execute this command in terminal everything works, but $(./mysh.sh) fails with same error.

I have tried escaping the space with \\ , or 'double-escape' quotes with \\\\\\" (silly idea, but was worth a try). Could anyone explain what is happening here?

You'd be better off storing commands in functions:

cmd() {
    sh -c "ls -a"
}
cmd

Or in arrays:

cmd=(sh -c "ls -a")
"${cmd[@]}"

Using plain string variables simply won't work. You'd have to use eval , which is not a great idea . Functions are much better.

cmd="sh -c \"ls -a\""
eval "$cmd"

Repeated applications of quoting rules can be complicated. First I will explain what is going wrong:

cmd="sh -c \"ls -a\""
$cmd

One of the first things Bash does when executing $cmd is split it up on whitespace characters: so you get a command with three arguments, equivalent to this:

sh -c "\"ls" "-a\""

Already you can see where this is going wrong. Some solutions have already been posted, but generally for each level of shell command processing the command will be subjected to, you need to provide another level of guard characters to maintain the original intended meaning:

# To execute the command "ls -a" in a shell:
sh -c "ls -a"
# Two shells deep:
sh -c "sh -c ls\\ -a"    # Backslash protects space from being treated as an argument separator by first level of shell processing

It's better to avoid repeat application of quote-guarding if you can...

cmd="sh -c \"ls -a\""
eval $cmd

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM