在 Ubuntu 中注销/重启/关闭时执行脚本

Dir*_*Dan 37 reboot shutdown scripts logout

我想.sh在注销和关闭 Ubuntu 时使用 bash运行一个文件。我在网上上下搜索,只找到了 KDE 和 GNOME 的修复程序。脚本很简单,我只需要知道是否可以将代码行添加到“注销/关闭”文件中,或者是否需要在另一个脚本中引用它。

Joh*_*631 25

如何用 systemd 做到这一点

如果你在 2016 年 6 月之后发现这个帖子,Ubuntu 及其衍生产品包括 Mint 将使用 systemd 来控制系统初始化和关闭。我对旧方法有问题,因此研究了 systemd 方法。

使用 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
Run Code Online (Sandbox Code Playgroud)

然后我以 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
Run Code Online (Sandbox Code Playgroud)

[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
Run Code Online (Sandbox Code Playgroud)

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

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

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


CLI(命令行)版本

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

使用第一行创建启动和关闭 shell 脚本,#!/bin/sh并使用chmod +x my_new_filename.

如上所述创建两个文件,或者在本示例中创建一个文件来处理启动和关闭任务。我将在我的主目录中执行脚本,但 @don_crissti 在 Stack Exchange 上展示了一些替代方案。

svim /etc/systemd/system/start_and_stop.service
Run Code Online (Sandbox Code Playgroud)

并复制文件内容:

[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
Run Code Online (Sandbox Code Playgroud)

然后使用以下命令启用服务

systemctl enable start_and_stop
Run Code Online (Sandbox Code Playgroud)

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


更改关机的触发条件

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

这个文件是由@Matthias 在 Unix 和 Linux 上的一个答案中提出的,但我无法让它运行,直到我添加了一个安装部分。

再次编辑脚本/etc/systemd/service/并使用systemctl enable your_file_name. 当我更改目标时,我使用了该systemclt 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
Run Code Online (Sandbox Code Playgroud)

调试

我最近(2020 年)做了一些发行版跳跃,首先是 KDE Neon,在那里我发现虽然 KDE 的内存很轻,但它的 CPU 使用率比 mint 高得多,然后是 Fedora 33 XFCE。

对于第二个,这些脚本都不起作用。所以我按照提示使用systemctl statusjournalctl -xe找到了问题。原来有些东西没有权限在我的主目录中运行脚本。我尝试不成功,直到我将调用更改为:

ExecStart=/usr/bin/bash /home/john/.scopening_atstart
Run Code Online (Sandbox Code Playgroud)

这可能会帮助某人;但请注意,您的系统可能正在使用,/bin/bash因此请检查您的文件名和路径。

  • 根据`man systemd.unit`用户创建的文件可以放在`$XDG_CONFIG_HOME/systemd/user`等本地用户位置 (2认同)

Rad*_*anu 21

要在注销时执行脚本:

  1. /etc/lightdm/lightdm.conf文件中添加以下行:

    session-cleanup-script=/path/to/script
    
    Run Code Online (Sandbox Code Playgroud)
  2. 您必须重新启动 LightDM 才能使此更改生效。要使用做到这一点走在TTY1 Ctrl+ Alt+ F1,登录与您的用户名和密码,运行以下命令:

    sudo service lightdm restart
    
    Run Code Online (Sandbox Code Playgroud)
  • 注:使用Ctrl+ Alt+F7切换到图形会话。

要在重新启动时执行脚本:

  1. 将您的脚本放入/etc/rc0.d.

  2. 使其可执行:

    sudo chmod +x K99_script
    
    Run Code Online (Sandbox Code Playgroud)
  • 笔记:
    • 此目录中的脚本按字母顺序执行。
    • 脚本的名称必须K99以在正确的时间运行。

在关机时执行脚本:

  1. 将您的脚本放入/etc/rc6.d.

  2. 使其可执行:

    sudo chmod +x K99_script
    
    Run Code Online (Sandbox Code Playgroud)
  • 笔记:
    • 此目录中的脚本按字母顺序执行。
    • 脚本的名称必须K99以在正确的时间运行。

资料来源:

  • [传统](http://www.tldp.org/HOWTO/HighQuality-Apps-HOWTO/boot.html#boot.subs) 以`K` 开头的'Kill' 和`S` 开头的脚本命名为'Start '。 (6认同)
  • 这是非常错误的:i) 运行级别 0、1 和 6 的脚本名称需要以“K”开头,运行级别 2、3、4 和 5 的脚本名称需要以“S”开头;ii) 你不需要_调用脚本`K99_foo`,数字只是决定脚本运行的顺序。如果你希望它最后运行,你需要选择一个比其他的大;iii) [运行级别 0 不用于重启!](http://manpages.ubuntu.com/manpages/lucid/man7/runlevel.7.html); 是用来关机的。6 用于重启。iv) 脚本在`/etc/rcN.d` 目录中没有作用。它们应该在`/etc/init.d` 和_linked_ 到`/etc/rcN.d` 中。 (6认同)
  • 如果您想保存一些数据,K99 建议不适用于关闭/重启,因为它发生在卸载之后,并且 K 用于禁用脚本(请参阅 /etc/rcS.d/README),使用 S 启动并将其放置在卸载之前,为了启动,在挂载后放置你的脚本,因为这个错误信息,用 S 作为第一个字母解决了这个问题 (5认同)
  • 14.04 对我不起作用,是否有任何更改或未指定的重要事实? (2认同)