Инструменты пользователя

Инструменты сайта


os:linux:utils

Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

Предыдущая версия справа и слеваПредыдущая версия
Следующая версия
Предыдущая версия
os:linux:utils [13.09.2024 16:55] – [rsync] viacheslavos:linux:utils [13.05.2025 12:25] (текущий) – [curl] viacheslav
Строка 1: Строка 1:
 +===== apt =====
 +==== Работа через прокси-сервер ====
 +<file bash /etc/apt/apt.conf>
 +Acquire::http::proxy "http://username:password@proxy:3128";
 +Acquire::https::proxy "https://username:password@proxy:3128";
 +Acquire::ftp::proxy "ftp://username:password@proxy:3128";
 +</file>
 +<file bash /etc/environment>
 +http_proxy="http://username:password@proxy:3128"
 +https_proxy="https://username:password@proxy:3128"
 +ftp_proxy="ftp://username:password@proxy:3128"
 +</file>
 +
 +==== Отключить новости в apt ====
 +<code bash>
 +# News about significant security updates, features and services will
 +# appear here to raise awareness and perhaps tease /r/Linux ;)
 +# Use 'pro config set apt_news=false' to hide this and future APT news.
 +
 +pro config set apt_news=false
 +</code>
 +
 +==== Список пакетов, установленных вручную ====
 +<code bash>
 +apt list --manual-installed=true
 +</code>
 +
 +==== Информация о пакете в репозитории (ещё не установленном в системе) ====
 +<code bash>
 +apt-cache show PACKAGE_NAME
 +</code>
 +
 +==== Убрать запрос на перезапуск сервисов во время обновления ====
 +<code bash>
 +export DEBIAN_FRONTEND=noninteractive
 +apt upgrade -y
 +</code>
 +На уровне системы:
 +<file bash /etc/needrestart/needrestart.conf>
 +# Restart mode: (l)ist only, (i)nteractive or (a)utomatically.
 +#
 +# ATTENTION: If needrestart is configured to run in interactive mode but is run
 +# non-interactive (i.e. unattended-upgrades) it will fallback to list only mode.
 +#
 +#$nrconf{restart} = 'a';
 +</file>
 +<code bash>
 +sed -i '/#$nrconf{restart}/c $nrconf{restart} = '"'"'a'"'"';' /etc/needrestart/needrestart.conf
 +</code>
 +
 +==== The following packages have been kept back ====
 +После ''apt upgrade'' сообщение
 +<code>
 +The following packages have been kept back:
 +  gimp gimp-data libgegl-0.0-0 libgimp2.0
 +</code>
 +Исправить можно несколькими способами:
 +<code bash>
 +# 1. Не помечает пакеты как установленные вручную, что может привести к большему ручному вмешательству в дальнейшем.
 +sudo apt-get --with-new-pkgs upgrade <list of packages kept back>
 +# 2. В большинстве случаев это даёт пакетам всё, что нужно для дальнейшего обновления
 +sudo apt-get install <list of packages kept back>
 +# 3. Агрессивный вариант, может удалить какие-то пакеты (не рекомендуется)
 +apt dist-upgrade
 +</code>
 +https://askubuntu.com/questions/601/the-following-packages-have-been-kept-back-why-and-how-do-i-solve-it
 +
 +==== Отвечать на вопрос о замене конфигов по умолчанию (N) при обновлении ====
 +Избавиться от вопросов типа
 +<code bash>
 +10.190.113.11 Configuration file '/etc/nscd.conf'
 +10.190.113.11  ==> Modified (by you or by a script) since installation.
 +10.190.113.11  ==> Package distributor has shipped an updated version.
 +10.190.113.11    What would you like to do about it ?  Your options are:
 +10.190.113.11     Y or I  : install the package maintainer`s version
 +10.190.113.11     N or O  : keep your currently-installed version
 +10.190.113.11           : show the differences between the versions
 +10.190.113.11           : start a shell to examine the situation
 +10.190.113.11  The default action is to keep your current version.
 +10.190.113.11 *** nscd.conf (Y/I/N/O/D/Z) [default=N] ?
 +</code>
 +
 +Вариант 1
 +<code bash>
 +apt-get update
 +apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" upgrade
 +apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" dist-upgrade
 +
 +# --force-confold: do not modify the current configuration file, the new version is installed with a .dpkg-dist suffix.
 +#   With this option alone, even configuration files that you have not modified are left untouched.
 +#   You need to combine it with --force-confdef to let dpkg overwrite configuration files that you have not modified.
 +# --force-confnew: always install the new version of the configuration file, the current version is kept in a file with the .dpkg-old suffix.
 +# --force-confdef: ask dpkg to decide alone when it can and prompt otherwise. This is the default behavior of dpkg and this option is mainly useful in combination with --force-confold.
 +# --force-confmiss: ask dpkg to install the configuration file if it’s currently missing (for example because you have removed the file by mistake).
 +</code>
 +
 +Вариант 2
 +<code bash>
 +DEBIAN_FRONTEND=noninteractive apt-get upgrade
 +</code>
 +
 +https://serverfault.com/questions/527789/how-to-automate-changed-config-files-during-apt-get-upgrade-in-ubuntu-12
 +
 +==== Ubuntu Pro / ESM ====
 +Отключить уведомления типа
 +<code>
 +Get more security updates through Ubuntu Pro with 'esm-apps' enabled:
 +  vlc-plugin-qt libvlc5 vlc-data libvlccore9 vlc imagemagick vlc-bin vlc-l10n
 +  libopenexr25 libpostproc55 libmagickcore-6.q16-6-extra vlc-plugin-samba
 +  ...
 +Learn more about Ubuntu Pro at https://ubuntu.com/pro
 +</code>
 +при ''apt upgrade''.
 +
 +Третий способ.
 +<code bash>
 +# One option is to create a symbolic link for 20apt-esm-hook.conf to /dev/null:
 +sudo ln -s -f /dev/null /etc/apt/apt.conf.d/20apt-esm-hook.conf
 +# Another option is to just comment out the action lines in that file:
 +sudo sed -i'' -e 's/^\(\s\+\)\([^#]\)/\1# \2/' /etc/apt/apt.conf.d/20apt-esm-hook.conf
 +# Or a third option is to just rename that file to a .bak file, and create a zero length file of the same name:
 +sudo mv /etc/apt/apt.conf.d/20apt-esm-hook.conf /etc/apt/apt.conf.d/20apt-esm-hook.conf.bak
 +sudo touch /etc/apt/apt.conf.d/20apt-esm-hook.conf
 +</code>
 +https://askubuntu.com/questions/1434512/how-to-get-rid-of-ubuntu-pro-advertisement-when-updating-apt
 +===== awk =====
 +mawk - pattern scanning and text processing language
 +<code bash>
 +awk '/pattern/' file # Вывести строки с pattern
 +awk '/pattern/ {action; action;}' file # Выполнить действия в строках с pattern, например,
 +awk '/apple/ {print $2" "$3;}' file # если строка содержит "apple", вывести 2-ю и 3-ю колонку через пробел
 +awk '!/apple/ {print $0;}' file # если строка НЕ содержит "apple", вывести строку полностью
 +awk '{print NF;}' file # вывести кол-во столбцов в каждой строке. $NF вывел бы значение в последнем столбце
 +awk 'length > 10' file # вывести строки длиной > 10 символов
 +awk -F ':' '{print $1;}' /etc/passwd # вывести имена пользователей (разделитель ":")
 +
 +cat permissions
 +File1   User1   Read    3000
 +Dir1    Grp2    Modify  2000
 +File3   User2   Modify  1000
 +Dir3    Grp1    Read    4000
 +Dir3    Grp3    Modify  6000
 +File1   User4   FullControl     10000
 +
 +# Блок BEGIN - действия до обработки данных, END - после
 +# Вывести "Starting script" и задать счётчик в 0. Если 3-й столбец match "[Mm]odify", то увеличить счётчик. В конце вывести строку и счётчик, обработать файл permissions
 +awk 'BEGIN {print "Starting script"; count=0;} $3 ~/[Mm]odify/ {count++;} END {print "People with modify permissions:",count;}' permissions
 +Starting script
 +People with modify permissions: 3
 +
 +# Изначально i=0, если i<кол-ва столбцов в строке, то прибавить к t значение 4-го столбца, затем увеличить i на единицу.
 +# Когда будут обработаны все строки файла permissions, вывести полученное значение t.
 +awk '{for(i=0;i<NF;i++) t+=$NF} END {print t;}' permissions
 +# 3000*4=12000
 +# 12000+2000*4=20000
 +# 20000+1000*4=24000
 +# 24000+4000*4=40000
 +# 40000+6000*4=64000
 +# 64000+10000*4=104000
 +104000
 +
 +# Если 2-я колонка match [Uu]ser, а значение последней меньше 2000, то вывести строку
 +awk '$2 ~/[Uu]ser/ {if($NF>2000) print "User", $2, "has", $NF, "number which more than 2000";}' permissions
 +User User1 has 3000 number which more than 2000
 +User User4 has 10000 number which more than 2000
 +
 +</code>
 +https://habr.com/ru/company/ruvds/blog/327754/
 +===== curl =====
 +<code bash>
 +# Вывести информацию о файле
 +curl -I "https://proof.ovh.net/files/1Mb.dat"
 +HTTP/1.1 200 OK
 +Server: nginx
 +Date: Thu, 12 May 2022 14:00:33 GMT
 +Content-Type: application/octet-stream
 +Content-Length: 1048576
 +Last-Modified: Tue, 29 Jun 2021 14:44:53 GMT
 +Connection: keep-alive
 +ETag: "60db31e5-100000"
 +Accept-Ranges: bytes
 +
 +# Сохранить с именем из URL (1Mb.dat)
 +curl "https://proof.ovh.net/files/1Mb.dat" -O
 +
 +# Проверка на наличие текста в URL (вариант IF-THEN)
 +curl -s google.com |fgrep -ci "301 moved" > /dev/null && echo "True" || echo "False"
 +
 +# HTTP status code
 +http_code=$(curl -kIso /dev/null -w "%{http_code}" https://google.com)
 +</code>
 +
 +===== date =====
 +<code bash>
 +# Последнее воскресенье месяца
 +if [[ $(date -d "$date + 1week" +%d%a) =~ 0[1-7]Sun ]]
 +then
 +    echo "$date is the last Sunday of the month!"
 +fi
 +
 +date -d yesterday +'%b %d' # Вчера (мая 25)
 +date -d yesterday +%F # 2022-04-25
 +date -r file1 # дата изменения файла
 +date -u # время в UTC
 +date +%T -s "10:50:9" # изменить системное время на 10:50:09
 +date -s "15 aug 2022 14:00:00" # изменить дату и время
 +date -d@$(echo $SECONDS) -u +%T # время работы сессии bash - конвертировать из секунд в hh:mm:ss
 +# Время работы сессии bash полезно для подсчёта времени работы скрипта (конец - начало = время работы)
 +
 +# Форматирование даты
 +%F - yy-MM-dd (2022-05-26)
 +%D – Display date as mm/dd/yy
 +%Y – Year (e.g., 2020)
 +%m – Month (01-12)
 +%B – Long month name (e.g., November)
 +%b – Short month name (e.g., Nov)
 +%d – Day of month (e.g., 01)
 +%j – Day of year (001-366)
 +%u – Day of week (1-7)
 +%A – Full weekday name (e.g., Friday)
 +%a – Short weekday name (e.g., Fri)
 +%T - Время в формате 10:20:30
 +%H – Hour (00-23)
 +%I – Hour (01-12)
 +%M – Minute (00-59)
 +%S – Second (00-60)
 +</code>
 +https://unix.stackexchange.com/questions/330571/how-to-know-last-sunday-of-month\\
 +https://phoenixnap.com/kb/linux-date-command
 +===== dd =====
 +<WRAP round info 70%>
 +Лучше вообще не использовать dd, а подобрать что-то посовременнее
 +</WRAP>
 +<code bash>
 +# Сделана копия диска
 +dd if=/dev/sda conv=sync,noerror bs=8M status=progress |gzip -c > /media/nas/server.img
 +# При восстановлении на больший диск он заполняется полностью и пишет, что нет места
 +zcat /media/nas/server.img |dd of=/dev/sda conv=sync,noerror bs=8M status=progress
 +</code>
 +[[https://unix.stackexchange.com/a/566993|Пишут]], что conv=sync,noerror лучше не использовать, т. к. данные повреждаются.
 +> conv=sync will pad a short read to a full block. Don't do it when reading from a compressed stream.
 +Упоминается использование iflag=fullblock. Т. е.,
 +<code bash>
 +zcat /media/nas/server.img |dd of=/dev/sda bs=8M status=progress
 +# или
 +zcat /media/nas/server.img |dd of=/dev/sda iflag=fullblock bs=8M status=progress
 +</code>
 +https://wiki.archlinux.org/index.php/Dd#Disk_cloning_and_restore
 +
 +===== df =====
 +Показывает объём свободного места на диске.
 +<code bash>
 +# в человекочитаемых единицах
 +df -h
 +Filesystem                         Size  Used Avail Use% Mounted on
 +/dev/mapper/ubuntu--vg-ubuntu--lv   57G  8.1G   46G  16% /
 +# Показать inode
 +df -i
 +</code>
 +
 +В файловых системах **ext[234]** кол-во inode фиксированное, это можно изменить с помощью ''tune2fs'', отмонтировав диск. Если inode заканчиваются из-за того, что в ФС создано очень много файлов и папок, то больше создать ничего будет нельзя, даже если есть место. В таких ФС, как **xfs, jfs** и **btrfs** inodes выделяются автоматически, руками ничего делать не надо.
 +
 +
 +===== diff =====
 +diff - compare files line by line
 +<code bash>
 +diff file1 file2 # В каждом 3 строки, в file1 уникальная строка line3, в file2 - line4
 +3c3
 +< line3
 +---
 +> line4
 +</code>
 +
 +===== du =====
 +**d**isk **u**sage. Показывает размер файлов и каталогов.
 +<code bash>
 +# Общий размер каталога (-s) в удобных единицах (-h)
 +du -sh ~/folder
 +# -d - глубина, сортировать по убыванию с учётом человекочитаемых единиц
 +du -hd 1 /var/log |sort -rh
 +59M     /var/log
 +57M     /var/log/journal
 +932K    /var/log/installer
 +116K    /var/log/apt
 +72K     /var/log/unattended-upgrades
 +4.0K    /var/log/private
 +4.0K    /var/log/landscape
 +4.0K    /var/log/dist-upgrade
 +</code>
 +https://shapeshed.com/unix-du/
 +
 +Отфильтровать строки с ''du: cannot read directory: Permission denied''
 +<code bash>
 +du -hd 1 / 2> >(grep -v 'Permission denied') | sort -rh
 +du -cBM --max-depth=1 2> >(grep -v 'Permission denied') | sort -n 
 +</code>
 +https://stackoverflow.com/questions/15141588/exclude-all-permission-denied-messages-from-du
 +
 +Вариант с псевдографикой - ''ncdu'' ([[https://dev.yorhel.nl/ncdu/man|docs]]).
 +===== find =====
 +<code bash>
 +find /etc -name 'cron*' # найти в /etc всё, начинающееся с "cron"
 +find /etc -type f -name 'cron*' # только файлы (-type d - только каталоги)
 +find . -perm 777 # найти в текущем каталоге файлы с правами доступа 777
 +find . -perm 777 -exec chmod 555 {} \; # изменить им разрешения на 555
 +find / -mtime +1 # найти файлы с датой изменения старше суток
 +find / -atime +1 # найти файлы с датой доступа старше суток
 +find / -group www-data # файлы с владельцем-группой
 +find / -size 1MB # найти файлы размером 1 МБ
 +find /var/www -name *bxu* -exec rm -rf {} +
 +# Найти файлы .txt и .log, варианты (опция -o - это оператор OR)
 +find . -regex '.*\.\(txt\|log\)$'
 +find . -name '*.txt' -o -name '*.log'
 +# Отключить ошибки, в основном Permission denied
 +find / -name 'ddd' 2> /dev/null
 +# Удалить файлы business-* старше 14 дней в каталогах business-*
 +find "/opt/app/business-*" -name "business-*" -type f -mtime +14 -delete
 +# Создать подкаталог old, заархивировать файлы (нерекурсивно) старше вчерашнего дня, удалить оригиналы, удалить архивы старше 30 дней
 +mkdir -p /opt/archive/jfr/old
 +find /opt/archive/jfr -maxdepth 1 -daystart -mtime +1 -type f | \
 +xargs tar czf /opt/archive/jfr/old/$(date -d '-2 day' +%F-%s).tar.gz --remove-files && \
 +find /opt/archive/jfr/old -mtime +30 -delete
 +</code>
 +The command termination ''+'' instead of ''\;'' highly optimizes the exec clause by not running the rm command for each file present on the file system. It is more ubiquitous, being specified by POSIX. ''-delete'' is from FreeBSD from 1996, not added to GNU find until 2004, ''-exec cmd {} +'' is from SysV in 80s, standardised by POSIX in 1992, added to GNU ''find'' in 2005. [[https://unix.stackexchange.com/questions/167823/finds-exec-rm-vs-delete]]
 +
 +===== grep =====
 +<code bash>
 +grep ^hello file1 # обычный grep понимает регулярки
 +grep [1-9] file1 # найти цифры с 1 по 9
 +grep [a-f] file1 # буквы с a до f
 +grep -f expression1 file1 # взять запрос из файла expression1
 +grep -lr cron /etc # вывести имена файлов, содержащих в себе слово "cron" (-r - recursive)
 +tail -f /var/log/haproxy.log |egrep -iv '(mail|cache)' # исключить несколько слов
 +grep -Rnw '/path/to/somewhere/' -e 'pattern' # поиск файлов, содержащих текст pattern
 +</code>
 +https://stackoverflow.com/questions/16956810/how-to-find-all-files-containing-a-specific-text-string-on-linux
 +
 +===== gzip =====
 +pigz - многопоточный gzip. Умеет также работать с zip и zlib (.zz).
 +<code bash>
 +# Не удалять оригинал, максимальное сжатие, использовать 4 потока
 +pigz -k -9 -p4 archlinux.iso
 +# Показать содержимое архива
 +pigz -l archlinux.iso.gz
 +# Сжать в zip
 +pigz -k -K archlinux.iso
 +# Сжатие каталогов, 2 варианта (-I = --use-compress-program=)
 +tar cf - Pictures/ | pigz > pictures.tar.gz
 +tar -I pigz -cf yourfile.tar.gz folder1 folder2
 +# Распаковать
 +pigz -d archlinux.iso.gz
 +</code>
 +https://ostechnix.com/pigz-compress-and-decompress-files-in-parallel-in-linux/
 +===== hdparm =====
 +hdparm - get/set hard disk parameters
 +
 +Можно померить скорость чтения
 +<code bash>
 +sudo hdparm -t --direct /dev/sda1
 +
 +/dev/sda1:
 + Timing O_DIRECT disk reads: 716 MB in  3.00 seconds = 238.57 MB/sec
 +</code>
 +
 +===== kill =====
 +''kill'' - сигнал завершения процесса (по умолчанию SIGTERM). Список доступных сигналов: ''man 7 signal''
 +
 +===== logrotate =====
 +<code bash>
 +# Посмотреть настройки для определённого лога
 +cat /etc/logrotate.d/<service_name>
 +# Тест настроек
 +logrotate -d /etc/logrotate.d/<service_name>
 +# Примерная строка для crontab, чтобы запустить logrotate
 +0 */2 * * * logrotate -f /path/to/service.conf
 +</code>
 +https://serverfault.com/questions/601131/rotate-haproxy-logs
 +
 +<code bash>
 +/var/log/service/*.log {
 +    size 2
 +    rotate 84
 +    compress
 +    missingok
 +    copytruncate
 +}
 +</code>
 +The ''rotate 84'' option is to keep a weeks worth of logs. (24/2 hour intervals = 12 logs per day, 12 * 7 = 84 .. or 1 weeks worth of logs).
 +
 +https://unix.stackexchange.com/questions/220200/logrotate-every-2-hours
 +
 +:!: Параметры вне каталогов глобальны и применяются к logrotate в целом, а не только к файлу, где они указаны!\\
 +Поэтому повторяющиеся параметры нужно писать в каждом каталоге.
 +<code bash>
 +/opt/app/tomcat/tomcat-9.0.70/BASE_app1/logs/catalina.out
 +{
 +  su admin admin # Выполнять от юзера и группы admin
 +  daily # архивировать каждый день
 +  rotate -1 # не удалять архивы
 +  olddir old # Помещать архивы в подкаталог old каталога, где лежат логи (можно ввести абсолютный путь)
 +  createolddir # если каталога olddir нет - создать
 +  compress # сжимать
 +  missingok # если лога нет - ничего страшного
 +
 +  copytruncate # Не удалять файл, а обнулить его, архивируя содержимое (чтобы процесс мог писать в него дальше)
 +  dateext # Помечать архив датой
 +  dateformat .%Y-%m-%d-%s # Формат даты, тут будет нечто вроде file-2024-08-08-1234567.1.log.gz
 +  maxsize 1G # Архивировать чаще, чем daily, если лог достиг 1 ГБ
 +}
 +
 +/opt/app/tomcat/tomcat-9.0.70/BASE_app1/logs/*.txt
 +/opt/app/tomcat/tomcat-9.0.70/BASE_app1/logs/*.log
 +{
 +  su admin admin
 +  daily
 +  rotate -1
 +  olddir old
 +  createolddir
 +  compress
 +  missingok
 +  minage 1 # Не архивировать логи новее 1 дня (там дата в названии)
 +}
 +</code>
 +
 +Стандартный конфиг для tomcat9:
 +<file bash /etc/logrotate.d/tomcat9>
 +/var/log/tomcat9/catalina.out {
 +  copytruncate
 +  weekly
 +  rotate 52
 +  compress
 +  delaycompress
 +  missingok
 +  create 640 tomcat adm
 +  su tomcat adm
 +}
 +</file>
 +===== ls =====
 +Вывод информации о файлах.
 +<code bash>
 +ls -l # в виде списка
 +</code>
 +Типы файлов в списке (1-й символ):
 +  * - Обычный файл
 +  * d Каталог
 +  * l Символическая cсылка
 +  * b Файл блочного устройства
 +  * c Файл символьного устройства
 +  * p Именованные каналы
 +  * s Сокет
 +  * n Сетевой файл
 +
 +===== lsblk =====
 +Показывает блочные устройства
 +<code bash>
 +lsblk
 +
 +NAME                      MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
 +loop0                       7:   0  55.6M  1 loop /snap/core18/2538
 +loop1                       7:   0    62M  1 loop /snap/core20/1611
 +loop2                       7:   0    62M  1 loop /snap/core20/1593
 +loop3                       7:   0 118.4M  1 loop /snap/docker/1779
 +loop4                       7:   0  67.2M  1 loop /snap/lxd/21835
 +loop5                       7:   0    47M  1 loop /snap/snapd/16292
 +loop6                       7:   0  67.8M  1 loop /snap/lxd/22753
 +loop7                       7:   0  43.6M  1 loop /snap/snapd/14978
 +sda                         8:   0    60G  0 disk
 +├─sda1                      8:1    0   1.1G  0 part /boot/efi
 +├─sda2                      8:2    0   1.5G  0 part /boot
 +└─sda3                      8:3    0  57.5G  0 part
 +  └─ubuntu--vg-ubuntu--lv 253:0    0  57.5G  0 lvm  /
 +sr0                        11:0    1  1024M  0 rom
 +</code>
 +
 +===== lsof =====
 +Вывод списка открытых файлов, сокетов и каналов.
 +<code bash>
 +COMMAND    PID  TID TASKCMD               USER   FD      TYPE             DEVICE SIZE/OFF       NODE NAME
 +systemd      1                            root  cwd       DIR              253,0     4096          2 /
 +systemd      1                            root  rtd       DIR              253,0     4096          2 /
 +systemd      1                            root  txt       REG              253,0  1620224    3540039 /usr/lib/systemd/systemd
 +systemd      1                            root  mem       REG              253,0  1369384    3539231 /usr/lib/x86_64-linux-gnu/libm-2.31.so
 +</code>
 +  - COMMAND - процесс\\
 +  - PID - идентификатор процесса\\
 +  - USER - пользователь
 +  - FD - дескриптор файла
 +    - cwd — рабочий каталог
 +    - rtd — каталог /root
 +    - txt — исполняемый файл
 +    - mem — область памяти
 +    - число — номер дескриптора файла, используемого процессом
 +    - u — файл открыт с правами RW
 +    - r — файл открыт с правами R
 +    - w — файл открыт с правами W с частичной блокировкой файла
 +    - W — файл открыт с правами W с блокировкой всего файла
 +  - TYPE — тип файла
 +    - REG — файл
 +    - DIR — каталог
 +    - FIFO — именованные каналы
 +  - DEVICE — номер устройства, на котором находится файл
 +  - SIZE/OFF — размер
 +  - NODE — номер inode, индексного дескриптора
 +  - NAME — имя файла
 +<code bash>
 +# Процессы, использующие каталог /tmp/test
 +lsof +D /tmp/test
 +COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME
 +vi      4570 root    3u   REG  253,0    12288 2621462 /tmp/test/.test.txt.swp
 +# Информация о процессе
 +lsof -p 4570
 +</code>
 +Если файл ''/tmp/test/.test.txt.swp'' удалить при работающем процессе, то ''lsof'' всё равно будет показывать файл с пометкой deleted. Если процесс завершить, то удалится дескриптор в ''/proc'' и файл исчезнет из вывода.
 +<code bash>
 +# Вывести удалённые файлы, занимающие память из-за того, что процесс не отпустил дескрипторы
 +lsof -a +L1 /tmp/test
 +</code>
 +https://linux.die.net/man/8/lsof
 +
 +===== netstat =====
 +Статистика по стеевым подключениям.
 +<code bash>
 +netstat -nap |grep ssh
 +</code>
 +http://www.opennet.ru/man.shtml?category=1&topic=netstat
 +===== printf =====
 +printf - format and print data
 +<code bash>
 +printf "Name:\t%s\nID:\t%04d\n" "User" "67"
 +Name:   User
 +ID:     0067
 +
 +today=$(date +%F)
 +time=$(date +%T)
 +printf -v d "Current user:\t%s\nDate:\t\t%s @ %s\n" $USER $today $time # d - задаваемая переменная
 +echo "$d"
 +Current user:   user
 +Date:           2022-05-27 @ 14:35:20
 +</code>
 +
 +===== ps =====
 +Список процессов.
 +<code bash>
 +ps aux | grep java
 +</code>
 +
 +===== read =====
 +Read a line from the standard input and split it into fields.
 +<code bash>
 +read -r < log.txt # Читает первую строку из файла
 +echo "$REPLY" # If no NAMEs are supplied, the line read is stored in the REPLY variable.
 +Jun  5 00:00:29 srv-mail1 postfix/smtpd[217187]: disconnect from unknown[192.168.5.3] ehlo=1 auth=0/1 rset=1 quit=1 commands=3/4
 +read -r month day time server id message  < log.txt
 +echo "$message" # any leftover words assigned to the last NAME.
 +disconnect from unknown[192.168.5.3] ehlo=1 auth=0/1 rset=1 quit=1 commands=3/4
 +echo "$server"
 +srv-mail1
 +
 +# Разделить строку на 2 части
 +$ i="v2.2.187 3826893 Very important commit, absolutely brilliant"
 +$ read -r tag description <<< $i
 +$ echo $tag
 +v2.2.187
 +$ echo $description
 +3826893 Very important commit, absolutely brilliant
 +</code>
 +[[https://stackoverflow.com/questions/10520623/how-to-split-one-string-into-multiple-variables-in-bash-shell|How to split one string into multiple variables in bash shell]]
 +===== rm =====
 +remove files or directories
 +<code bash>
 +# Удалить всё, в т. ч. файлы с точками в начале имени
 +rm -rf -- ..?* .[!.]* *
 +</code>
 +
 +===== rsync =====
 +<code bash>
 +# копировать содержимое /www с 10.1.0.9 на локальный сервер, исключая вложенный каталог
 +rsync --info=progress2 --recursive --exclude='site.domain.ru/common.site.domain.ru/data' user@10.1.0.9:/www/* /www
 +# если без звёздочки (или без /), то будет скопирован сам каталог conf.d как подпапка
 +rsync --info=progress2 --recursive user@10.1.0.9:/etc/apache2/conf.d/* /etc/apache2/conf.d
 +
 +# -a - "делать копию максимально идентичной" (разрешения, владелец, время и т. д.), также "обновляй файлы только когда надо"
 +# -c - считать контрольные суммы. Большие файлы бьются на куски, и суммы считаются для кусков.
 +# -P - прогресс
 +rsync -a -c -P <source> <dest>
 +
 +# --ignore-existing - если имя файла есть в <dest>, не копировать (больше ничего не проверяется)
 +# -u - "если два файла различны, обновлять только если у файла в <source> новее дата изменения"
 +rsync -a -P -u --ignore-existing <source> <dest>
 +</code>
 +https://linux.die.net/man/1/rsync\\
 +https://www.servers.ru/knowledge/linux-administration/how-to-copy-files-between-linux-servers-using-rsync\\
 +https://stackoverflow.com/questions/40024222/copy-with-rsync-when-files-are-different
 +
 +
 +===== sed =====
 +<code bash>
 +# Заменить test на another test
 +echo "This is a test" | sed 's/test/another test/'
 +# Заменить в файле (файл не перезаписывается)
 +sed 's/test/another test' ./myfile
 +# Ключ -e - несколько действий
 +sed -e 's/This/That/; s/test/another test/' ./myfile
 +# Ключ -f - чтение команд из файла. Содержимое файла mycommands:
 +s/This/That/
 +s/test/another test/
 +# команда:
 +sed -f mycommands myfile
 +
 +# Флаги, пишутся в конце команды (s/pattern/replacement/flags). Без флагов обрабатывается только первое совпадение.
 +# g - заменить все совпадения, число - обработать именно это совпадение,
 +# p - вывести исходную строку, w outputfile - записать результат в outputfile.
 +sed 's/test/another test/g' myfile
 +sed 's/test/another test/2' myfile
 +sed -n 's/test/another test/p' myfile # -n - вывести только совпадения
 +sed 's/test/another test/w output' myfile
 +
 +# Можно заменить разделитель для более удобного чтения
 +sed 's/\/bin\/bash/\/bin\/csh/' /etc/passwd
 +sed 's!/bin/bash!/bin/csh!' /etc/passwd
 +
 +# Фильтр, обработка диапазона строк (с 10 по 20)
 +sed '10,20s/test/another test/' myfile
 +# с 10 до конца (можно использовать регулярку)
 +sed '2,$s/test/another test/' myfile
 +# заменить только в строке, где встречается слово user
 +sed '/user/s/bash/csh/' /etc/passwd
 +
 +# удалить 3-ю строку
 +sed '3d' myfile
 +# удалить с 10 по 20
 +sed '10,20d' myfile
 +# с 10 до конца
 +sed '10,$d' myfile
 +# удаление строк по шаблону
 +sed '/test/d' myfile
 +# При удалении можно указывать несколько шаблонов.
 +# удалятся строки, где есть second и fourth и всё между ними
 +sed '/second/,/fourth/d' myfile
 +
 +# вставка текста до
 +echo "Another test" | sed 'i\First test'
 +# вставка текста после
 +echo "Another test" | sed 'a\First test' 
 +# перед 2-й строкой
 +sed '2i\This is the inserted line.' myfile
 +
 +# заменить целиком всю 3-ю строку
 +sed '3c\This is a modified line.' myfile
 +# заменить целиком все строки, где есть This is
 +sed '/This is/c This is a changed line of text.' myfile
 +
 +# замена отдельных символов на соответствующие (1 на 5 и т. д.)
 +# применяется ко всему потоку, ограничить нельзя
 +sed 'y/123/567/' myfile
 +
 +# вывести строки с их номерами
 +sed '=' myfile
 +# вывести номера строк, соответствующих шаблону
 +sed -n '/test/=' myfile
 +
 +# вставить содержимое newfile после 3-й строки myfile
 +sed '3r newfile' myfile
 +# вставлять содержимое newfile каждый раз после строки, соответствующей шаблону
 +sed '/test/r newfile' myfile
 +
 +# Заменить строки в myfile, где есть DATA, на содержимое newfile, удалить исходную строку 
 +sed '/DATA/ {
 +r newfile
 +d}' myfile
 +</code>
 +https://habr.com/ru/company/ruvds/blog/327530/
 +
 +<code bash>
 +# Заменить foo на too.
 +sed -i 's/foo/too/'
 +# Удалить 14ю строку.
 +sed -i '14d' /file
 +# Удалить строку содержащую Network или network.
 +sed -i '/[Nn]etwork/d' /file
 +# Добавить в конец файла "[mounts]" затем перенос на новую строку и "user root".
 +sed -i '$ a \\n[mounts]\nuser root' /etc/munin/config 
 +# После 14ой строки добавить "echo "graph_category logger"".
 +sed '14a\ echo \"graph_category logger\"' /etc/munin/plugins/command 
 +# Вставить в начало файла '# vim: ft=ruby' и перенос строки.
 +sed '1i # vim: ft=ruby\n'  
 +# Заменить повторяющиеся пустые строки на одну пустую строку
 +sed -e ':a;/^$/N;/\n$/{D;ba}' file.txt
 +# Конвертация переносов строк DOS (CR/LF) в Unix (LF)
 +sed 's/.$//' dosfile.txt > unixfile.txt
 +# Заменить строку string1 строкой string2
 +sed 's/string1/string2/g'
 +# Изменить строку anystring1 на anystring2
 +sed 's/\(.*\)1/\12/g'
 +# Убрать комментарии и пустые строки
 +sed '/ *#/d; /^ *$/d'
 +# Соединить строки (линии) с предшествующим \
 +sed ':a; /\\$/N; s/\\\n//; ta'
 +# Удалить предшествующие пробелы строк
 +sed 's/[ \t]*$//'
 +# Закомментировать активные метасимволы оболочки двумя кавычками
 +sed 's/\([\\`\\"$\\\\]\)/\\\1/g'
 +# Выровнять числа по правой границе
 +seq 10 | sed "s/^/      /; s/ *\(.\{7,\}\)/\1/"
 +# Напечатать 1000-ную строку
 +sed -n '1000p;1000q'
 +# Напечатать строки с 10 по 20-ую
 +sed -n '10,20p;20q'
 +# Получить title из HTML страницы
 +sed -n 's/.*<title>\(.*\)<\/title>.*/\1/ip;T;q'
 +# Убрать пустые строки из файла
 +sed '/^$/d' input.txt > output.txt
 +# Удаляем из всех .html файлов начало до тэга <pre>
 +# и от </pre> до конца файла, включая и сами тэги
 +cat *.html | sed '1,/<pre>/d; /<\/pre>/,$d' > final.file
 +</code>
 +http://najomi.org/_nix/sed
 +
 +Обучалка по sed с примерами: https://grymoire.com/Unix/Sed.html
 +
 +==== Замена абзацев ====
 +Полный ужас
 +<code bash>
 +# build.gradle.kts
 +sed -i '/val artifactStorage =/c\
 +val nexusUrl: String by project\
 +val nexusUser: String by project\
 +val nexusPass: String by project' build.gradle.kts
 +
 +sed -i '/^repositories {/,/^}/c\
 +allprojects {\
 +    repositories {\
 +        maven {\
 +            setUrl("https://nexus.example.ru/repository/project-maven/")\
 +            credentials {\
 +                username = nexusUser\
 +                password = nexusPass\
 +            }\
 +        }\
 +        maven {\
 +            setUrl("https://nexus.example.ru/repository/project-maven-ext-distr/")\
 +            credentials {\
 +                username = nexusUser\
 +                password = nexusPass\
 +            }\
 +        }\
 +        mavenLocal()\
 +    }\
 +}' build.gradle.kts
 +
 +sed -i '/val releases =/,/manager\"/c\
 +            setUrl("https://nexus.example.ru/repository/project-maven-ext-distr/")\
 +            credentials {\
 +                this.password = nexusPass\
 +                this.username = nexusUser' build.gradle.kts
 +</code>
 +
 +===== split =====
 +split - split a file into pieces
 +<code bash>
 +split -l 2 file1 # Разделить file1 на файлы, где будет по 2 строки из него
 +</code>
 +
 +===== su, sudo =====
 +''su'' - вход от другого имени.
 +<code bash>
 +# войти от учётки vasya
 +su vasya
 +# войти от учётки vasya + его переменные окружения
 +su - vasya
 +# войти под рутом
 +su
 +# запустить одну команду без полноценного входа
 +su -c 'id'
 +</code>
 +''sudo'' - расширенный вариант ''su''. Позволяет настроить доступ для каждого пользователя или группы (''/etc/sudoers''). Файл ''/etc/sudoers'' нельзя редактировать напрямую, только через редактор visudo! Visudo проверяет сделанные настройки.
 +<code bash>
 +# разрешить пользователю ''vasya'' запускать команду ''id'' от рута
 +User_Alias ADMINS = vasya
 +Cmnd_Alias ID     = /usr/bin/id
 +ADMINS     ALL    = ID
 +</code>
 +Лучше всего не редактировать сам файл ''/etc/sudoers'', а раскомментировать там строку
 +<code bash>
 +includedir /etc/sudoers.d
 +</code>
 +и описывать правила в отдельных файлах в этой папке. Например, создаём файл ''/etc/sudoers.d/vasya'', и разрешаем ему
 +<code bash>
 +# запускать команду id
 +vasya ALL=(root) NOPASSWD:/usr/bin/id
 +# или вообще входить под рутом без пароля с его переменными окружения
 +vasya ALL=(root) NOPASSWD:/usr/bin/su -
 +</code>
 +Проверить, какие команды разрешены юзеру vasya от рута
 +<code bash>
 +sudo -l
 +</code>
 +Можно вести логи, для этого в ''/etc/sudoers'' добавить
 +<code bash>
 +Defaults    logfile="/var/log/sudo.log"
 +</code>
 +Сохранять ввод и вывод команд
 +<code bash>
 +Defaults        log_output
 +Defaults        log_input
 +Defaults        iolog_dir=/var/log/sudo-io/%{user}
 +%admins         ALL=(ALL) NOPASSWD: LOG_INPUT: LOG_OUTPUT: ALL
 +</code>
 +
 +[[https://www.digitalocean.com/community/tutorials/how-to-edit-the-sudoers-file-ru|Редактирование файла Sudoers (DigitalOcean)]]
 +===== test =====
 +test - check file types and compare values
 +<code bash>
 +test -f file1 # если файл есть, возврат true
 +test -w file1 # можно ли писать в файл
 +test 1 -gt 2 && echo "true" || echo "false" # сравнение и вывод
 +false
 +[ 5 -eq 5 ]; echo $?
 +0
 +[ 5 -eq 3 ]; echo $?
 +1
 +[ "word" = "letter" ]; echo $?
 +1
 +</code>
 +
 +===== wc =====
 +Word count.
 +<code bash>
 +cat file* |wc -l # Общее кол-во строк в файлах, начинающихся с "file"
 +</code>
 +
 +===== zip / unzip =====
 +<code bash>
 +# список файлов в архиве
 +unzip -l file.zip
 +# извлечь один файл
 +unzip home/user/file.zip backend/target/file.jar > /var/www/html/file.jar
 +</code>
  

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki