3 трюка для терминала, о которых вам хотелось бы знать раньше

3 трюка для терминала, о которых вам хотелось бы знать раньше


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

Подстановка процессов для преобразования данных во временные файлы данных

Возможно, вы сталкивались с ситуацией, когда вам нужен был путь к файлу в качестве аргумента, а у вас были только данные.

Например, допустим, вы хотите отредактировать текст, который уже есть в терминале:

echo "foo" | nano     

Предыдущая команда не работает, потому что нельзя передавать данные в nano через конвейер; вместо этого нужно указать путь к файлу, например: nano /path/to/file.txt.

Чтобы решить эту проблему, вы, вероятно, будете использовать последовательность команд, подобную следующей:

echo foo > bar.txt nano bar.txt     

С помощью двух отдельных команд вы создаёте файл, а затем что-то с ним делаете. Такой подход является неоптимальным, потому что файлы остаются разбросанными по вашей файловой системе, и вам также приходится вводить путь к ним. Подстановка процессов решает эту проблему:

echo <(true)     

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

/dev/fd/16

Подстановка процесса создает временный файл из вывода команды, позволяя другой команде читать из него. Таким образом, в предыдущем примере «<(true)» генерирует путь к выводу, а «echo» его получает. Данные в выводе просто равны «true».

Часть пути «fd» относится к термину «дескриптор файла», который просто является идентификатором, используемым программным обеспечением для внутреннего обращения к открытым файлам. В этом примере дескриптор файла имеет значение 16. Дескрипторы файлов являются приватными для процессов, которые их используют — в данном случае это «echo».

Давайте используем подстановку процесса полезным образом:

nano <(echo "foo")     

Предыдущая команда эквивалентна введению следующей:

echo "foo" > /tmp/foo nano /tmp/foo     

Вы не сможете сохранять и редактировать текст при запуске nano <(echo "foo"), потому что специально созданный файл доступен только для чтения, но вы можете изменить место его сохранения с помощью сочетания клавиш Ctrl+o.

Подстановка процесса ввода/вывода

Выражение "<(foo)" создаёт подстановку процесса для ввода. В качестве альтернативы, вы также можете создать подстановку процесса для вывода:

echo "foo" > >(cat)     

Предыдущая команда эквивалентна введению следующей:

echo "foo" > /tmp/foo cat /tmp/foo     

Хотя эти две команды могут казаться разными, они работают одинаково. Это становится яснее, когда вы понимаете, что echo "foo" > >(cat) записывает "foo" в специальный файл, из которого затем читает команда cat.

Итак, подводя итог:

  • echo <(true) — это подстановка процесса ввода, и echo получает данные через специальный путь к файлу (в данном случае данные — только «true»).
  • echo "foo" > >(cat) является выходной подстановкой процесса, и cat получает выведенное слово через специальный путь. Первый символ ">" — это оператор перенаправления, а второй является частью самой подстановки.

Чтобы завершить этот раздел, я думаю, что реальный пример удачно всё свяжет:

diff <(ls -1 ~) <(ls -1 /tmp)     

Эта команда сравнит различия между двумя директориями. Использование подстановки процесса во входных данных полезно в этом случае, потому что diff ожидает пути к файлам, а именно это и предоставляет подстановка процесса.

Флаг «ls -1» — это единица, а не буква l.

Расширение истории для повторения команд

Разработчики Bash часто используют термин «расширение». Это звучит сложно, но на самом деле просто означает преобразование чего-то маленького во что-то большее — расширение. Самый известный пример — расширение тильды (~), которое заменяется на путь к вашему домашнему каталогу.

Следующие три примера называются расширениями истории. Эти выражения расширяются от простых вводимых символов до элементов вашей истории команд оболочки.

Бах, бах!!

Это одна из команд, которой я пользуюсь чаще всего после cd и ls. Ею просто пользоваться и её легко понять. Она повторно выполняет последнюю вашу команду.

ls !!     

Вы можете видеть из вывода команды, что команда ls выполняется дважды.

Развернуть конкретный элемент в вашей истории

Сначала просмотрите вашу историю, чтобы выбрать подходящую команду:

history     

Затем просто выберите один из чисел слева и вставьте его в качестве N:

!N     

Дважды проверьте команду перед её повторным выполнением, потому что если вы случайно выполните неправильную команду, ваш день будет испорчен.

Лучшее в том, что при раскрытии этих пронумерованных элементов истории их номера остаются неизменными, заключается в том, что это позволяет вам с ними знакомиться. Конечно, это знакомство длится только до тех пор, пока вы не удалите файл ~/.bash_history.

Развернуть по имени для более удобного выбора

Частый поиск в истории команд и нахождение определённой команды по её номеру может быть утомительным. Существует альтернативный и более эффективный способ: Bash позволяет частично набрать начало команды, и будет выполнено самое последнее совпадение.

echo foo !e !ech     

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

Группы команд

Иногда вы захотите выполнить несколько команд как группу, но воспринимать их вывод как один результат. Рассмотрим следующий пример:

echo foo > /tmp/foo.txt echo bar >> /tmp/foo.txt     

Символ «>» называется оператором перенаправления и отправляет вывод команды в указанный файл, перезаписывая его содержимое; «>>» делает то же самое, за исключением того, что добавляет данные в файл — то есть оператор перенаправления для добавления (append).

Предыдущая команда создаст файл, который будет выглядеть следующим образом:

foo bar

Иногда, когда ваши команды более сложные, использование такого подхода может выглядеть некрасиво из-за большого количества ненужных строк. Более простой подход — использовать группу команд.

Группа команд объединяет все выходные данные своих команд в один. Это делает обработку результата значительно проще.

{ echo foo; echo bar; } > /tmp/foo.txt     

Это приведет к такому же результату, как и предыдущая команда. Перенаправление должно происходить только один раз, поэтому оператор добавления перенаправления (>>) не нужен.

После каждой команды требуется точка с запятой, особенно после последней команды. Также необходимы пробелы между скобками и словами команд.

Вы можете доказать, что команды вне группы выполняются только один раз, выполнив следующую последовательность команд:

{ echo "A"; echo "B"; } | wc -l     

Группа команд отправляет оба вывода echo вместе как единый поток. Вот почему «wc» считает обе строки вместе как одно сообщение и показывает 2; в противном случае он показал бы 1 на двух отдельных строках.

Пример реального сценария использования:

{ ping -c 1 example.com; ping -c 1 example.net; } > /tmp/ping.txt      

Вкратце:

  • Подстановка процесса заменяет процесс временным файловым путем. Например, nano <(echo "foo") и echo "foo" > >(cat).
  • Расширения истории Bash — это специальные символы, которые ссылаются на элементы вашей истории Bash. Например, !foo, !N или !!.
  • Группа команд объединяет вывод нескольких команд в один результат. Например, { echo "foo"; echo "bar"; } > /tmp/foo.txt.

Все, что рассмотрено, лишь поверхностно охватывает возможности Bash. Если вас привлекают расширения истории оболочки, вам понравится наш учебник о том, как использовать команду history. Вас также могут заинтересовать советы, которые облегчают изучение командной строки.

Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *