我想.sh
在注销和关闭 Ubuntu 时使用 bash 运行一个文件。我在网上搜索了好久,只找到了针对 KDE 和 GNOME 的修复程序。脚本很简单,我只想知道是否可以将代码行添加到“注销/关闭”文件中,或者是否需要在另一个脚本中引用它。
答案1
如何使用 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
然后我以 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 进入多用户目标时,将执行 start 服务;当退出多用户目标时,将执行 stop 服务。下面将介绍具有不同激活条件的替代服务文件。
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
并复制文件内容:
[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 行上添加或删除目标将使您能够做出更细微的区分:
这个文件是@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
调试
我最近(2020 年)进行了一些发行版切换,首先是 KDE Neon,我发现虽然 KDE 内存较少,但它的 CPU 使用率比 mint 高得多,然后是 Fedora 33 XFCE。
对于第二个,这两个脚本都不起作用。所以我按照提示使用systemctl status
和journalctl -xe
查找问题。结果发现某些东西没有权限在我的主目录中运行脚本。我尝试了但没有成功,直到我将调用更改为:
ExecStart=/usr/bin/bash /home/john/.scopening_atstart
这可能会对某些人有所帮助;但请注意,您的系统可能正在使用,/bin/bash
因此请检查您的文件名和路径。
答案2
要在注销时执行脚本:
/etc/lightdm/lightdm.conf
在文件中添加以下行:session-cleanup-script=/path/to/script
您必须重新启动 LightDM 才能使此更改生效。为此,使用Ctrl+ Alt+进入 TTY1 F1,使用您的用户名和密码登录并运行以下命令:
sudo service lightdm restart
- 注意:使用++Ctrl切换到图形会话。AltF7
要在重启时执行脚本:
将您的脚本放入
/etc/rc0.d
。使其可执行:
sudo chmod +x K99_script
- 笔记:
- 该目录中的脚本按字母顺序执行。
- 您的脚本名称必须以 开头才能
K99
在正确的时间运行。
关机时执行脚本:
将您的脚本放入
/etc/rc6.d
。使其可执行:
sudo chmod +x K99_script
- 笔记:
- 该目录中的脚本按字母顺序执行。
- 您的脚本名称必须以 开头才能
K99
在正确的时间运行。
资料来源: