LinuxCamp | DevOps
Обо мне: C/C++/Linux эксперт. Говорим про разработку, Linux, DevOps, сети и администрирование. Админ (реклама): @XoDefender Чат: @linuxcamp_chat Менеджер: @Spiral_Yuri Биржа: https://telega.in/c/linuxcamp_tg РКН: https://clck.ru/3RWA3C
نمایش بیشتر📈 تحلیل کانال تلگرام LinuxCamp | DevOps
کانال LinuxCamp | DevOps (@linuxcamp_tg) در بخش زبانی روسی بازیگری فعال است. در حال حاضر جامعه شامل 13 932 مشترک است و جایگاه 9 149 را در دسته فناوری و برنامهها و رتبه 47 289 را در منطقه روسيا دارد.
📊 شاخصهای مخاطب و پویایی
از زمان ایجاد در невідомо، پروژه رشد سریعی داشته و 13 932 مشترک جذب کرده است.
بر اساس آخرین دادهها در تاریخ 08 ژوئیه, 2026، کانال فعالیت پایداری دارد. در ۳۰ روز گذشته تغییر اعضا برابر -100 و در ۲۴ ساعت گذشته برابر -6 بوده و همچنان دسترسی گستردهای حفظ شده است.
- وضعیت تأیید: تأیید نشده
- نرخ تعامل (ER): میانگین تعامل مخاطب 28.83% است و در ۲۴ ساعت نخست پس از انتشار، محتوا معمولاً 11.52% واکنش نسبت به کل مشترکان کسب میکند.
- دسترسی پستها: هر پست به طور میانگین 4 023 بازدید دریافت میکند. در اولین روز معمولاً 1 608 بازدید جمعآوری میشود.
- واکنشها و تعامل: مخاطبان بهطور فعال حمایت میکنند؛ میانگین واکنش به هر پست 23 است.
- علایق موضوعی: محتوا بر موضوعات کلیدی مانند linuxcamp, ядро, linux, диск, docker تمرکز دارد.
📝 توضیح و سیاست محتوایی
نویسنده این فضا را محل بیان دیدگاههای شخصی توصیف میکند:
“Обо мне: C/C++/Linux эксперт. Говорим про разработку, Linux, DevOps, сети и администрирование.
Админ (реклама): @XoDefender
Чат: @linuxcamp_chat
Менеджер: @Spiral_Yuri
Биржа: https://telega.in/c/linuxcamp_tg
РКН: https://clck.ru/3RWA3C”
به لطف بهروزرسانیهای پرتکرار (آخرین داده در تاریخ 09 ژوئیه, 2026)، کانال همواره بهروز و دارای دسترسی بالاست. تحلیلها نشان میدهد مخاطبان بهطور فعال با محتوا تعامل دارند و آن را به نقطه اثرگذاری مهم در دسته فناوری و برنامهها تبدیل کردهاند.
$ scp user@host:/path/to/file /local/dir
Скопируем файлы с локального компьютера на удаленный хост:
$ scp /local/dir/file user@host:/remote/dir
Скопируем файл с одного удаленного хоста на другой:
$ scp user1@host1:/remote/file user2@host2:/remote/dir
Прога sftp не требует постоянно указывать адрес ssh сервера. Вместо этого мы подключаемся к нему один раз и используем интерфейс get и put:
$ sftp user@host
sftp> get /remote/dir/file /local/dir
sftp> put /local/dir/file /remote/dir
Для передачи каталогов используем флаг "-r":
$ scp -r /local/dir user@host:/remote/dir
$ sftp> put -r /local/dir /remote/dir
Также хочется отметить, что sftp имеет важное преимущество перед обычным ftp — она не требует, чтобы на удаленном узле работал сервер FTP. Ей необходим только SSH.
LinuxCamp | #microhelp
$ tr флаг SET1 [SET2]
Сетами представлены наборы символов, с которыми tr будет работать. Второй набор не всегда используется.
Команда разбирает текст посимвольно и выполняет операцию для каждого элемента отдельно.
Флаги команды tr:
1) -d (--delete): удаляет элементы из первого набора:
$ echo "Hello 123 world" | tr -d ' a-zA-Z'
123
2) -c (--complement): обработать каждый символ, который не входит в набор "SET1":
$ echo "Hello 123 world" | tr -cd 'a-zA-Z\n'
Helloworld
В примере мы удалили все символы, которые не входят в перечисление 'a-zA-Z\n';
Таким же макаром можно все буквы удалить и оставить только цифры:
$ cat customer.csv
USA,1234567890
Canada,0987654321
$ cat customer.csv | tr -cd '0-9\n'
1234567890
0987654321
3) -s (--squeeze-repeats): cжимает повторяющиеся символы из первого набора до одного:
$ echo "Hello World" | tr -s ' '
Hello World
4) -t (--truncate-set1): обрезает первый набор до длины второго:
$ echo "abcdef" | tr -t 'abcdef' '123'
123def
Если длина первого набора больше и мы не указываем флаг, каждый последующий его символ, который (по номеру > конец "SET2"), будет заменен:
$ echo "abcdef" | tr 'abcdef' '123'
123333
При своем дефолтном поведении, программа заменяет символы из "SET1" на элементы "SET2":
$ echo "Hello World" | tr 'a-z' 'A-Z'
HELLO WORLD
Команда умеет парсить шаблоны: [:upper:], [:lower:] и т.д. Детальнее можно ознакомиться в мануале:
$ echo "hello world" | tr [:lower:] [:upper:]
HELLO WORLD
Данные на вход можно получить и через файлик. Для этого мы используем перенаправление:
$ cat infile
www.baeldung.com
$ tr 'a-z' 'A-Z' < infile
WWW.BAELDUNG.COM
Измененные данные нужно куда-то записать? Правильно, перенаправляем вывод:
$ tr 'a-z' 'A-Z' < infile > outfile
LinuxCamp | #utils
$ file linuxmint-22.1-xfce-64bit.iso
linuxmint-22.1-xfce-64bit.iso: ISO 9660 CD-ROM filesystem data (DOS/MBR boot sector) ... (bootable)
В зависимости от содержимого образ может быть загрузочным и не загрузочным. Давайте из приведенного выше описания iso-шника выведем возможные способы работы с ним:
1) он представляет собой архив - его можно распаковать;
2) он содержит файловую систему ISO9660 - его можно монтировать;
Начнем с "распакоуки". Для этого можем воспользоваться утилитой 7z:
$ sudo apt install p7zip-full
$ 7z x linux*.iso -o./extract
После завершения процесса мы вольны вносить в файловую структуру свои коррективы. После правок нужно будет заново собрать установочный iso образ. Для этого есть утилитка mkisofs, которая корректно собирает ISO9660 архивы из файлов и каталогов.
Второй способ - монтировать образ и скопировать его содержимое.
В привычном для нас понимании, монтирование относится к блочным устройствам (usb, ssd, hdd), которые содержат определенную файловую систему (exFAT, ext, zfs). Такой механизм позволяет нам получить доступ к содержимому носителей.
Но вот в чем дело, iso файл не является блочным устройством и его нельзя просто так примонтировать... Ничего, есть решение - механизм loop device.
Loop device — это виртуальное блочное устройство, которое позволяет использовать обычный ресурс с файловой системой, как физический девайс. Через него можно смонтировать образ и получить доступ к его файловой системе.
Посмотреть то, какое устройство с каким ресурсом соотносится, можно через команду losetup:
$ sudo losetup -a
/dev/loop13: [64512]:2672215 (/path/to/output.iso)
Для того, чтобы создать и монтировать "loop device", используем mount:
$ sudo mount -o loop test.iso ./mnt_point
Теперь, т.к. файловая система ISO9660 является "read-only", нам нужно скопировать все содержимое образа в отдельный каталог:
$ mkdir new_mnt_point
$ cp -rT mnt_point new_mnt_point
Далее "по уму" редактируем образ и пересобираем его с помощью mkisofs:
$ sudo mkisofs -o ./new.iso -quiet -R -b boot/grub/bios.img -no-emul-boot -boot-load-size 4 -boot-info-table ./new_mnt_point
Если все сделано правильно, на выходе мы получим "bootable" образ.
LinuxCamp | #filesystem
$ ls -l
-rw-r--r-- ... dhcpcd.conf
Команда umask (встроена в оболочку) позволяет настроить те самые права, которые будут применимы по умолчанию к ресурсам при их создании.
Ранее мы затрагивали права в:
1) разница между chmod и chown;
2) файл групп /etc/group;
3) шпаргалка по правам доступа;
Немного вспомним наши права
В общем случае права доступа в UNIX разбиты на три категории: u (user), g (group), o (other).
Каждая категория имеет три типа битов, которые различны для файлов и каталогов.
Для файлов:
r (read, 4, 100) – чтение файла.
w (write, 2, 010) – изменение файла.
x (execute, 1, 001) – выполнение файла как программы.
Для каталогов:
r (read, 4, 100) – чтение списка файлов.
w (write, 2, 010) – изменение и создание файлов в каталоге.
x (execute, 1, 001) – открытие файлов в каталоге.
Когда создаётся новый ресурс, система назначает ему максимально возможные права: файлы (666 = rw-rw-rw-), каталоги (777 = rwxrwxrwx).
Как работает umask
Суть работы команды - не добавить права, а ограничивает их, убрав заданные биты доступа.
Итоговый набор бит рассчитывается довольно просто: от максимальных прав отнимается маска.
Дефолтное значение маски обычно следующее:
$ umask
0002
Поэтому права по умолчанию для файла будут:
666 - 002 = 664
-rw-rw-r--
А для каталога:
777 - 002 = 775
drwxrwxr-x
Важное замечание: с помощью маски не получится сохранить либо исключить бит выполнения "x" для файлов. Этот флаг можно обработать только для каталогов:
$ umask 010
$ mkdir newdir
$ ls -l
drwxrw-rwx ... newdir
Напомню, что права файла рассчитываются на основе адского набора "666", где выполнение уже отключено.
Формы синтаксиса umask
У команды довольно простой синтаксис и несколько способов определения маски:
$ umask опции восьмеричная_маска
$ umask опции u=права,g=права,o=права
Посмотреть текущее значение маски можно двумя способами:
$ umask
0002
$ umask -S
u=rwx,g=rwx,o=rx
Способы задания маски
Вообще, маска может определяться 4 цифрами, но первую можно опустить, т.к. она не используется:
$ umask 002
$ umask
0002
Команда umask работает с цифрами справа налево, поэтому незначащие нули можно тоже опустить, по необходимости:
$ umask 77
$ umask
0077
Маску можно задать и с помощью более традиционных обозначений:
$ umask u=rwx,g=rwx,o=
В таком формате оно, как пишется, так и понимается - работает по принципу chmod.
Мы не исключаем "rwx" для пользователя и группы, а чистим все права для "остальных" персон. Такая запись равна маске "007":
$ umask
0007
$ touch filetest
$ ls -l
-rw-rw---- ... filetest
Группы прав также можно объединять:
$ umask ug=rwx,o=rx
Или же задавать сразу для всех категорий, использовав "a" (all):
$ umask a=rwx
Также можно работать с отдельными правами. Оператором "+" или "-" можно разрешить или запретить целевое действие:
$ umask -S ug-w
u=rx,g=rx,o=rx
$ umask -S a+w
u=rwx,g=rwx,o=rwx
Можно и комбинировать два предыдущих способа. Например, разрешить пользователю все операции, а группе и остальным убрать право на чтение:
$ umask u=rwx,go-r
LinuxCamp | #utils
./live/filesystem.squashfs
И если мы "разожмем" ее через:
$ unsquashfs filesystem.squashfs
То увидим внутри что-то очень знакомое:
bin etc initrd.img lib media opt
...
Именно тут-то и сидели те самые бинари, которые изначально требовалось подменить. Дальше пазл примерно сложился, я обратно собрал всю эту иерархию в ".squashfs":
$ mksquashfs squashfs-root filesystem.squashfs
После упаковал новый iso образ, отладил багу и проработал фикс. На всякий, сразу приложу команду, которой готовил образы:
$ sudo mkisofs -o ~/Загрузки/new.iso -quiet -R -b boot/grub/bios.img -no-emul-boot -boot-load-size 4 -boot-info-table ./
В общем, вот такой интересный опыт был получен. Как вы, вообще, хотите больше поговорить о файловых системах, внутрянке iso образов, grub?
LinuxCamp | #story
$ cp ./src/file ./dest/
2) без сохранения - с указанием нового имени файла;
$ cp ./src/file ./dest/file_backup
Сразу же скину ссылку на полную информацию о команде. Далее мы рассмотрим основные кейсы.
Копирование каталога
Для копирования каталогов нужно использовать опцию "-r":
$ cp -r source destination
$ ls destination
source
Тут ме переносим весь каталог вместе с его наполнением.
Если нет полной уверенности в том, что каталог "dest" существует, можно добавить флаг "-t" для вывода предупреждения:
$ cp -rt src dest3
cp: cannot stat 'dest3': No such file or directory
Копирование в этом случае выполнено не будет и каталог не будет создан.
Копирование содержимого каталога
Для того, чтобы перенести только содержимое директории, а не ее саму, используем:
$ cp -r src no_dest
$ ls no_dest
file1 file2 file3
Но есть нюансик... Это так работает только, если no_dest ранее не существовал. Если каталог назначения существует, то в нем будет создан src.
Для того чтобы избежать такого поведения можно использовать опцию "-T":
$ cp -rT src yes_dest
ls yes_dest
file1 file2 file3
Как вариант, еще можно решить задачу использованием шаблона поиска:
$ cp src/* dest
Однако в этом случае скрытые файлы скопированы не будут. Ну и это не проблема особо:
$ cp src/* src/.* dest
Обработка существующих файлов
По умолчанию, если файл каталоге назначения уже существует, он будет перезаписан. Если вы хотите, чтобы утилита спросила вас, стоит ли его перезаписывать, используйте флаг "-i":
$ cp -i src/* dest
cp: overwrite 'dest/file1'? y
cp: overwrite 'dest/file2'? y
С помощью опции "-n" можно отключить перезапись существующих ресурсов:
$ cp -n file1 dest
Создание бэкапов
Для существующих файлов можно cделать резервную копию с помощью опции "-b". Если использовать этот флаг, то в конце названия файла резервной копии будет добавлен символ тильды "~":
$ cp -b file1 dest
$ ls dest
file1~
При использовании параметра "--backup" можно настроить имя резервной копии. Вот доступные варианты:
1) none - резервная копия не делается;
2) numbered - к имени файла будет добавляться номер;
3) simple - в конец файла будет добавлен знак "~";
4) existing - если в целевой директории уже есть бэкапы, то будет использоваться аналогичный им тип нейминга;
Чтобы использовать номер в имени бэкапа используйте:
$ cp --backup=numbered file1 dest
$ ls dest
file1.~1~
Ещё один вариант обработки существующих файлов - заменять только, если изначальный новее.
Для этого нужно использовать опцию "-u":
$ cp -u file1 dest
Копирование ссылок
По умолчанию жесткие и символические ссылки копируются как обычные файлы, сохраняя содержимое ресурса, к которому были подвязаны:
$ cp test_link links
$ ls -l links
-rw-rw-r-- 1 ... test_link
Если вы хотите, чтобы символические ссылки копировались, сохраняя свой тип, нужно использовать опцию "-P":
$ cp test_link links
$ ls -l links
lrwxrwxrwx 1 ... test2_link -> test2
Ток, пожалуйста, не забывайте проверять путь к оригиналу на корректность - в примере выше ссылка поломана.
Для жестких ссылок существует другой подход. Если вы хотите, чтобы она осталась собой после копирования, нужно использовать опцию "-l":
$ cp -l hlink hlink1
$ ls -l
-rw-rw-r-- 3 ... file
-rw-rw-r-- 3 ... hlink
-rw-rw-r-- 3 ... hlink1
Сохранение атрибутов
По умолчанию cp обновляет временные метки и атрибуты прав доступа файлов при копировании.
Иногда может возникнуть необходимость их сохранить. Для этого используем "--preserve":
$ cp --preserve=all file dest
LinuxCamp | #utils
find каталог параметры действие
Параметры - дополнительные опции, например, глубина поиска, фильтр по имени и т.д;
Действие - что будет выполнено с результатами поиска;
По синтаксису выше найдем пустые каталоги в tmp:
$ find /tmp -type d -empty -print
Детально ознакомиться с параметрами и прочей петрушкой можете по ссылке.
Поиск по типу файла
Флаг "-type" позволяет искать файлы по типу, среди которых:
1) f – простые файлы;
2) d – каталоги;
3) l – символические ссылки;
4) b – блочные устройства (dev);
5) c – символьные устройства (dev);
6) p – именованные каналы;
7) s – сокеты;
Перечисляем только каталоги:
$ find . -type d
.
./.ssh
./.cache
Поиск по размеру файла
Флаг "-size" позволяет произвести фильтрацию по размеру.
Выведем все файлы более 1 Гб (+1G):
$ find . -size +1G
./android-studio-ide-183.5692245-mac.dmg
"+" — поиск файлов больше заданного размера;
"-" — поиск файлов меньше заданного размера;
Отсутствие знака — поиск по полному совпадению с заданным размером;
Единицы измерения файлов: c (байт), k (Кбайт), M (Мбайт), G (Гбайт).
Поиск пустых файлов и каталогов
Параметр "-empty" позволяет найти пустые ресурсы:
$ find . -type d -empty
./datafiles
Не учитывать регистр при поиске
Если опция "-name" чувствительна к регистру, то "-iname" наоборот:
$ find . -name "new*"
./new test file
./newFile
$ find . -iname "new*"
./NewFile
./new test file
./newFile
Несколько каталогов
Для поиска по нескольким каталогам просто используем перечисление:
find ./dir1 ./dir2 -type f -name "*.c"
Поиск по правам доступа
Команда нам позволяет искать ресурсы по определенной маске прав, например, 0664:
$ find . -type f -perm 0664
Вместо числового представления маски можно использовать символьное для: u (user) g (group) и o (other).
Выполним поиск файлов доступных владельцу для чтения/записи:
$ find /etc -perm /u=rw
Чтобы немного въехать в суть прав доступа, можно просмотреть вот этот пост.
Ограничение глубины поиска
Если нам нужно указать максимальную глубину поиска, используем "-maxdepth".
Следующий запуск find пройдется только по самому верхнему уровню указанного каталога:
$ find /etc -maxdepth 1
Операторы
Для инвертирования шаблона либо объединения можно применять операторы: and, or, not.
Флаг "-and" обычно можно опустить, т.к. он ставится по дефолту.
Найдем файлы, которые не соответствуют шаблону:
$ find . -not -name "test*"
Либо найдем все файлы, начинающиеся на "test", но без расширения "php":
$ find . -name "test" -not -name "*.php"
Можем также объединить несколько условий и найти ресурсы, которые принадлежат "xoadmin" и имеют размер "< 100 байт":
$ find . -user xoadmin -and -size -100c -type f
Если нужно учесть принадлежность к еще какому-нибудь пользователю, используем "or":
$ find . \( -user xoadmin -or -user vasya \) -and -size -100c -type f
Действия
К команде можно добавить действия, которые будут выполнены с результатами поиска:
1) -delete: удаляет результаты поиска;
$ find . -empty -delete
2) -ls: выводит доп информацию;
3) -print: показывает полный путь к найденным файлам (стоит по умолчанию);
4) -exec: выполняет указанную команду для найденных ресурсов;
$ find . -empty -exec rm -rf {} +
Тут мы удаляем все пустые файлы и каталоги одним вызовом "rm -rf".
Можем через exec найти файлы и прочитать их:
$ find . -type f -exec cat {} \;
Вместо {} подставляется путь к файлу. Если команда оканчивается на "\;", значит она будет выполнена для каждой строки с результатом.
LinuxCamp | #utils
$ head test
Line 1
Line 2
Line 3
...
$ ls | head
adduser.conf
alsa
alternatives
...
Если в команде head не указаны флаги, то по умолчанию выводятся первые 10 строк.
Для того, чтобы ограничить вывод и просмотреть N элементов, используем параметр "-n":
$ head -n2 test
Line 1
Line 2
Параметр "-n" также можно использовать для того, чтобы вывести все содержимое, за исключением N последних строк. Для этого нужно использовать выражение вида "-n-N".
Если у нас всего 10 строк и требуется получить первые 3, сделаем:
$ head -n-7 test
Line 1
Line 2
Line 3
Без проблем можно единовременно получить вывод с нескольких файлов. Достаточно перечислить названия через пробел:
$ head -n2 test test2
==> test <==
Line 1
Line 2
==> test2 <==
Line 11
Line 12
Если вывод названий файлов и разделителей "\n" нам не нужен, используем флаг "-q":
$ head -n2 -q test test2
Line 1
Line 2
Line 11
Line 12
Команда tail печатает последние строки файла — по умолчанию также 10:
$ tail test
Line 1
Line 2
Line 3
...
Принцип использования команды tail практически аналогичен head. Если хотим ограничить вывод последними 3 строками, добавляем флаг "-n":
$ tail -n3 test
Line 8
Line 9
Line 10
Если поставить перед номером знак "+", печать начнется со строки этого номера и продолжится до конца файла:
$ tail -n+9 test
Line 9
Line 10
Обе команды вместе
Объединяйте head и tail, чтобы напечатать любой диапазон строк.
Например, чтобы вывести строки c 4 по 7, используем head для элементов "1-7" и tail для "7-4":
$ head -n7 test | tail -n4
Line 4
Line 5
Line 6
Line 7
В общем, чтобы отобразить строки от M до N, извлеките первые N строк с помощью head, затем выведите последние N-M+1 строк с помощью tail.
Чуток жизненной практики
Последнее время частенько приходится работать с патчами - накладывать их на приложения через quilt и снимать.
Нужно было наложить на утилиту только 10 патчей из 20. Для того, чтобы поработать с диапазоном, использовал команду head:
$ quilt series | head -n 10 | xargs -L1 quilt push
1) quilt series выводит список патчей в столбец;
2) head -n 10 отображает только первые 10 строк;
3) xargs -L1 quilt push выполняет команду для каждого отдельного патча;
LinuxCamp | #utils
$ ls
'test script.sh' test test_1 test_2
$ ls | grep -w test
test script.sh
test
Аналогичного результата можно добиться через регулярное выражение:
$ ls | grep "\<test\>"
test script.sh
test
"\<" — начало слова.
"test" — искомый текст.
"\>" — конец слова.
Угловые скобки должны экранироваться, иначе они будут интерпретироваться как простые символы.
Игнорировать регистр
По умолчанию, grep чувствительна к регистру, что немного мешает поиску. Проблема решается путем добавления ключа "-i" к команде:
ls | grep -i new
newFile
NewFile
Вывод файлов с совпадениями
Используйте параметр "-l", чтобы вывести не сами строки, а только пути к файлам, в которых они содержатся:
$ grep -r -l "libnma" /usr/share
/usr/share/doc/libnma-gtk4-0/copyright
Параметр "-r" отвечает за рекурсивный поиск - grep прошерстит не только 1 уровень каталога, а пойдет вглубь.
Поиск по нескольким параметрам
Для того, чтобы передать команде несколько вводных данных для определения совпадений, используется флаг "-e" перед каждым объектом поиска:
$ ls | grep -i -e new -e old
NewFile
newFile
oldFile
Эту команду система понимает, как "или-или" и выводит все вхождения указанных слов.
Использование регулярных выражений
Настоящая сила grep проявляется, когда вы переходите от сопоставления простых строк к сопоставлению шаблонов - регулярных выражений.
Выражения бывают 2 типов: basic и extended. Одна из особенностей второго типа заключается в том, что некоторые символы требуют экранирования для сохранности фич: ?, +, {, |, (, ), <, >.
Но можно обойтись просто добавлением флага "-E":
$ ls | grep -E "script|test"
1. Квадратные скобки "[]" используются, чтобы провести проверку на соответствие одному из указанных символов:
$ ls | grep "test[23]"
test2
test3
Можем указать "-" для того, чтобы использовать диапазон значений:
$ ls | grep "test[1-3]"
test2
test3
2. Каретка "^" используется для поиска строк, которые начинаются с указанного шаблона. Давайте найдем совпадение всех строк, начинающихся с заглавной буквы:
$ grep "^[A-Z]" myfile
A lot of text
Hello world
3. Знак доллара "$" означает конец строки. В результат входят только те элементы, конец которых подходит под шаблон:
$ grep "world$" myfile
Hello world
hello world
4. Точка "." обозначает любой одиночный символ, кроме новой строки. Регулярное выражение "....." обозначает любую строку, содержащую минимум 5 символов:
$ grep '.....' myfile
5. Вертикальная черта "|" выполняет роль логического оператора "ИЛИ":
$ ls | grep "script\|test"
script
test
В общем, регулярные выражения прекрасны и многообразны. Детальнее ознакомиться с ними можете по ссылке.
Экранирование
Иногда выражения приводят к неожиданным результатам.
Предположим, вы хотите найти в файле "myfile" только те строки, которые заканчиваются на ".sh".
Следующая команда выдаст неверный результат, поскольку точка — это регулярное выражение, означающее «любой символ»:
$ grep ".sh" myfile
script_name.sh
script_namesh
Чтобы обойти эту проблему, требуется экранировать спецсимвол:
$ grep "\.sh" myfile
script_name.sh
Такое решение иногда становится громоздким. К счастью, можно заставить grep забыть о регулярных выражениях и искать буквально то, что мы указываем.
Для этого используется параметр (fixed) "-F":
$ grep -F ".sh" myfile
script_name.sh
LinuxCamp | #utils