Почему использование '*' не всегда работает на zsh?

Я выполнил следующую команду на zsh

sudo apt-get install rhythmbox* 

Она вызвала ошибку, когда я запустил ту же команду в bash, она работала. Почему это происходит?

Как я могу заставить вышеуказанную команду работать на zsh?

4
задан 3 September 2017 в 06:20

3 ответа

Вот что происходит

Bash попытается оценить шаблон rhythmbox* в текущем рабочем каталоге. Поскольку очень маловероятно, что какой-либо файл или каталог будет начинаться с последовательности rhythmbox, он не будет расширяться, но Bash предоставит его в качестве аргумента apt-get здесь.

Обратите внимание, что если у вас есть файл с именем rhythmbox-test, он не будет работать, так как будет расширен, и rhythmbox-test будет предоставлен в качестве аргумента для apt-get.

Решение: избегайте или цитируйте его!

Итак, чтобы надежно использовать скороговорки из apt-get в оболочке Bash, вы всегда должны избегать его. Используйте кавычки или обратную косую черту, например

sudo apt-get install rhythmbox\* 

или

sudo apt-get install "rhythmbox*"

Примерно то же самое касается Zsh.

Расширение шаблона называется globbing .

Демо

touch aa ab  # creates files aa and ab
ls a*        # lists both files as Bash provided ls two arguments.
ls 'a*'      # No such file or directory. Bash provided literally a* to ls.
ls a\*       # No such file or directory. Same as above.
0
ответ дан 3 September 2017 в 06:20

Вы должны использовать кавычки, чтобы zsh не расширял '*' (вы хотите, чтобы apt-get расширил *)

sudo apt-get install "rhythmbox*"
0
ответ дан 3 September 2017 в 06:20

Вместо этого используйте ^rhythmbox^). Обычно избегайте * при установке или удалении пакетов.

Даже если вы цитируете его , поэтому оболочка пропускает его без изменений , * не делает то, что ожидает большинство людей, когда появляется в имени пакета с большинством apt / apt-get действия, в том числе install, remove и purge. Избегайте * в схеме, которая следует за этими действиями, если вы точно не знаете, что они делают и почему. Обычно * не то, что вы на самом деле хотите, и это один из тех случаев, когда кажется, что вы этого не хотите. * не означает , не означает «любые символы» в этом контексте.

Правильный способ указать apt-get установить все пакеты, имена которых начинаются с с rhythmbox, это:

sudo apt-get install ^rhythmbox

Это также работает с apt install. Точно так же, если вам нужно было удалить такие пакеты, вы можете указать ^rhythmbox после действия remove или purge.

^rhythmbox соответствует всем именам пакетов, которые начинаются с rhythmbox, потому что ^ является якорем начала строки (или, в данном случае, начала строки) . [+1173]


Проблема с * в имени пакета для установки или удаления заключается в том, что apt и apt-get интерпретируют его как регулярное выражение, а не как глобус . В регулярном выражении * означает «ноль или более предыдущего элемента». Поэтому, когда вы запускаете sudo apt-get install с rhythmbox\*, 'rhythmbox*', "rhythmbox*" или (когда оболочка не раскрывается *) rhythmbox*, вы на самом деле говорите apt-get установить каждый пакет с rhythmbo где-нибудь в его имени.

  • Не rhythmbox, rhythmbo, потому что x должен появляться любое количество раз - ноль или более раз.
  • Не в начале имени или как целого имени, но в любом месте его имени.

В конкретном случае этого конкретного пакета это, вероятно, не вызовет огромных проблем, так как, вероятно, есть несколько пакетов, которые имеют rhythmbo в своих именах, но не начинаются с [ 1140]. Но с пакетами, имена которых короче, особенно при использовании действий remove или purge, это часто приводит к катастрофическим последствиям .


Основным исключением является apt list. Действие list действительно интерпретирует * и ? как глобализующих символов, а не как метасимволы регулярного выражения. Таким образом, вы можете искать пакеты, имена которых начинаются с rhythmbox, например:

apt list rhythmbox\*

(или с 'rhythmbox*' или "rhythmbox*".)

Но чтобы установить таких пакетов - и не устанавливать больше пакетов, чем вы хотите - вам все равно нужно использовать:

sudo apt install ^rhythmbox

Или вы можете просто передать нужные вам имена пакетов. Использование apt list может помочь вам найти их.

0
ответ дан 3 September 2017 в 06:20

Другие вопросы по тегам:

Похожие вопросы: