Содержание

apt

Работа через прокси-сервер

/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";
/etc/environment
http_proxy="http://username:password@proxy:3128"
https_proxy="https://username:password@proxy:3128"
ftp_proxy="ftp://username:password@proxy:3128"

Отключить новости в apt

# 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

На уровне системы:

/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';
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 <list of packages kept back>
# 2. В большинстве случаев это даёт пакетам всё, что нужно для дальнейшего обновления
sudo apt-get install <list of packages kept back>
# 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;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

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, а подобрать что-то посовременнее

# Сделана копия диска
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

Пишут, что 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

disk usage. Показывает размер файлов и каталогов.

# Общий размер каталога (-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 (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/<service_name>
# Тест настроек
logrotate -d /etc/logrotate.d/<service_name>
# Примерная строка для 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:

/etc/logrotate.d/tomcat9
/var/log/tomcat9/catalina.out {
  copytruncate
  weekly
  rotate 52
  compress
  delaycompress
  missingok
  create 640 tomcat adm
  su tomcat adm
}

ls

Вывод информации о файлах.

ls -l # в виде списка

Типы файлов в списке (1-й символ):

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
  1. COMMAND - процесс
  2. PID - идентификатор процесса
  3. USER - пользователь
  4. FD - дескриптор файла
    1. cwd — рабочий каталог
    2. rtd — каталог /root
    3. txt — исполняемый файл
    4. mem — область памяти
    5. число — номер дескриптора файла, используемого процессом
    6. u — файл открыт с правами RW
    7. r — файл открыт с правами R
    8. w — файл открыт с правами W с частичной блокировкой файла
    9. W — файл открыт с правами W с блокировкой всего файла
  5. TYPE — тип файла
    1. REG — файл
    2. DIR — каталог
    3. FIFO — именованные каналы
  6. DEVICE — номер устройства, на котором находится файл
  7. SIZE/OFF — размер
  8. NODE — номер inode, индексного дескриптора
  9. 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 <source> <dest>
 
# --ignore-existing - если имя файла есть в <dest>, не копировать (больше ничего не проверяется)
# -u - "если два файла различны, обновлять только если у файла в <source> новее дата изменения"
rsync -a -P -u --ignore-existing <source> <dest>

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>\(.*\)<\/title>.*/\1/ip;T;q'
# Убрать пустые строки из файла
sed '/^$/d' input.txt > output.txt
# Удаляем из всех .html файлов начало до тэга <pre>
# и от </pre> до конца файла, включая и сами тэги
cat *.html | sed '1,/<pre>/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

Редактирование файла 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