Почему разделение поля WORD не происходит в операторе case WORD in, когда WORD является переменной?

Сценарий оболочки:

#!/bin/sh
a="foo  bar"

case $a in
    "foo  bar")
        echo case 1
        ;;
esac

case foo  bar in
    "foo  bar")
        echo case 2
        ;;
esac

Выполнение этого с bash приводит к следующему выводу и ошибке.

case 1
foo: line 10: syntax error near unexpected token `bar'
foo: line 10: `case foo  bar in'

Выполнение этого с dash:

case 1
foo: 10: foo: Syntax error: word unexpected (expecting "in")` leads to the following output and error.

Я не понимаю, почему первый оператор case выполняется успешно, а второй нет.

Согласно документу POSIX по адресу http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_05, в любом случае произойдет разделение полей, поэтому после того, как $a расширится до foo bar в первом выражении case, оно должно быть эквивалентно второму.

Так что оба должны потерпеть неудачу. Почему первый оператор case выполняется успешно?


person Lone Learner    schedule 20.01.2016    source источник
comment
Потому что первая — это одна строка, а вторая — нет?   -  person 123    schedule 20.01.2016
comment
@123 Первый touch "foo bar". Тогда, по вашей логике, a="foo bar"; ls $a должен отображать файл foo bar, но ls foo bar не должен этого делать, потому что первая представляет собой одну строку, а вторая — нет. Но на самом деле обе команды не работают, потому что в в обоих случаях, и в обоих случаях у нас есть два слова, а не одно, после разделения поля.   -  person Lone Learner    schedule 20.01.2016
comment
Зачем вы спорите о том, чего явно не понимаете? Посмотрите на ответ ниже.   -  person 123    schedule 20.01.2016
comment
@123 Я спорю о том, что пытаюсь понять. Если бы я четко понимал эту тему, я бы не задавал вопрос в первую очередь. Я прочитал ответ ниже. Это хорошо. Я проголосовал и принял это как правильный ответ. Это не меняет того факта, что я не понимаю вашего комментария выше и того, как он объясняет наблюдаемое поведение в вопросе, то есть почему первая строка представляет собой одну строку в case $a, а не в ls $a.   -  person Lone Learner    schedule 20.01.2016
comment
Итак, вы прочитали ответ, но не поняли мой комментарий? I am trying to understand Вы никогда не просили разъяснений. Вы только что начали объяснять разделение полей.   -  person 123    schedule 20.01.2016
comment
@123 Я прочитал ответ. Это объясняет, что в случае case нет разделения полей. В вашем комментарии указано, что в первом случае это одна строка. Почему? Я этого не понял. Вот почему я прокомментировал то, что прокомментировал. Через 5 минут ответ @l3x ниже объяснил, что разделение полей не происходит в case, и я принял его как правильный ответ. Я не просил каких-либо разъяснений в комментарии, потому что я уже задал его в своем вопросе. Я только что опубликовал то, что выглядело как противоречие вашему комментарию, чтобы сделать комментарий коротким и запустить дискуссию.   -  person Lone Learner    schedule 20.01.2016
comment
Я не понимаю, какое разрешение вы хотите от этого?   -  person 123    schedule 20.01.2016
comment
@123 Нет. На вопрос уже был дан ответ.   -  person Lone Learner    schedule 20.01.2016


Ответы (1)


Разделение слов не выполняется в первом случае для слова, используемого в операторе case. Из POSIX:

Условная конструкция регистра

Случай условной конструкции должен выполнять составной список, соответствующий первому из нескольких шаблонов (см. Обозначение сопоставления шаблонов), которому соответствует строка, полученная в результате расширения тильды, расширения параметра, подстановки команд, арифметического расширения и удаления кавычек. данное слово.

Итак, заключаете вы слово в кавычки или нет, оно не будет расширено и безопасно без кавычек.

case $a in  
   ...
esac

и

case "$a" in    
   ...
esac

будут работать, как ожидалось.

Ясно, что это не эквивалентно второму примеру, где у вас есть два слова в операторе case.

person P.P    schedule 20.01.2016