Як вимкнути сервер Linux після запуску протягом 60 хвилин?


18

У мене є сервер, який зазвичай відключається з міркувань безпеки. Коли я хочу попрацювати над ним, я вмикаю його, виконую завдання і знову закриваю. Мої завдання зазвичай займають не більше 15 хвилин. Мені хотілося б запровадити механізм автоматичного відключення через 60 хвилин.

Я досліджував, як це зробити з cron, але не думаю, що це правильний спосіб, оскільки cron не враховує, коли сервер востаннє був увімкнутий. Я можу встановлювати лише періодичні зразки, але вони не враховують ці дані.

Як я міг зробити цю реалізацію?


4
Погляньте на at(разове виконання).
dirkt

14
Я цього не робив, але ваш скрипт для входу міг запустити а, sudo shutdown -h +60який би запустив лічильник зворотного відліку 60 хвилин для завершення (-halt) процесу. Якщо ви хочете скасувати це, ви могли б sudo shutdown -c (це не використовує cron)
guiverc

7
Залежно від характеру завдань, можливо, варто запустити їх всередині контейнера докера, тому вам не потрібно турбуватися про вимкнення сервера. Контейнер створений, він виконує ваші завдання, і він знищується після цього.
Вісенте Оліверт Рієра

6
Не чекайте від цього ніякої реальної користі для безпеки. Більшість уразливих місць можна експлуатувати менше ніж за секунду, тому вимкнення через годину не запобігає експлуатації. І зловмисник, який виявив уразливість, може чекати, коли ви ввімкнете машину, щоб здійснити атаку.
kasperd

2
Re: коментар @kasperd, я б перефразував це так, що вам потрібно точно такий же рівень безпеки на вашому сервері, незалежно від того, наскільки це чи мало насправді в Інтернеті. Зауважте, це сервер, тому він підключений до чогось, а це означає, що щось буде знати, коли він увімкнений - автоматичні розгортки - це не те, про що ви хвилюєтеся, це будь-які з'єднання, і ви не можете уникнути цього, так що максимальна безпека весь час є єдиний шлях.
StephenG

Відповіді:


23

Якщо ви виконуєте завдання як один і той же користувач кожен раз, ви можете просто додати в свій профіль команду вимкнення, необов'язково з опцією -P. Число означає кількість хвилин, коли команда відключення затримується. Переконайтеся, що ваш користувач має можливість виконувати команду вимкнення через sudo без пароля.

echo "sudo shutdown -P +60" >> ~/.profile

11
Час у хвилинах, а не в секундах. Спробуйте shutdown -k -P 3600vs shutdown -k -P 60( -kдрукує настінне повідомлення, але не має іншого ефекту)
sebasth

12
Але спробуйте спочатку команду, ви не хочете, щоб миттєве відключення було прив’язане до вашого профілю!
Фабіан Рьолінг

17
Я думаю, що кожен вхід в ssh спричинить новий виклик відключення. Чи буде тоді лічильник скинутий?
JoL

4
Можливо, варто також зазначити, що реєстрація не буде дозволена протягом останніх 5 хвилин, як це було зазначено на сторінці закриття.
JoL

6
Зауважте, що 60 хвилин після входу в систему не такі, як 60 хвилин після завантаження. Що робити, якщо ви завантажите машину, а потім забудете увійти?
Хаген фон Ейтцен

69

Є кілька варіантів.

  • Надайте час безпосередньо shutdown -P:

    shutdown -P +60
    

    Зауважте, що shutdown man page також вказує:

    Якщо використовується аргумент часу, за 5 хвилин до того, як система вийде з ладу, створюється / run / nologin-файл, щоб переконатися, що подальший вхід не буде дозволений.

  • Використовувати atкоманду.

  • Створіть файл системного блоку або сценарій init, який працює shutdown -P 60при запуску.

  • Використовуйте cron @rebootдля запуску команди після завантаження.

    Додати до (root) crontab:

    @reboot shutdown -P +60
    

Для останніх двох методів ви також можете використовувати sleep 3600 && shutdown -P nowаргумент часу, shutdownщоб затримати зупинку на 60 хвилин. Таким чином вхід можливий до останнього моменту перед тим, як вимкнутись.


2
Я думаю, що за допомогою sleepкоманди вам все-таки потрібно вказати час shutdown- ми хотіли б використовувати nowдля цього аргумент, якщо ми вже виконали очікування (але зауважте, що ви не отримаєте дуже багато попередження, щоб зберегти свою роботу перед ним зникає з-під тебе!).
Toby Speight

1
Хоча shutdown -P 60це працює - це не спосіб виклику команди. Відповідно до сторінки чоловіка, яку ви повинні використовувати shutdown -P +60. --- Також відключення без аргументу часу (у прикладі sleep 3600 && shutdown -P) буде затримано на одну хвилину (як shutdown -P +1). Як писав Тобі Спейт, ви, ймовірно, хочете використовувати shutdown -P now.
пабук

33

Це виглядає як проблема XY .

Мої завдання займають зазвичай не більше 15 хвилин. Я хотів би реалізувати механізм, щоб автоматично відключити його через 60 хвилин.

Якщо ви вимкнетесь через 60 хвилин, ви ризикуєте виникнути особливо складною проблемою і просто потрібно мати більше часу. Багато попередніх рішень не дозволили б затримати відключення.

Якщо завдання не є інтерактивним завданням, а натомість є сценарієм завдання, яке автоматично запускається з іншої машини, @sdkks дав чудове рішення для цього; ви дійсно повинні просто задати машині запускати потужність, як тільки сценарій і всі його завдання закінчуються.

Однак якщо ваше завдання є інтерактивним завданням, я б запропонував замість цього виявити простою.

Якщо ви виконуєте завдання в графічному інтерфейсі (X11), ви можете виявити незайняті сеанси GUI, використовуючи описаний тут підхід: запустіть команду, коли система не працює та коли знову активна

Якщо ви виконуєте завдання через термінал, ви можете виявити ввійшли користувачів за допомогою whoкоманди. Ви можете встановити cronjob, який вимикає машину, якщо whoповертає порожній результат. Зауважте, що це буде досить консервативний підхід; вона не вимкне систему, якщо ви залишили консоль підключеною, але не працює.

Якщо ви хочете бути трохи агресивнішими, а також від'єднати незайняті термінальні сеанси, ви можете поєднати попередній підхід із автоматичним відключенням простою сеансів SSH ClientAliveInterval та ClientAliveCountMax. Іншим підходом до цього, якщо у вас немає SSH, але у вас локальний термінальний сеанс, є використання терміналу в режимі очікування , поверненого wкомандою.


2
Це дуже важливий момент. Що б ви не здійснили - вам цікаво переконатися, що ви також можете скасувати закриття.
Тінь

1
Щось пішло не так, якщо він все ще працює на 60 м, тому, можливо, просто почніть знову. Це може дуже дорого хмарно. Якщо не забезпечити відключення одного разу, я повернув мені більше 4000 доларів.
mckenzm

8

Хоча попередні відповіді тут усі задовольняють вимогу до досконалості, ви також можете вимкнути живлення машини, як тільки завдання будуть виконані.

bashСценарії можуть бути trapпед, тобто певні сигнали можуть бути перехоплені і певні завдання можуть виконуватися за потреби.EXITє одним із сигналів, який може бути захоплений.

Ви зможете:

  1. Встановіть trapдля EXITсвоїх автоматизованих скриптів оболонки, що означає припинення автоматизованих завдань
  2. Встановіть trapсвій .bashrc EXIT, тобто кожен раз, коли виходите з цієї машини, вимикайте його.

Варіант №1 був би ідеальним випадком, за умови, що для ваших завдань не потрібна перевірка adhoc та ручне судження.

Варіант №2 охоплює випадки, коли ви забудете вийти з терміналу без вимкнення живлення. Однак є застереження; якщо у вас кілька відкритих декількох клем на одній машині, і ви виходите з одного з них, він все одно вимкне машину все одно. (Можна цього сценарію уникнути, але я не ускладнюватиму рішення.)

cleanup(){
    # Do some tasks before terminating
    echo oh la la, cleaning is so nice
    echo "See you later, world"
    sudo poweroff & # finally shutdown
}
trap cleanup EXIT

Це може бути наприкінці .bashrcваріанту №2, десь у верхній частині сценарію для варіанту №1.

Чому б не використовувати poweroffв кінці сценарію?

Я вважаю за краще використовувати set -eo pipefailвгорі своїх сценаріїв. Якщо трапиться якась помилка, вона мовчки не вийде; він перестане виконувати більше команд. trapвід EXITсигналу повинен охоплювати випадки , коли скрипт завершується передчасно з - за помилки.

Однак для ваших завдань це також може означати, що машина вимкнеться до їх завершення.

У мене є простий bashшаблон, який я використовую для спрощення налагодження сценаріїв; можливо, це може принести користь. Будь ласка, дивіться цю суть .


Домовились, і напевне, можливо, час відключення дня з крону. Це гальмо мертвого чоловіка.
mckenzm

@Abigail для сценарію, він повинен бути вгорі, тому що .bashrcя віддаю перевагу нижній частині, якщо щось інше замінить його. Ваше занепокоєння не здається ясним, чи можете ви поділитися прикладом фрагменту на repl.it, можливо?
sdkks

@mckenzm я не розумію. Чи можете ви поділитися зразковим кодом або більше пояснень?
sdkks

5

Розвиваючи коментар @dirkt, ви можете вставити atкоманду у свій .bashrcабо в .profileтой файл, який ваш оболонка використовує для входу для планування автоматичного відключення на 60 хвилин після входу.

Щось на зразок:

at now + 60 minutes -f /sbin/halt

Це завдання - аж atдо алеї. Ви також можете побачити atзавдання/var/spool/
sdkks

5
Я б радив не використовувати atв цьому контексті, оскільки він переживає перезавантаження. Якщо ОП повинен був увійти в систему, вимкнути його вручну, а потім знову ввійти протягом години, він би почався ще до того, як пройде година після його останнього входу, коли відбулося перше заплановане відключення.
Аарон

@Aaron це правда. Не думав про це. Наполегливість завантаження - застереження для цього рішення.
sdkks

5

Наступні запускаються commandз параметрами, і якщо вона успішно завершиться, вона негайно вимкне це поле, припускаючи, що користувач може працювати poweroff. Це може знадобитися використовувати sudo poweroff.

command --parameters && poweroff

Тоді як наступний просто запускається poweroffнегайно, коли команда припиняється:

command --parameters ; poweroff

Якщо ви вважаєте, що команді потрібен час відпочинку після завершення, запустіть

command --parameters ; sleep 3600 ; poweroff

Якщо ви думаєте, що команда може працювати за понаднормовий час, ви можете обмежити її на годину:

timeout 1h command --parameters ; poweroff

timeoutє частиною coreutilsпакету, тож ви його, мабуть, вже маєте.


3

Якщо ви дійсно стурбовані безпекою, використовуйте механічний таймер розетки на джерелі живлення. Просто встановіть його в будь-який час, коли ви хочете його відключити. Таким чином, ніхто не може віддалено увійти та відключити відключення. Вам потрібен фізичний доступ.


2
Корупція файлової системи?
Xen2050

@ Xen2050 не є проблемою для будь-якої сучасної файлової системи (журнальної).
Том

1
@Tom У вас є джерело для примусових виправдань, ніколи не спричинить пошкодження файлової системи, якщо є журнал? Звучить для мене новим, я хотів би прочитати на ньому. Принаймні, вона повинна позначати файлову систему як брудну, змушуючи fsck правильно?
Xen2050

1
У більшості випадків він повинен просто перевидати журнал і зробити це з ним. Вимкнення живлення не повинно спричиняти пошкодження файлової системи в файловій системі, що перебуває в журналі, хоча жодних гарантій немає, якщо ви не використовуєте файлову систему типу ZFS, спеціально розроблену для цього випадку.
Том

1
Перезапис журналу може не вдатися - мені було дуже складно сесію fsck пару тижнів тому після перемикання електроенергії на 1/2 секунди до машини без ДБЖ. Це використовувало ext4 з журналом; це не зовсім непереможне!
Toby Speight

2

Якщо ви знаходитесь в systemdмашині, ви можете використовувати монотонний таймер

Блок таймера /etc/systemd/system/shutdown_after_an_hour.timer

[Unit]
Description=shutdown after an hour

[Timer]
OnBootSec=1h

[Install]
WantedBy=timers.target

Блок таймера /etc/systemd/system/shutdown_after_an_hour.service:

[Unit]
Description=shutdown after an hour

[Service]
ExecStart=/sbin/poweroff --force --no-wall
Type=oneshot

Це ввімкнено через

# systemctl enable shutdown_after_an_hour.timer

Її статус (особливо скільки часу залишилось до відключення) доступний через

# systemctl list-timers shutdown_after_an_hour.timer

Він буде працювати при наступному перезавантаженні, це не корисно для systemctl startнього під час сеансу, коли він буде створений, оскільки він або не буде працювати (тому що він не був запущений під час перезавантаження), або вимкне машину відразу, якщо минула одна година. Я не знаю, який з них відбудеться насправді, я ніколи не перевіряв конкретний випадок.


1

Спробуйте помістити скрипт ( sudo shutdown -P 3600) в /etc/init.dкаталог, щоб автоматично запустити його при запуску.

Або спробуйте скористатися anacron, додавши команду у /etc/anacrontabфайл. Я також пропоную використовувати nohupперед командою, щоб бути впевненим, що команда все ще працює після виходу.


1
Залежно від дистрибутиву, воно може не виконатись, просто перебуваючи в init.d
sdkks

@sdkks, ти маєш рацію. Анакроном також можна вважати. введення скрипту в / etc / anacrontab, який також використовується з 'nohup' у випадку виходу з системи.
Савериофр

1
@Saveriofr Ви можете редагувати свою відповідь, щоб поліпшити її якість (краще, ніж розміщувати додаткову інформацію як коментар).
Ентоні Г - справедливість для Моніки

1

Використовуйте файл виходу з вашої оболонки

Якщо сервер вам потрібен лише для інтерактивних чи неінтерактивних завдань, запущених вашим UID, подумайте про те, щоб увімкнути команди відключення у ваш файл ~ / .bash_logout . Посібник GNU Bash говорить:

Коли інтерактивна оболонка входу виходить, або неінтерактивна оболонка входу виконує команду вбудованого входу, Bash зчитує та виконує команди з файлу ~ / .bash_logout, якщо він існує.

Отже, додавання "sudo poweroff" або подібного до вашого виходу у файл вимкне сервер, як тільки ви вийдете з поточного сеансу або коли неінтерактивна сесія Bash дзвонить exit. Ви також можете вибрати для використання в або передати тимчасову затримку вимикання , якщо ви хотіли б відкласти завершення роботи.

Для більш інтерактивного підходу до цього питання, ви можете помістити такі файли Bashism у свій файл виходу:

# Shutdown unless N or n is pressed within 30 seconds.
shopt -s nocasematch
read -t 30 -N 1 -p 'Shutdown now? (Y/n) '
[[ "$REPLY" =~ n ]] || sudo poweroff

Коваджі

Ви можете пам’ятати про таке рішення:

  • Це, ймовірно, буде працювати навіть під терміналом, запущеним X Windows, але, ймовірно, не буде працювати для сеансу X11, який не був запущений startxабо подібним.
  • Якщо у вас є неінтерактивні сценарії, які дзвонять exit, у вас можуть виникнути відключення, яких ви не очікуєте.
  • Ваш файл sudoers може запросити пароль, якщо ви не вказали NOPASSWDдля команд вимкнення або якщо ви не зателефонували sudo -vперед запуском команди завершення.
  • Напевно, є й інші крайові випадки, про які я ще не думав.

Коротше кажучи, ви можете розглянути, чи відповідає цей підхід вашій реальній потребі, чи краще варіант, такий як моніторинг відсутності зареєстрованих користувачів або інша альтернатива. Ваш пробіг обов'язково відрізнятиметься.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.