Linux как экранировать пробел
Войти
Авторизуясь в LiveJournal с помощью стороннего сервиса вы принимаете условия Пользовательского соглашения LiveJournal
Пробелы в командной строке Bash
О том что пробелы в Linux недопустимы, ну точнее нежелательны. я узнал еще на заре своего освоения этой системы. Тем ни менее, всегда возникает вопрос, а что с ними делать, дабы не создавать проблем. Частично ответ дается в этой статье.
Алексей Дмитриев, 23 сентября 2009
Если аргумент какой-либо команды содержит пробелы (или знаки табуляции) то Bash интерпретирует их как множественные аргументы. Вот, например, команда echo:
Но ошибкой будет считать, что команда такая "умная", что в точности воспроизводит введенный текст. Это не так:
На самом деле команда интерпретирует любое количество пробелов (и знаков табуляции) как один пробел; а пробел как разделитель между аргументами. Так как по умолчанию команда echo печатает стандартный вывод в одну строку, то и результат будет одинаковым с любым количеством пробелов.
Другие команды по умолчанию печатают свой вывод обработки каждого аргумента с новой строки, например команда print:
Тут уж сразу видно, что команда обрабатывала не фразу, а каждое слово как отдельный аргумент.
Как же заставить команду включить пробелы (и знаки табуляции) в свой стандартный вывод? Тут возможны два пути:
1. Маскировка при помощи обратного слэша (\). По-английски называется Escaping, а управляющие символы, начинающиеся с обратного слэша, Escapе-символами (само слово "escapе" переводится как исчезать, скрываться). Вот пример маскировки пробела:
Механизм такой маскировки прост: при помощи специального символа, обратного слэша, мы лишили пробела его значения как разделителя между аргументами, и теперь он интерпретируется Bash только как часть текста.
2. Закавычивание. Если заключить аргумент в кавычки, двойные или одинарные, то он всегда будет интерпретирован в качестве единого выражения. Например:
Такой же механизм работает и с командами, принимающими имена файлов в качестве аргумента. Имена файлов ведь тоже могут содержать пробелы; для примера создадим файл по имени text file и попытаемся просмотреть его при помощи команды cat:
Применим маскировку:
Или кавычки:
А интересно, справится ли с этой задачей автозавершение?
При работе в командной строке администраторы часто сталкиваются с необходимостью что-то сделать с определенным файлом: удалить, переместить, скопировать. При выполнении подобных задач зачастую приходится обращаться к файлам по имени, что может быть затруднительно, поскольку в именах файлов могут встречаться самые разные символы. Даже те, которых нет на клавиатуре. В этом плане работу может облегчить файловый менеджер, в котором файл можно просто выделить и совершить с ним нужное действие. Но для тех, кто привык работать исключительно в командной строке, предлагаются следующие способы.
В качестве shell-оболочки рассмотрим bash, как самую используемую. А в качестве операции над файлами рассмотрим удаление, как самую деструктивную.
Ситуации могут быть разными. В текущей директории могут быть файлы, которые нужно удалить вместе с теми, которые нужно оставить. Имена у них могут быть самыми разными. Причем первые от последних могут отличаться только одним каким-нибудь заковыристым символом.
В названии файла есть служебный символ bash
Самый простой случай. Для удаления файлов, содержащих в своем названии служебные символы вроде пробелов, кавычек, двойных кавычек, звездочек, обратные кавычки и др. можно заэкранировать обратным слешем или использовать одинарные кавычки:
С помощью одинарных кавычек нельзя удалить файл, в названии которого есть одинарная кавычка, даже заэкранировав ее.
С полным списком служебных символов и механизмом экранирования в bash можно ознакомиться в man bash. Раздел QUOTING.
Имя файла начинается с дефиса
Удалить файл, начинающийся с дефиса простым экранированием не получится, и команда rm будет воспринимать дефис, как начало своего аргумента. Решить проблему довольно просто:
Удаляем по wildcard
Если удаление файлов попадает под wildcard-маску, то можно удалить всю группу файлов:
Файлы с управляющим символом в названии
В названии файла может встречаться управляющий ASCII-символ, такой как перевод строки (\n), табуляция (\t), backspace (\b). Это символы с ASCII-кодами менее 0x20, а также символы DELETE и ESC. Для удаления таких файлов подходит конструкция:
Другим способом удаления таких файлов являяется ввод управляющего символа с клавиатуры. Для этого нужно воспользоваться комбинацией клавиш, которая экранирует следующий введенный символ, тем самым запрещая системе обрабатывать его. Как правило, эта комбинация CTRL+V. Точно убедиться в этом можно с помощью команды stty -a, посмотрев на параметр lnext. Удалим файл, содержащий символ ESC:
Удаление файлов с символами utf8
Если имя файла содержит символ в кодировке utf8, который мы не можем набрать на клавиатуре, то удалить такой файл можно выделением его мышкой, копированием в буфер обмена и последующей вставкой на ввод команды rm. Главное условие состоит в том, что наш терминал должен работать в кодировке utf8. Кодировка выставляется в настройках терминала. Будь то xterm, putty или брутальный linux tty.
Перекодировка имени файла
Подозревая, что имя файла находится в кодировке, отличной от кодировки терминала, мы можем выполнить перекодирование всех файлов в текущей директории. В результате файлы с битой кодировкой будут перекодированы, а файлы с ascii-символами изменений не претерпят. Существенный плюс этого способа – приведение всех файлов в читабельный вид.
Как видно, чтобы осуществить правильное перекодирование нужно знать две кодировки: предполагаемую кодировку файла и кодировку нашего терминала. Наиболее трудно распознать предполагаемую кодировку файла по непонятным символам. Есть замечательная табличка
Также можно воспользоваться сторонними программами, которые попытаются распознать кодировку автоматически. Например, онлайн-декодер Лебедева.
Если вы встретили такие символы в примонтированном media-носителе или смонтированном разделе Windows, не спешите ничего перекодировать. Возможно, вы просто указали неправильные опции монтирования.
Автокомплит
В случае, если в директории название требуемого файла начинается уникально, и это название можно однозначно сформировать автокомплитом, то это довольно простой способ удалить файл:
Удаляем файл через меню выбора
Если мы дошли сюда, дело плохо. Попробуем удалить конкретный файл, составив для этого меню выбора. В итоге, все что нам останется сделать – это выбрать нужный пункт меню вместо ввода имени файла. Для этого нам нужно запрограммировать действие, которое будет происходить с файлом или файлами после ввода нами нужных пунктов меню.
Удаление по номеру inode
Удалить файл можно по его номеру inode. Номер inode уникально идентифицирует файл в файловой системе. Узнать номер inode можно с помощью команды ls, а удалить – с помощью find. Недостаток этого способа, такой же, как у предыдущего. Неудобно, в случае большого числа файлов.
Удаление по hex-коду
И нельзя не упомянуть один суровый метод. Удаление по hex-кодам. Суть такова: мы узнаем hex-коды всех байтов в имени файла, а затем удаляем файл, указывая вместо имени hex-коды.
В данной главе мы будем учиться размещать более одной команды в командной строке, используя для этого операторы управления . Также мы кратко обсудим связанные с этими операторами параметры ($?) и вопросы использования аналогичных операторам специальных символов (&).
Точка с запятой (;)
Вы можете разместить две и более команд в одной и той же строке, разделив эти команды с помощью символа точки с запятой ; . Командная оболочка будет исследовать строку команды до момента достижения символа точки с запятой. Все аргументы перед этим символом точки с запятой будут рассматриваться как аргументы, не относящиеся к команде, находящейся после символа точки с запятой. Все команды с наборами аргументов будут выполнены последовательно, причем командная оболочка будет ожидать завершения исполнения каждой из команд перед исполнением следующей команды.Амперсанд (&)
Технические подробности выполняющихся при использовании рассматриваемого оператора операций приведены в разделе, посвященном процессам .
Символ доллара со знаком вопроса ($?)
Код завершения предыдущей команды сохраняется в переменной командной оболочки с именем $? . На самом деле $? является параметром командной оболочки, а не ее переменной, так как вы не можете присвоить значение переменной $? .Двойной амперсанд (&&)
Командная оболочка будет интерпретировать последовательность символов && как логический оператор "И" . При использовании оператора && вторая команда будет исполняться только в том случае, если исполнение первой команды успешно завершится (будет возвращен нулевой код завершения). Во втором примере используется тот же принцип работы логического оператора "И" . Данный пример начинается с использования работоспособного варианта команды cd с последующим исполнением команды ls , после чего используется неработоспособный вариант команды cd , после которого команда ls не исполняется .Двойная вертикальная черта (||)
Оператор || представляет логическую операцию "ИЛИ" . Вторая команда исполняется только тогда, когда исполнение первой команды заканчивается неудачей (возвращается ненулевой код завершения). В следующем примере используется тот же принцип работы логического оператора "ИЛИ" .Комбинирование операторов && и ||
Вы можете использовать описанные логические операторы "И" и "ИЛИ" для создания структур условных переходов в рамках строк команд. В данном примере используется команда echo для вывода информации о том, успешно ли отработала команда rm .Экранирование специальных символов (\)
Символ обратного слэша \ позволяет использовать управляющие символы без их интерпретации командной оболочкой; процедура добавления данного символа перед управляющими символами называется экранированием символов .Обратный слэш в конце строки
Строка команды, заканчивающаяся обратным слэшем, продолжается в следующей строке. Командная оболочка не будет интерпретировать символы перехода на новые строки и отложит исполнение операции раскрытия команды и ее исполнение до момента чтения новой строки команды без обратного слэша в конце.Практическое задание: операторы управления
0. Ответ на каждый из вопросов может быть представлен с помощью единственной строки команды!
1. Какой бинарный файл исполняется при вводе команды passwd ?
2. Какого типа данный файл?
3. Выполните команду pwd два раза. (Помните о пункте 0.)
4. Выполните команду ls после команды cd /etc , но только в том случае, если исполнение команды cd /etc завершилось без ошибок.
5. Выполните команду cd /etc после команды cd etc , но только в том случае, если исполнение команды cd etc завершилось ошибкой.
6. Выведите строку "сработало" в случае успешного завершения исполнения команды touch test42 или строку "не сработало" в случае неудачного завершения. Все операторы должны находиться в одной строке и исполняться с привилегиями обычного пользователя (не пользователя root). Протестируйте полученную команду в вашей домашней директории и директории /bin/ .
7. Выполните команду sleep 6 ; для чего предназначена эта команда?
8. Выполните команду sleep 200 в фоновом режиме (без ожидая завершения ее исполнения).
9. Создайте строку команды, в рамках которой будет исполняться команда rm file55 . Ваша строка команды должна выводить строку 'удалось' в том случае, если файл file55 был удален и строку 'не удалось' в случае возникновения проблем.
10 (необязательное задание). Используйте команду echo для вывода строки "Hello World со странными' символами \ * [ >
\\ ." (включая все кавычки).
Корректная процедура выполнения практического задания: операторы управления
0. Ответ на каждый из вопросов может быть представлен с помощью единственной строки команды!
1. Какой бинарный файл исполняется при вводе команды passwd ?
2. Какого типа данный файл?
3. Выполните команду pwd два раза. (Помните о пункте 0.)
4. Выполните команду ls после команды cd /etc , но только в том случае, если исполнение команды cd /etc завершилось без ошибок.
5. Выполните команду cd /etc после команды cd etc , но только в том случае, если исполнение команды cd etc завершилось ошибкой.
6. Выведите строку "сработало" в случае успешного завершения исполнения команды touch test42 или строку "не сработало" в случае неудачного завершения. Все операторы должны находиться в одной строке и исполняться с привилегиями обычного пользователя (не пользователя root). Протестируйте полученную команду в вашей домашней директории и директории /bin/ .
7. Выполните команду sleep 6 ; для чего предназначена эта команда?
Осуществляется ожидание в течение 6 секунд
8. Выполните команду sleep 200 в фоновом режиме (без ожидая завершения ее исполнения).
9. Создайте строку команды, в рамках которой будет исполняться команда rm file55 . Ваша строка команды должна выводить строку 'удалось' в том случае, если файл file55 был удален и строку 'не удалось' в случае возникновения проблем.
10 (необязательное задание). Используйте команду echo для вывода строки "Hello World со странными' символами \ * [ >
Если аргумент какой-либо команды содержит пробелы (или знаки табуляции) то Bash интерпретирует их как множественные аргументы. Вот, например, команда echo:
Но ошибкой будет считать, что команда такая "умная", что в точности воспроизводит введенный текст. Это не так:
На самом деле команда интерпретирует любое количество пробелов (и знаков табуляции) как один пробел; а пробел как разделитель между аргументами. Так как по умолчанию команда echo печатает стандартный вывод в одну строку, то и результат будет одинаковым с любым количеством пробелов.
Другие команды по умолчанию печатают свой вывод обработки каждого аргумента с новой строки, например команда printf:
Тут уж сразу видно, что команда обрабатывала не фразу, а каждое слово как отдельный аргумент.
Как же заставить команду включить пробелы (и знаки табуляции) в свой стандартный вывод? Тут возможны два пути:
1. Маскировка при помощи обратного слэша (\). По-английски называется Escaping, а управляющие символы, начинающиеся с обратного слэша, Escapе-символами (само слово "escapе" переводится как исчезать, скрываться). Вот пример маскировки пробела:
Механизм такой маскировки прост: при помощи специального символа, обратного слэша, мы лишили пробела его значения как разделителя между аргументами, и теперь он интерпретируется Bash только как часть текста.
2. Закавычивание. Если заключить аргумент в кавычки, двойные или одинарные, то он всегда будет интерпретирован в качестве единого выражения. Например:
Такой же механизм работает и с командами, принимающими имена файлов в качестве аргумента. Имена файлов ведь тоже могут содержать пробелы; для примера создадим файл по имени text file и попытаемся просмотреть его при помощи команды cat:
А интересно, справится ли с этой задачей автозавершение?
Автозавершение выбрало вариант маскировки. Это не удивительно, ведь маскировать приходится не только пробелы, но и управляющие символы, с которыми кавычки не справятся.
Пока мы рассматривали только пробелы внутри аргумента команды. Лишние же пробелы перед командой, между командой и опциями, между опцией и аргументом, как правило, игноририруются. Если только иное поведение специально не оговорено в синтаксисе команды.
И, наконец, пробел, поставленный вместо аргумента многих команд, заставляет их принимать стандартный ввод. Например:
Читайте также: