У меня есть старый метод уничтожения простаивающих процессов mosh-сервера, который не работает на моем новом VPS.
Вот старый метод, который я запускаю в crontab root для очистки mosh-процессов, которые простаивали более 10 дней:
for tty in `w -sf | grep -P '\d\ddays mosh-server' | cut -c 10-15`; do kill -9 `ps -o pid= -t $tty`; done
Проблема в том, что на новом VPS эти процессы не имеют TTY, поэтому я не могу сопоставить TTY и таким образом уничтожить mosh. Вот что у меня есть (кстати, новый VPS работает под управлением ядра 3.2 на Debian wheezy, старый был предыдущей версией Debian).
for loginday in `w | grep -P '\d\ddays.* mosh-server' | cut -c 34-40 | sed 's/^\([0-9]*\)\([a-zA-Z]*\).*$/\2 \1/'`; do echo $loginday; done
Я пытаюсь получить день входа в систему от 'w' и позже сопоставить его с информацией из 'ps':
ps -C mosh-server -o bsdstart
Таким образом, я мог сопоставить любые неактивные сеансы mosh-сервера, начатые в тот же день, что и вход в систему (что, вероятно, составляет 99,9% из них в дикой природе), и убить их ТАКИМ образом, используя 'ps' для получения pid.
Однако 'w' выводит день входа следующим образом:
03Oct13
Который я сократил до просто «03Oct».
И ps выводит так:
Oct 3
Вы можете видеть в приведенной выше команде sed, которая является частью, которая не работает, я пытаюсь взять «03Oct» и вывести «Oct 03» (я разберусь с нулями, когда это заработает) и Я не могу заставить себя работать внутри цикла for когда кажется, что он работает, когда я тестирую его с помощью 'echo':
echo 03Oct | sed 's/\([0-9]*\)\([a-zA-Z]*\).*/\2 \1/'
Что меняет команду sed, когда я вставляю ее в цикл for?
Еще лучше, есть ли лучший или менее хакерский способ сделать это? Учитывая, что отдельные процессы бездействующего mosh-сервера не имеют TTY в Linux 3.2, которые я могу легко сопоставить? Редактировать: Кроме того, в системах с установленным libutempter mosh-сервер запишет информацию в utmp это, как я подозреваю, было бы полезно, но я не знаю, как это сделать.
Чтобы сделать что-то более точное, чем анализ дат, вы можете посмотреть файловую систему / proc. Что-то вроде этого работает у меня на redhat:
⚡ for pid in $(pgrep mosh-server -u $USER); do if [[ $(stat -c %Y /proc/$pid) -lt $(( $(date +%s) - 36000 )) ]]; then echo "$pid is probably stale";fi; done
27831 is probably stale
38041 is probably stale
38669 is probably stale
⚡ ps fux | grep mosh
1524 2444 0.4 0.0 160352 4752 ? S 08:27 0:00 mosh-server new -c 256 -s -l LANG=en_US.UTF-8 -- bash -lc use prod
1524 27831 0.0 0.0 161648 6288 ? S Apr05 0:02 mosh-server new -c 256 -s -l LANG=en_US.UTF-8 -- bash -lc use prod
1524 38041 0.0 0.0 159696 4332 ? S Apr04 0:03 mosh-server new -c 256 -s -l LANG=en_US.UTF-8 -- bash -lc use prod
1524 38669 0.0 0.0 161276 5920 ? S Apr04 0:37 mosh-server new -c 256 -s -l LANG=en_US.UTF-8 -- bash -lc use prod
Измените эхо на kill, а 36000 - на то, что вы хотите, чтобы ваш таймаут в секундах был. Если вы хотите сделать это для всех пользователей, отбросьте -u $ USER и запустите его как root.
Ваш echo
test отличается от вашего теста цикла двумя важными способами:
Одна из причин, по которой ваш тест цикла не работает, заключается в том, что вы не учитываете пробелы. Другая причина в том, что вы используете *
квантификатор, который означает «ноль или более» и имеет эффект, что вам нужны цифры, но не совсем. Чтобы исправить это, вы можете использовать +
квантификатор, который означает «один или несколько». Мы будем использовать это для альфа-символов. Однако, поскольку вы хотите удалить ведущий ноль, мы можем немного изменить направление цифр.
Поскольку GNU sed поддерживает расширенные регулярные выражения, мы можем исключить экранирование всех этих специальных символов, а также тех, которые я добавил. Обратите внимание, однако, что -r
вариант не переносной. Кроме того, я заменяю именованный класс символов на алфавитные символы, чтобы сделать регулярное выражение более читабельным и сделать его совместимым с языками с разными наборами символов.
sed -r 's/^ *((0)|([1-9]))([0-9])([[:alpha:]]+).*$/\5 \3\4/'
Ведущий ноль фиксируется в группе 2 и отбрасывается. Группа 1 - это первая цифра двузначного числа. Группа 3 пуста, если группа 2 содержит ноль (из-за чередования, созданного с помощью символа вертикальной черты).
Так далеко как utmp
идет, делает last mosh-server
вывести что-нибудь полезное для вас (с установленной libutempter)?
Пожалуйста, также смотрите Управление процессом чтобы узнать, найдете ли вы что-нибудь полезное