# 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
==== Список пакетов, установленных вручную ====
apt list --manual-installed=true
==== Информация о пакете в репозитории (ещё не установленном в системе) ====
apt-cache show PACKAGE_NAME
==== Убрать запрос на перезапуск сервисов во время обновления ====
export DEBIAN_FRONTEND=noninteractive
apt upgrade -y
На уровне системы:
sed -i '/#$nrconf{restart}/c $nrconf{restart} = '"'"'a'"'"';' /etc/needrestart/needrestart.conf
==== The following packages have been kept back ====
После ''apt upgrade'' сообщение
The following packages have been kept back:
gimp gimp-data libgegl-0.0-0 libgimp2.0
Исправить можно несколькими способами:
# 1. Не помечает пакеты как установленные вручную, что может привести к большему ручному вмешательству в дальнейшем.
sudo apt-get --with-new-pkgs upgrade
# 2. В большинстве случаев это даёт пакетам всё, что нужно для дальнейшего обновления
sudo apt-get install
# 3. Агрессивный вариант, может удалить какие-то пакеты (не рекомендуется)
apt dist-upgrade
https://askubuntu.com/questions/601/the-following-packages-have-been-kept-back-why-and-how-do-i-solve-it
==== Отвечать на вопрос о замене конфигов по умолчанию (N) при обновлении ====
Избавиться от вопросов типа
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 D : show the differences between the versions
10.190.113.11 Z : 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] ?
Вариант 1
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).
Вариант 2
DEBIAN_FRONTEND=noninteractive apt-get upgrade
https://serverfault.com/questions/527789/how-to-automate-changed-config-files-during-apt-get-upgrade-in-ubuntu-12
==== Ubuntu Pro / ESM ====
Отключить уведомления типа
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
при ''apt upgrade''.
Третий способ.
# 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
https://askubuntu.com/questions/1434512/how-to-get-rid-of-ubuntu-pro-advertisement-when-updating-apt
===== awk =====
mawk - pattern scanning and text processing language
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;i2000) 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
https://habr.com/ru/company/ruvds/blog/327754/
===== curl =====
# Вывести информацию о файле
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"
===== date =====
# Последнее воскресенье месяца
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)
https://unix.stackexchange.com/questions/330571/how-to-know-last-sunday-of-month\\
https://phoenixnap.com/kb/linux-date-command
===== dd =====
# Сделана копия диска
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
[[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. Т. е.,
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
https://wiki.archlinux.org/index.php/Dd#Disk_cloning_and_restore
===== df =====
Показывает объём свободного места на диске.
# в человекочитаемых единицах
df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/ubuntu--vg-ubuntu--lv 57G 8.1G 46G 16% /
# Показать inode
df -i
В файловых системах **ext[234]** кол-во inode фиксированное, это можно изменить с помощью ''tune2fs'', отмонтировав диск. Если inode заканчиваются из-за того, что в ФС создано очень много файлов и папок, то больше создать ничего будет нельзя, даже если есть место. В таких ФС, как **xfs, jfs** и **btrfs** inodes выделяются автоматически, руками ничего делать не надо.
===== diff =====
diff - compare files line by line
diff file1 file2 # В каждом 3 строки, в file1 уникальная строка line3, в file2 - line4
3c3
< line3
---
> line4
===== du =====
**d**isk **u**sage. Показывает размер файлов и каталогов.
# Общий размер каталога (-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
https://shapeshed.com/unix-du/
Отфильтровать строки с ''du: cannot read directory: Permission denied''
du -hd 1 / 2> >(grep -v 'Permission denied') | sort -rh
du -cBM --max-depth=1 2> >(grep -v 'Permission denied') | sort -n
https://stackoverflow.com/questions/15141588/exclude-all-permission-denied-messages-from-du
Вариант с псевдографикой - ''ncdu'' ([[https://dev.yorhel.nl/ncdu/man|docs]]).
===== find =====
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
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 =====
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
https://stackoverflow.com/questions/16956810/how-to-find-all-files-containing-a-specific-text-string-on-linux
===== gzip =====
pigz - многопоточный gzip. Умеет также работать с zip и zlib (.zz).
# Не удалять оригинал, максимальное сжатие, использовать 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
https://ostechnix.com/pigz-compress-and-decompress-files-in-parallel-in-linux/
===== hdparm =====
hdparm - get/set hard disk parameters
Можно померить скорость чтения
sudo hdparm -t --direct /dev/sda1
/dev/sda1:
Timing O_DIRECT disk reads: 716 MB in 3.00 seconds = 238.57 MB/sec
===== kill =====
''kill'' - сигнал завершения процесса (по умолчанию SIGTERM). Список доступных сигналов: ''man 7 signal''
===== logrotate =====
# Посмотреть настройки для определённого лога
cat /etc/logrotate.d/
# Тест настроек
logrotate -d /etc/logrotate.d/
# Примерная строка для crontab, чтобы запустить logrotate
0 */2 * * * logrotate -f /path/to/service.conf
https://serverfault.com/questions/601131/rotate-haproxy-logs
/var/log/service/*.log {
size 2
rotate 84
compress
missingok
copytruncate
}
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 в целом, а не только к файлу, где они указаны!\\
Поэтому повторяющиеся параметры нужно писать в каждом каталоге.
/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 дня (там дата в названии)
}
Стандартный конфиг для tomcat9:
ls -l # в виде списка
Типы файлов в списке (1-й символ):
* - Обычный файл
* d Каталог
* l Символическая cсылка
* b Файл блочного устройства
* c Файл символьного устройства
* p Именованные каналы
* s Сокет
* n Сетевой файл
===== lsblk =====
Показывает блочные устройства
lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
loop0 7:0 0 55.6M 1 loop /snap/core18/2538
loop1 7:1 0 62M 1 loop /snap/core20/1611
loop2 7:2 0 62M 1 loop /snap/core20/1593
loop3 7:3 0 118.4M 1 loop /snap/docker/1779
loop4 7:4 0 67.2M 1 loop /snap/lxd/21835
loop5 7:5 0 47M 1 loop /snap/snapd/16292
loop6 7:6 0 67.8M 1 loop /snap/lxd/22753
loop7 7:7 0 43.6M 1 loop /snap/snapd/14978
sda 8:0 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
===== lsof =====
Вывод списка открытых файлов, сокетов и каналов.
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
- 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 — имя файла
# Процессы, использующие каталог /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
Если файл ''/tmp/test/.test.txt.swp'' удалить при работающем процессе, то ''lsof'' всё равно будет показывать файл с пометкой deleted. Если процесс завершить, то удалится дескриптор в ''/proc'' и файл исчезнет из вывода.
# Вывести удалённые файлы, занимающие память из-за того, что процесс не отпустил дескрипторы
lsof -a +L1 /tmp/test
https://linux.die.net/man/8/lsof
===== netstat =====
Статистика по стеевым подключениям.
netstat -nap |grep ssh
http://www.opennet.ru/man.shtml?category=1&topic=netstat
===== printf =====
printf - format and print data
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
===== ps =====
Список процессов.
ps aux | grep java
===== read =====
Read a line from the standard input and split it into fields.
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
===== rsync =====
# копировать содержимое /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
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 =====
# Заменить 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
https://habr.com/ru/company/ruvds/blog/327530/
# Заменить 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>.*/\1/ip;T;q'
# Убрать пустые строки из файла
sed '/^$/d' input.txt > output.txt
# Удаляем из всех .html файлов начало до тэга
# и от
до конца файла, включая и сами тэги
cat *.html | sed '1,//d; /<\/pre>/,$d' > final.file
http://najomi.org/_nix/sed
Обучалка по sed с примерами: https://grymoire.com/Unix/Sed.html
===== split =====
split - split a file into pieces
split -l 2 file1 # Разделить file1 на файлы, где будет по 2 строки из него
===== su, sudo =====
''su'' - вход от другого имени.
# войти от учётки vasya
su vasya
# войти от учётки vasya + его переменные окружения
su - vasya
# войти под рутом
su
# запустить одну команду без полноценного входа
su -c 'id'
''sudo'' - расширенный вариант ''su''. Позволяет настроить доступ для каждого пользователя или группы (''/etc/sudoers''). Файл ''/etc/sudoers'' нельзя редактировать напрямую, только через редактор visudo! Visudo проверяет сделанные настройки.
# разрешить пользователю ''vasya'' запускать команду ''id'' от рута
User_Alias ADMINS = vasya
Cmnd_Alias ID = /usr/bin/id
ADMINS ALL = ID
Лучше всего не редактировать сам файл ''/etc/sudoers'', а раскомментировать там строку
includedir /etc/sudoers.d
и описывать правила в отдельных файлах в этой папке. Например, создаём файл ''/etc/sudoers.d/vasya'', и разрешаем ему
# запускать команду id
vasya ALL=(root) NOPASSWD:/usr/bin/id
# или вообще входить под рутом без пароля с его переменными окружения
vasya ALL=(root) NOPASSWD:/usr/bin/su -
Проверить, какие команды разрешены юзеру vasya от рута
sudo -l
Можно вести логи, для этого в ''/etc/sudoers'' добавить
Defaults logfile="/var/log/sudo.log"
Сохранять ввод и вывод команд
Defaults log_output
Defaults log_input
Defaults iolog_dir=/var/log/sudo-io/%{user}
%admins ALL=(ALL) NOPASSWD: LOG_INPUT: LOG_OUTPUT: ALL
[[https://www.digitalocean.com/community/tutorials/how-to-edit-the-sudoers-file-ru|Редактирование файла Sudoers (DigitalOcean)]]
===== test =====
test - check file types and compare values
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
===== wc =====
Word count.
cat file* |wc -l # Общее кол-во строк в файлах, начинающихся с "file"
===== zip / unzip =====
# список файлов в архиве
unzip -l file.zip
# извлечь один файл
unzip home/user/file.zip backend/target/file.jar > /var/www/html/file.jar