关机前执行命令

关机前执行命令

我想在计算机关闭之前执行一个简单的命令(时间并不重要)。

对于启动,我可以使用 /etc/rc.local;有类似的关闭功能吗?

请注意,我仍然想使用菜单中的集成关机按钮;即我不想每次通过终端关闭时都使用自定义脚本 - 它需要是自动的。

答案1

Linux Mint 基于 Ubuntu,所以我猜测运行级别系统可能是相同的。在 Ubuntu 上,不同运行级别的脚本根据其在目录中的存在情况来执行/etc/rc[0-6].d运行级别0 对应关机,6 对应重启。

通常,脚本本身存储在 中/etc/init.d,然后将符号链接放置在与您需要的运行级别相对应的目录中。

因此,在您的情况下,编写您的脚本,将其存储在 中/etc/init.d/,然后在每个/etc/rc0.d/etc/rc6.d(如果您想要两者)中创建一个指向您的脚本的符号链接。

每个运行级别目录中的脚本将在自然顺序,因此如果运行级别内的顺序对您很重要,请相应地选择符号链接的名称。

答案2

现在 Ubuntu 变体和 Mint 已经转移到 systemd,我发现基于上述的旧解决方案不太令人满意。我在网上搜索了如何使用 systemd 来实现这一点,最终结合了其他人的智慧并将其记录为博客文章:blogspot.com.au包含以下教程。

使用 systemd,您可以创建一两个文件来使用下面的模板调用脚本,并执行几个命令。简单的。


图形化版本

第一的创建要在启动和/或关闭时运行的脚本。我创建了 .scopening_atstart 和 .scfullcopy_atend。

然后通过右键单击该文件,选择属性并确保在权限下勾选了“允许将文件作为程序执行”,确保它们都是可执行的。

我创建的两个文件填充并保存 ramdisk 的内容。他们还在我的主目录中创建一个文件来证明该服务正在运行。它们的形式如下:

#!/bin/sh
cp -pru /home/john/zRamdisk/subdirectory1/* /home/john/.wine/drive_c/subdirectory1/
rm /home/john/stop_time
date +%D' '%T > /home/john/stop_time

然后我以root身份打开文件管理器,打开/etc/systemd/system并创建了一个文件startup.service和一个文件save-ramdisk.service。显然,您可以选择自己的名称,通用名称可能包含名为 johns_start.service 的启动文件和名为 johns_shutdown.service 的关闭文件。只是不要选择现有的服务名称。

[Unit]
Description=Startup Applications

[Service]
Type=oneshot
RemainAfterExit=false
ExecStart=/home/john/.scopening_atstart

[Install]
WantedBy=multi-user.target

[Unit]
Description=Save Ramdisk to Wine drive C

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/bin/true
ExecStop=/home/john/.scfullcopy_atend

[Install]
WantedBy=multi-user.target

您可以使用相同的服务文件,将可执行脚本的完整路径替换为我的。

最后对于每一个都执行命令 systemctl enable your_files_name (但不带后缀服务)。所以我的第一个是systemctl enable startup

重新启动计算机一次即可启动服务。每当 systemd 进入多用户目标时,都会执行启动服务,而当退出多用户目标时,将会执行停止服务。下面将描述具有不同激活条件的替代服务文件。


CLI(命令行)版本

此描述假设您从主目录而不是 /home/john 进行操作,根据需要使用 sudo,并选择我编写 vim 或 svim 的编辑器。

创造第一行包含启动和关闭 shell 脚本#!/bin/sh,并使用 使其可执行chmod +x my_new_filename

创造如上所述的两个文件,或者在本示例中,一个文件用于处理启动和关闭任务。我将在我的主目录中执行脚本,但 @don_crissti 显示了一些替代方案堆栈交换

vim /etc/systemd/system/start_and_stop.service

并复制文件内容:

[Unit]
Description=Run Scripts at Start and Stop

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/home/john/.startup_commands  #your paths and filenames
ExecStop=/home/john/.shutdown_commands

[Install]
WantedBy=multi-user.target

然后启用服务使用命令:

systemctl enable start_and_stop

并重新启动系统,之后服务将处于活动状态。systemctl is-enabled start_and_stop这些命令systemctl is-active start_and_stop可用于监视您的新服务。


更改关闭的触发条件

上述文件均使用多用户环境的打开或关闭来启动脚本的运行。下面的文件使用四个潜在关闭进程的开头来启动其脚本。在 Before 行 + WantedBy 行添加或删除目标可以让您做出更精细的区分:

该文件是在第二个答案中提出的这篇文章的但在添加安装部分之前我无法让它运行。

再次编辑脚本/etc/systemd/service/并使用 启用它systemctl enable your_file_name。当我更改目标时,我使用了该systemctl disable file_name命令,然后重新启用它,将其符号链接到目标目录。重新启动,服务将运行。

[Unit]
Description=Do something required
DefaultDependencies=no
Before=shutdown.target reboot.target halt.target
# This works because it is installed in the target and will be
#   executed before the target state is entered
# Also consider kexec.target

[Service]
Type=oneshot
ExecStart=/home/john/.my_script  #your path and filename

[Install]
WantedBy=halt.target reboot.target shutdown.target

答案3

您需要使用rc.shutdownLinux 内核的关闭脚本。引用OpenBSD 手册页:

当使用reboot(8)或halt(8)命令关闭系统时,或者当init(8)收到这样做的信号时,或者当发出键盘请求的停止时(如果体系结构支持它),rc( 8) 使用参数“shutdown”调用。

因此,您只需打开 rc.shutdown 并添加您想要执行的任何 shell 命令即可。

更新:由于 Linux Mint 基于 Ubuntu,它具有不同的启动/关闭过程,因此以下是与您相关的过程:

编写您要执行的 shell 脚本并将其复制到/etc/rc*.d/.对应*于您希望脚本执行的运行级别。
Ubuntu 遵循 Debian 运行级别编号,因此运行级别 0 用于停止,运行级别 6 用于重新启动。

答案4

rc.shutdown对于 Debian Wheezy、Devuan 及其衍生版本以及其他版本中使用的基于 SysV 依赖的 init 系统,您可以模仿类似rc.local以下的行为:

将您的命令添加到以下框架中/etc/rc.shutdown

#!/bin/sh -e
#
# rc.shutdown
#

# <add your commands here, before exit 0>

exit 0

保存脚本并使文件可执行chmod a+x /etc/rc.shutdown

/etc/init.d/rc.shutdown然后,将包含以下内容的新脚本添加到您的系统:

#! /bin/sh
### BEGIN INIT INFO
# Provides:          rc.shutdown
# Required-Start:
# Required-Stop:
# X-Stop-After:      umountroot
# Default-Start:
# Default-Stop:      0 6
# Short-Description: Run /etc/rc.shutdown if it exist
### END INIT INFO


PATH=/sbin:/usr/sbin:/bin:/usr/bin

. /lib/init/vars.sh
. /lib/lsb/init-functions

do_stop() {
    if [ -x /etc/rc.shutdown ]; then
            [ "$VERBOSE" != no ] && log_begin_msg "Running local shutdown scripts (/etc/rc.shutdown)"
        /etc/rc.shutdown
        ES=$?
        [ "$VERBOSE" != no ] && log_end_msg $ES
        return $ES
    fi
}

case "$1" in
    start)
        # No-op
        ;;
    restart|reload|force-reload)
        echo "Error: argument '$1' not supported" >&2
        exit 3
        ;;
    stop|status)
    do_stop
        exit 0
        ;;
    *)
        echo "Usage: $0 start|stop" >&2
        exit 3
        ;;
esac

还要使该脚本可执行。

在 /etc/rc[06].d 中创建符号链接:

cd /etc/rc0.d ; ln -s ../init.d/rc.shutdown K01rc.shutdown

cd /etc/rc6.d ; ln -s ../init.d/rc.shutdown K01rc.shutdown

用于insserv更正符号链接并创建必要的 .depend.boot、.depend.start 和 .depend.stop 文件:

insserv -v

您需要成为 root 或使用 sudo 来执行上述所有命令。

相关内容