Как защитить скобки, переданные команде cd?

Как защитить скобки, переданные команде cd?

Я спросилздеськак сделать cdзащиту пробелов. Дополнение Tab отлично, но иногда нужно вставлять путь из буфера обмена, так что это полезно.

Однако решение ломается из-за скобок. Как бы вы ни пытались экранировать и защитить ввод, он всегда возвращает:

bash: syntax error near unexpected token `('

Есть ли способ сделать так, чтобы он также обрабатывал скобки? Я хочу, чтобы когда я ввожу это, это работало:

cd My path with spaces (and parentheses)

решение1

Используйте одинарные кавычки 'вокруг аргумента. (Это работает для любой команды, а не только cd).

cd 'My path with spaces (and parentheses)'

Вы не можете заставить bash передать скобки в cd. Заставить пробелы работать вообще — это очень специализированный хак.

Одинарные кавычки работают вокруг каждого символа, кроме 'самого себя. Замените одинарные кавычки на последовательность из 4 символов '\''.

cd 'Apostrophe'\''s a pain'

Это не работает, если имя каталога начинается с дефиса, потому что это заставляет cdкоманду интерпретировать аргумент как опцию. Передайте --перед именем каталога, чтобы избежать этого.

Видетьhttps://unix.stackexchange.com/questions/69144/how-do-i-escape-a-sub-directory-name-with-an-ampersand-in-it/69147#69147Больше подробностей.

Другой метод — заставить оболочку считывать отдельную строку текста вместо передачи аргумента в командной строке.

Strapakowsky@darkstar ~$ read -r; cd -- "$REPLY"
My path with spaces (and parentheses)
Strapakowsky@darkstar ~/My path with spaces (and parentheses)$ 

Вместо того, чтобы копировать-вставлять вручную, вы можете сделать это программно. Установите либоxclipилиxsel.

cd -- "$(xclip -o -selection clipboard)"
cd -- "$(xsel -bo)"

Вы можете сделать это псевдонимом.

alias cde='cd -- "$(xsel -bo)"'

решение2

Как правильно cdуказывать каталоги, в именах которых есть такие символы, как пробелы и скобки:

Если имя вашей папки не содержит символ одинарной кавычки ', просто заключите его в одинарные кавычки:

cd 'My path with spaces (and parentheses)'

Если он содержит ', но не содержит символ двойной кавычки ", обратной косой черты \, обратной кавычки `или знака доллара $, заключите его в двойные кавычки:

cd "My path with spaces (and parentheses)"

Нечасто имя файла или каталога содержит как одинарные, так и двойные кавычки. (Возможно, это связано с тем, что имя файла или каталога вообще нечасто содержит двойные кавычки. Единственная причина, по которой я изначально не рекомендовал двойные кавычки, заключается в том, что, в отличие от одинарных, двойные кавычки позволяют расширять $переменные среды. Это может стать проблемой, если имя файла содержит $символ, за которым следует текст.)

Если он содержит оба или вам просто нужен другой метод, то вы можете вручную экранировать каждый пробел и скобку, вставив \перед ними символ обратной косой черты:

cd My\ path\ with\ spaces\ \(and parentheses\)

Это раздражает, но, к счастью, оболочка ссделаем это для вас, если вы введете начало имени и нажмете Tab. Если есть более одного имени файла или каталога, которое начинается с My, то вам может потребоваться ввести еще немного, чтобы оно раскрылось. Если вы нажмете , Tabа оно не раскроется, вы можете нажать Tabеще раз, чтобы увидеть список файлов, которые соответствуют тому, что вы ввели до сих пор. Тогда вы будете знать, сколько еще вам нужно ввести, чтобы оно совпало уникально и раскрылось.

В качестве альтернативы вы можете экранировать внутренние кавычки. Например, предположим, что у вас есть папка с именем:

Mischa's gardening tips for "home and office"

Вы можете использовать:

cd Mischa\'s\ gardening\ tips\ for\ \"home\ and\ office\"

Но вы также можете просто использовать:

cd 'Mischa'\''s gardening tips for "home and office"'

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

Почему вы, вероятно, не сможете сделать cdработу так, как вам хотелось бы:

Что касается cd My path with spaces (and parentheses)работы: нет, вы действительно не можете этого сделать, потому что это поведение не является специфичным для cdкоманды, это часть способа выполнения любой команды. Когда команда запускается, она дает список аргументов, предоставленных пользователем. Когда оболочка видит пробел, она знает, что один аргумент только что закончился, а другой только что начался. Чтобы передать пробел как часть аргумента, его нужно заключить в кавычки одним из вышеперечисленных способов.

Вы могли бы достичьчастьэтогонекоторыйвремени -- вы могли бы заставить cd My path with spacesсебя войти в My path with spacesпапку. Вы могли бы сделать это, написав скрипт оболочки, который объединяет все предоставленные пользователем аргументы с пробелами. (Затем, если вы хотите, вы могли бы заставить себя cdвызывать этот скрипт, создав псевдоним оболочки, названный cdдля него; это имело бы приоритет над встроенной оболочкой cd, которую вы в настоящее время обычно запускаете.) Но:

  • Скрипт не получит различные аргументы для My path with spacesи My path with spaces, поэтому cd My path with spacesзавершится ошибкой или попадет в неправильную папку.

  • Вы не могли сделать этого для скобок, потому что они используются для группировки оболочкой, так что они никак не сообщаются команде. На самом деле, в большинстве случаев оболочка просто выдаст синтаксическую ошибку (как вы видели):

    ek@Kip:~$ cd My path with spaces (and parentheses)
    bash: syntax error near unexpected token `('
    

    Независимо от того, что вы измените, эта синтаксическая ошибка будет продолжать возникать при выполнении этой команды.

Я говорю, что вы "вероятно" не сможете заставить это работать, потому что есть один способ, который это сделает — вы можете создать свою собственную оболочку, которая будет вести себя так, как вы хотите. Но это чрезвычайно сложно, и вряд ли кто-то захочет это делать, просто чтобы внести это изменение. (Вы также можете изменить исходный код существующей оболочки, что является более практичным решением, но все равно требует больше усилий, чем большинство людей хотели бы приложить.) Кроме того, маловероятно, что cdможет принимать имена каталогов с произвольными символами, включая пробелы, как это происходит в Windows.

Если вам интересно, почему это работает в Windows, но не в Ubuntu: в Windows команды передаются в виде текста, набранного после них, какстрока текста, и когда команде необходимо интерпретировать эту строку как последовательность отдельных аргументов (что она обычно, но не всегда, делает), код команды должен вызвать специальную библиотечную функцию, которая анализирует строку командной строки. (В программе на языке C это происходит за кулисами, но все равно подразумевает использование API Windows.)

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