Bash tokenizing quoted string with spaces as individual words

后端 未结 3 1284
没有蜡笔的小新
没有蜡笔的小新 2021-01-23 05:59

I\'m trying to execute the following commands:

mkdir \'my dir\'
CMD=\"ls \'my dir\'\"
RESULT=$($CMD)

This results in:

ls: \'my:         


        
相关标签:
3条回答
  • 2021-01-23 05:59

    To provide another approach -- one that works on POSIX systems -- xargs can do this parsing for you, as long as you can guarantee that the argument list is short enough that it doesn't get split into multiple separate commands:

    CMD="ls 'my dir'"
    printf '%s\n' "$CMD" | xargs sh -c '"$@"' sh
    
    0 讨论(0)
  • 2021-01-23 06:01

    Solution 1: Use sh -c

    mkdir 'my dir'
    CMD="ls 'my dir'" # careful: your example was missing a '
    RESULT=$(sh -c "$CMD")
    

    Solution 2: Declare CMD as an array

    mkdir 'my dir'
    CMD=(ls 'my dir') # array with 2 elements
    RESULT=$("${CMD[@]}")
    
    0 讨论(0)
  • 2021-01-23 06:07

    (Almost) all languages differentiate between code and data:

    args="1, 2"
    myfunc(args) != myfunc(1, 2)
    

    The same is true in bash. Putting single quotes in a literal string will not make bash interpret them.

    The correct way of storing a program name and arguments (aka a simple command) is using an array:

    cmd=(ls 'my dir')
    result=$("${cmd[@]}")
    

    Bash will automatically split words on spaces unless you double quote, which is why your example sometimes appears to work. This is surprising and error prone, and the reason why you should always double quote your variables unless you have a good reason not to.

    It's also possible to get bash to interpret a string as if it was bash code entirely, using eval. This is frequently recommended, but almost always wrong.

    0 讨论(0)
提交回复
热议问题