답변:
가장 좋은 방법은 이전 라이브러리를 사용하는 프로그램 / 서비스를 찾아 다시 시작하는 것입니다. 'lsof'를 사용하여 사용 된 모든 파일을 나열하고 'DEL'유형의 파일을 찾아서이를 달성 할 수 있습니다. DEL은 파일 시스템에서 파일 이름이 제거되었지만 누군가 사용하기 때문에 여전히 메모리에 갇혀 있음을 의미합니다.
전체 명령 행은 다음과 같습니다.
sudo lsof +c 0 | grep 'DEL.*lib' | awk '1 { print $1 ": " $NF }' | sort -u
재부팅해야하는 유일한 필수 이유는 새 커널입니다 (kexec를 사용하여 소프트 재부팅 할 수 있음). 자세한 내용은 https://wiki.archlinux.org/index.php/Kexec 를 참조 하십시오 .
새로운 커널 initramfs를로드하고 부팅 cmdline을 지정하십시오
kexec -l /boot/new-kernel --initrd=/boot/new-initramfs --reuse-cmdline
호출 kexec
( systemctl
적절한 종료에 사용, kexec -e
직접 실행)
systemctl kexec
kexec-load@.service
위키에 설명 된대로 a를 생성 하면 재부팅 하면 BIOS 재부팅 대신 systemd
자동으로 소프트 kexec
재부팅됩니다.
시스템화 된 서비스 이름을 제공하는 약간 개선 된 버전 :
PIDS="(lsof +c0 -n 2> /dev/null | grep 'DEL.*lib' | awk '{print $2}' | sort -u)"
for PID in $PIDS; do
systemctl status $i
done | grep '●' | awk '{print $2}' | sort -u
또는 한 줄 :
for i in $(lsof +c0 -n 2> /dev/null | grep 'DEL.*lib' | awk '{print $2}' | sort -u); do systemctl status $i; done | grep '●' | awk '{print $2}' | sort -u
몇 가지 문제가 있습니다.
systemctl daemon-reload
다른 것을 다시 시작하기 전에 실행해야합니다systemd
자체)을 다시 시작해야하는 경우 다음을 사용하여 수행 할 수 있습니다.systemctl daemon-reexec
systemctl restart dbus.service
다른 서비스를 중단하려면 dbus를 다시 시작한 후 다시 시작해야합니다.
systemd
그 자체: systemctl daemon-reexec
systemd-logind
systemd-machined
dbus
systemctl restart sshd
연결되어있는 동안 다시 시작하지 않으면 두 가지 옵션이 있습니다.
systemctl restart sshd
사용하여 일정at/cron/systemd
SSH
과 같은 다른 원격 (보안) 셸을 사용하여 다시 시작mosh
screen/tmux
서비스 SSH
재시작 과 같은 서비스도 차단 될 수 있습니다 . 가장 쉬운 방법은 서비스를 재시작하기 전에 이러한 세션을 닫는 것입니다쉬운 방법은 실행중인 커널의 버전을 디스크의 최신 커널과 비교하는 것입니다. 쉽게 할 수 있는 스크립트 를 찾았습니다 .
커널이 여러 개 설치되어 있으므로 실행중인 커널에 해당하는 커널 만 확인하도록 스크립트를 수정했습니다. 예를 들어, 현재 버전 4.9.79 및 4.14.16이 설치되어 있으므로 /boot/vmlinuz-4.14-x86_64를 확인해야합니다. 불행히도 이것은 버전 5.1 사용을 시작할 때 작동하지 않으므로 업데이트가 필요하거나 (4 x 3 대체)보다 강력한 방법을 찾아야합니다.
내 스크립트는 다음과 같습니다.
#!/bin/sh
NEXTLINE=0
FIND=""
CURRENT_KERNEL=`uname -r`
KERNEL_PATH="/boot/vmlinuz-${CURRENT_KERNEL:0:4}"
for I in `file $KERNEL_PATH*`; do
if [ ${NEXTLINE} -eq 1 ]; then
FIND="${I}"
NEXTLINE=0
else
if [ "${I}" = "version" ]; then NEXTLINE=1; fi
fi
done
if [ ! "${FIND}" = "" ]; then
if [ ! "${CURRENT_KERNEL}" = "${FIND}" ]; then
echo "Boot required"
else echo "No boot required"
fi
fi