Разница между echo $(cal) и echo "$(cal)"

Разница между echo $(cal) и echo "$(cal)"

Я использую echo $(cal)и echo "$(cal)"в Linux, и это дает мне разные результаты, как на картинке. Двойные кавычки не должны мешать $в этом случае, так что дает echo "$(cal)"этот горизонтальный стиль по сравнению с echo $(cal).

Вот результат:

Скриншот вывода

echo "$(cal)"

Su Mo Tu We Th Fr Sa  
                   1  
 2  3  4  5  6  7  8  
 9 10 11 12 13 14 15  
16 17 18 19 20 21 22  
23 24 25 26 27 28 29  
30

echo $(cal)

June 2019 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

решение1

Есть два ключевых отличия:

  1. Оболочка выполняетразделение словна unquoted $(cal). Это означает, что, принимая значение по умолчанию для IFS, все строки пробелов (включая новые строки) заменяются одним пробелом. Это вывод unquoted команды находится на одной строке.

    Вот более простой пример:

    $ s='line     1
    > line  2'
    $ echo "$s"
    line     1
    line  2
    $ echo $s
    line 1 line 2
    

    Как вы видите, во втором echo, без двойных кавычек, все последовательности пробелов были заменены одинарными пробелами. Это как раз то, что вы видели при использовании echoбез двойных кавычек с echo $(cal).

  2. Оболочка выполняетрасширение имени путина результат разделения слов. Это не имеет никакого значения в вашем примере, но если ваш вывод включает ?или *или другие глоб-активные символы, это может привести к некоторым сюрпризам.

    Вот простой примеррасширение имени пути. Начнем с каталога с тремя файлами:

    $ ls
    file1  file2  file3
    

    Теперь давайте определим строку: $ s='file?'

    Теперь видим, что echoс двойными кавычками возвращается наша строка, но без двойных кавычек строка расширяется до имен файлов:

    $ echo "$s"
    file?
    $ echo $s
    file1 file2 file3
    

Связанный контент