Продолжаем цикл статей о полезных советах и хитростях командной строки Bash. В сегодняшней статье мы рассмотрим поиск только того, что вам нужно, а также познакомимся с pwd
и узнаем путь, с которого был запущен скрипт.
В этом цикле статей вы узнаете:
- Полезные советы, приемы и методы работы с командной строкой Bash
- Как взаимодействовать с командной строкой Bash продвинутым образом
- Как отточить свои навыки работы с Bash в целом и стать более опытным пользователем Bash
Предыдущие части статей можно найти здесь:
- Полезные советы и фишки оболочки Bash — Часть 1
- Полезные советы и фишки оболочки Bash — Часть 2
- Полезные советы и фишки оболочки Bash — Часть 3
Содержание:
- Требования к программному обеспечению и условные обозначения
- Путь к рабочему каталогу
- Ищем только то, что нужно
- Заключение
Требования к программному обеспечению и условные обозначения
Категория | Требования или используемая версия программного обеспечения |
---|---|
Система | Свободные дистрибутивы GNU/Linux |
Программное обеспечение | Командная строка Bash, система на базе Linux |
Другое | Различные утилиты, которые либо включены в оболочку Bash по умолчанию, либо могут быть установлены с помощью sudo apt-get install tool-name (где tool-name представляет собой инструмент, который вы хотите установить) |
Условные обозначения | # - требует, чтобы заданные linux-команды выполнялись с правами root либо непосредственно от имени пользователя root, либо с помощью команды sudo .$ - требует, чтобы заданные linux-команды выполнялись от имени обычного непривилегированного пользователя |
Пример 1: Путь к рабочему каталогу
Мы привыкли, что вызов pwd в командной строке сообщает нам имя нашего текущего каталога:
$ pwd
/home/yodo/
Но если мы хотим получить каталог, из которого был запущен скрипт, работает ли использование этой переменной из скрипта таким же образом?
$ cat test_pwd.sh
#!/bin/bash
MY_PATH1="${PWD}"
echo "${MY_PATH1}"
MY_PATH2="$(pwd)"
echo "${MY_PATH2}"
Мы будем использовать два способа получения пути: посмотрим (для первого назначения MY_PATH1
) на автоматически заданную переменную PWD
(уровень ОС), а во втором случае (для второго назначения MY_PATH2
) выполним pwd
в под-оболочке ($(...)
) и присвоим его MY_PATH2
. Давайте выполним то же самое:
$ ./test_pwd.sh
/home/yodo/
/home/yodo/
Выглядит всё неплохо, так? Да, возможно, но как только мы перейдем в другой каталог и вызовем скрипт, используя его полное или относительное имя пути, переменная PWD
(или команда pwd
) внутри скрипта вернет каталог, в котором мы находились в момент запуска скрипта. Давайте проверим это:
Здесь мы видим, что pwd
(или переменная $PWD
)) всегда возвращает реальный текущий путь.
Это может быть проблемой: мы можем захотеть запустить подскрипт или получить доступ к файлу из того же каталога (или его подкаталога), в котором находился скрипт. Это часто случается с более сложными сценариями Bash, которые вызывают несколько подскриптов и/или файлов данных и конфигурации.
Каков же единый способ получения пути, с которого был запущен скрипт?
Можно рассмотреть вариант использования команды dirname "\$0"
:
$ cat test2.sh
#!/bin/bash
echo "\$0"
dirname "\$0"
Dirname выдает - относительное - имя каталога любого переданного ему аргумента, и в данном случае это [$0](https://coderoad.ru/29258603/Что-означает-0-1-2-в-скрипте-shell "$0") - специальная переменная, которая устанавливается при запуске скрипта на имя скрипта в том виде, в котором он был запущен. Давайте проверим это:
$ ./test2.sh
./test2.sh
.
$ cd test
$ ../test2.sh
../test2.sh
..
Уже лучше, я полагаю, это может немного помочь (в основном, чтобы получить представление), но это все еще не дает нам полного действительного имени пути. Для этого мы можем обернуть dirname
вдвойную оболочку ($()
) в сочетании с актуальным полным именем, полученным в результате выполнения pwd
:
$ cat make_it_work.sh
#!/bin/bash
MY_PATH="$(cd "$(dirname "\$0")" && pwd)"
echo "${MY_PATH}"
Так. Посмотрим, а работает ли:
$ ./make_it_work.sh
/home/yodo/
Пока все хорошо, но работает ли, если запустить из подкаталога?
Да!
Сначала мы переходим в test
и проверяем, что находимся в нём же, если команда change directory (cd
) была успешной (в соответствии с инструкциями &&
).
В обоих случаях - независимо от того, вызывается ли скрипт в относительном виде (../make_it_work.sh
) или с полным именем пути (/home/yodo/make_it_work.sh
), в результате мы видим каталог, из которого был запущен скрипт (/home/yodo), а не фактический текущий рабочий каталог, или pwd (/home/yodo).
В итоге, вы можете использовать однострочный скрипт MY_PATH="$(cd "$(dirname "\$0")" && pwd)"
для получения правильного, полностью определенного имени каталога из ваших скриптов. Можно даже добавить относительный путь после получения пути нахождения скрипта, например: ${MY_PATH}/include/mysubscript.sh
и даже ${MY_PATH}/../one_dir_up_file.txt
и т.д.
Пример 2: Ищем только то, что нужно
Вы когда-нибудь использовали grep
? Grep - это универсальная утилита командной строки Bash, которая позволяет легко выбрать текст из файла. Чаще всего она используется следующим образом:
$ cat test
line 1 my line
line 2 your lines
line 3 our line
$ grep 'line 2' test
line 2 your lines
У нас есть входной файл с 3 строками, и мы ищем определенный текст ( строка 2 ) в этом файле. Но как быть, если вам нужны только те строки
, в которых упоминается кратное строке число? А если вам нужно только слово перед ним, включая кусок строки
, но не выводить саму строку x
?
В этом случае мы можем искать только то, что нам нужно, используя флаг -o
('only') для grep:
$ grep -o 'lines' test
lines
$ grep -o '\w\+ lines' test
your lines
Эврика! Сначала мы искали только слово 'lines', и оно было найдено. Затем мы добавили к нему пробел и регулярное выражение, которое в псевдокоде гласит: найди строку, где слово оканчивается (\w
) и после него (\+
) идёт lines
. В результате строка с Your
( у слова пробелы(границы) перед ним и после) включена. А вот line 2
не включена. Хоть слово и оканчивается, но после не следует lines
.
Заключение
Заключение
В этой статье мы изучили pwd
и рассмотрели, как использовать pwd
внутри скрипта в сочетании с dirname
для получения полного пути к каталогу, из которого был запущен скрипт, таким образом, чтобы он всегда работал. Мы также рассмотрели поиск только того, что нам нужно, используя флаг -o
и, в данном случае, регулярное выражение для поиска границ слов.
Оставляйте комментарии и делитесь своими приёмами работы с оболочкой Bash!
Оригинал статьи можно найти здесь.

Sample bio text.