命令行生存指南：强制早睡
你会不会经常陷入这么一个情景：计划晚上早点睡叫，然而无奈总是一不小心玩过头了。
关机 命令行生存指南
112.245.89.200
哈哈哈这个太谐了
来自山东泰安的 Chrome 86.0|GNU/Linux 用户
2020-11-04T21:46:41.000
171.92.162.60
感觉没啥用，又不是不可以卸载。其实用下列命令也能达到这个效果<br />
<br />
systemctl poweroff —force —force<br />
<br />
上述命令，会在执行完成针对文件系统的 sync 后，强制关机。既不会向进程发 TERM 信号，使其能保存数据，也不会等待服务结束运行。
来自四川达州的 Chrome Mobile iOS 86.0|iOS 14.1 用户
2020-11-05T10:15:09.000
你会不会经常陷入这么一个情景：计划晚上早点睡叫，然而无奈总是一不小心玩过头了。
![](/data/attachment/album/202011/04/190932kgror11gnrg0c6pg.jpg)



> 
> 作为一个工程师，我们经常与命令行打交道，但除了工作用的命令，你是否尝试过让命令来替代你生活中方方面面？
> 
> 
> 为了让更多的爱好者可以用命令行作为自己的有效工具，Linux 中国特别邀请了三位作者，撰写了《命令行生存指南》，希望可以通过这个系列的文章，让你换一个视角，来看待命令行的存在。如果你想体验一下不一样的命令行，那就不妨来看看今天的《命令行生存指南》。
> 
> 
> 本次的内容为试读内容，也欢迎你针对今天的内容提出自己的意见和建议。
> 
> 
> 


### 操作概述


你会不会经常陷入这么一个情景：计划晚上早点睡叫，然而无奈总是一不小心玩过头了。你需要一种方法强制让你到时间了就要关机去睡觉了，这该怎么做呢？


Kgotobed 是一个很变态的内核模块。它会强制 Linux 在特定时间关闭，而你却毫无办法（即使你是 root 用户）。


### 概念和术语


内核模块允许 Linux 内核在运行时动态地向其中插入和删除代码。这些模块是具有独立功能的程序，可以被单独编译，但无法独立运行。模块在运行时作为内核的一部分在内核空间内运行。


### 操作实战


#### 场景一：使用 Kgotobed 强制关机




| 难度 | ★★★ |
| --- | --- |
| 演示发行版 | archlinux |
| 涉及命令 | `gotobed` |


##### 安装


在 archlinux 上要安装 `kgotobed`，首先需要安装 `dkms` 和 `linux-headers` 这两个包：



```
sudo pacman -S dkms linux-headers --noconfirm

```

然后去 github 上克隆它的源代码：



```
git clone https://github.com/nikital/kgotobed.git

```

最后我们对源代码进行手工编译： 



```
cd kgotobed/
sudo make install

```

`make install` 命令会完成以下三件事情：


1. 通过 DKMS 注册 `kgotobed.ko`
2. 安装 `gotobed` 命令到 `/usr/local/bin` 下
3. 在 systemd 中注册、启用并运行 `kgotobed.service`


##### 使用


直接运行 `gotobed` 就能看到设置的强行关机的时间：



```
[vagrant@archlinux kgotobed]$ gotobed 22:00
Current bedtime is 2018-04-13 01:00:00
Setting bedtime to 2018-04-12 22:00:00
Bedtime will be in 10 hours 32 minutes

```

不过你不能把时间调到更晚…… 



```
[vagrant@archlinux kgotobed]$ gotobed 2:00
Current bedtime is 2018-04-13 01:00:00
Error: Attempting to postpone bed time, it doesn't work like this...

```

要想调整默认时间，你需要修改 `/etc/systemd/system/kgotobed.service`。


原始的 `kgotobed.service` 内容如下所示：



```
[Unit]
Description=kgotobed: Poweroff at bedtime
After=dkms.service

[Service]
Type=oneshot
ExecStartPre=/sbin/modprobe kgotobed
Environment=TIME=01:00
ExecStart=/usr/local/bin/gotobed -f ${TIME}

[Install]
WantedBy=multi-user.target

```

我们将其中的 `TIME=01:00` 改成 `TIME=02:00` 后重启系统，再次执行 `gotobed` 可以看到时间已经修改了：



```
[vagrant@archlinux ~]$ gotobed 
Current bedtime is 2018-04-13 02:00:00
```

##### 删除 kgotobed


要逃脱强制关机的命运，几乎唯一的办法就是卸载 kgotobed 了。


我们可以在源代码目录中执行 `make uninstall` 进行卸载：



```
[vagrant@archlinux ~]$ cd kgotobed/
[vagrant@archlinux kgotobed]$ sudo make uninstall
dkms remove kgotobed/1.0 --all

-------- Uninstall Beginning --------
Module:  kgotobed
Version: 1.0
Kernel:  4.15.15-1-ARCH (x86_64)
-------------------------------------

Status: Before uninstall, this module version was ACTIVE on this kernel.

kgotobed.ko:
 - Uninstallation
   - Deleting from: /usr/lib/modules/4.15.15-1-ARCH/extra//
 - Original module
   - No original module was found for this module on this kernel.
   - Use the dkms install command to reinstall any previous module version.

depmod...........

DKMS: uninstall completed.

------------------------------
Deleting module version: 1.0
completely from the DKMS tree.
------------------------------
Done.
rm -f /usr/local/bin/gotobed
rm -f /etc/systemd/system/kgotobed.service
systemctl daemon-reload
[vagrant@archlinux kgotobed]$ 

```

### 小练习


请按照自己的需求更改强制关机的时间。

