我正在进行 Debian 11 测试。这是一台低端计算机,适用于计算机经验很少的用户,我希望使用不提示用户输入密码的脚本使其保持最新状态。
遵循几个主题的建议(例如这里):
所以我写了一个像这样的简单脚本/home/user/Documents/update.sh
:
#!/bin/bash
sudo apt update -y
sudo apt upgrade -y
sudo apt autoclean -y
sudo apt autoremove -y
然后我使脚本可执行:
chmod a+x /home/user/Documents/update.sh
然后我给了用户user
权限,visudo
以免询问密码
user ALL=(ALL:ALL) NOPASSWD:/home/user/Documents/update.sh, /usr/bin/apt update, /usr/bin/apt upgrade, /usr/bin/apt autoclean, /usr/bin/apt autoremove
在终端上运行命令进行测试后sh '/home/user/Documents/update.sh'
,该脚本无需输入密码即可运行。
第一次尝试在启动时使用 crontab 运行脚本:
为了在每次启动时运行脚本,我修改了crontab -u user -e
(我也直接使用测试crontab -e
):
@reboot sh '/home/user/Documents/update.sh'
但每次重新启动时:没有脚本启动。
第二次尝试使用 Gnome Tweaks 和桌面文件在启动时运行脚本:
作为替代方案,我尝试创建一个update.desktop
文件,/usr/share/applications
在其中双击启动脚本:
[Desktop Entry]
Name=update
Exec=sh '/home/user/Documents/update.sh'
Terminal=true
Type=Application
Encoding=UTF-8
测试后,双击该文件即可运行脚本,无需输入密码
然后,与侏儒调整,我在启动时将文件添加updates.desktop
为应用程序
这就是我的第二个问题出现的地方:脚本在启动时启动,但要求我输入密码。
然后我不明白为什么会发生这种情况(Gnome Tweaks 是否在另一个用户下运行,等等)。
问题 :
- 为什么 crontab 方法不起作用? (我已经启动了 crontab 服务以确保)
- 为什么 Gnome Tweak 方法提示我输入密码以及如何解决此问题?
非常感谢。
答案1
您可以做的最基本的事情是/usr/bin
在脚本中添加前缀:
#!/bin/bash
sudo /usr/bin/apt update -y
sudo /usr/bin/apt upgrade -y
sudo /usr/bin/apt autoclean -y
sudo /usr/bin/apt autoremove -y
这将起作用,因为您允许用户运行/usr/bin/apt
但不允许apt
。这实际上很好,因为它可以阻止某人调用自己的恶意程序apt
并将其放入$PATH
.但是,我建议不要这样做,因为依赖于 NOPASSWD 选项的脚本并不是最好的。
下一个最简单的解决方案可能是替换sudo
为pkexec
与桌面条目一起使用的脚本。 pkexec
是 的一部分polkit
,并且是 的 GUI 版本sudo
。它会使您的 gnome 会话变暗并提示输入密码,而不是使用终端。
#!/bin/bash
pkexec /usr/bin/apt update -y
pkexec /usr/bin/apt upgrade -y
pkexec /usr/bin/apt autoclean -y
pkexec /usr/bin/apt autoremove -y
还有一些方法可以让用户在没有交互式提示的情况下执行某些操作。您需要为此查找 polkit 规则。例如,这可以适用于/usr/share/polkit-1/actions/org.update.policy
:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE policyconfig PUBLIC
"-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
"http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
<policyconfig>
<vendor>Your name</vendor>
<action id="org.update">
<description>Update the system</description>
<message>This will run apt update/upgrade and then autoremove.</message>
<defaults>
<allow_any>yes</allow_any>
<allow_inactive>yes</allow_inactive>
<allow_active>yes</allow_active>
</defaults>
<annotate key="org.freedesktop.policykit.exec.path">/usr/bin/apt</annotate>
</action>
</policyconfig>
但是,最好的答案(特别是如果您更喜欢非交互性)是将其作为服务运行。一个简单的解决方案可能是:
#/etc/systemd/system/update.service
[Unit]
Description=Auto upgrade
After=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/bin/apt update -y
ExecStart=/usr/bin/apt upgrade -y
ExecStart=/usr/bin/apt autoclean -y
ExecStart=/usr/bin/apt autoremove -y
[Install]
WantedBy=multi-user.target
然后用于sudo systemctl enable --now update.service
运行它并为下一次启动做好准备。
apt
(至少在 Debian 发行版中)已经有类似于服务解决方案的东西: 每天触发一次并为您做一些更新apt-daily.service
。apt-daily-upgrade.service
看一眼
/etc/apt/apt.conf.d/50unattended-upgrades
以及/usr/lib/apt/apt.systed.daily
有关如何配置它来执行您想要的操作的说明。我认为这个解决方案甚至比制作您自己的服务更好,因为可能破坏您系统的边缘情况和稳定性已经由其作者解决了apt
。例如,如果自动清理会卸载libc6
,或者linux-*
此脚本将避免这种情况。
像这样的东西可能会起作用(默认情况下这些值都是 0 禁用):
# /etc/apt/apt.conf.d/10periodic
# Run 'apt update' every day
APT::Periodic::Update-Package-Lists 1
# Run 'apt-get autoclean' every 1 day
APT::Periodic::AutocleanInterval 1
# Run apt-get clean every 1 day
APT::Periodic::CleanInterval 1
# Run unattended-upgrade every 1 day
# This is similar to `apt upgrade` depending on your configuration
# (requires package 'unattended-upgrade')
# This effectively does the 'apt upgrade'
APT::Periodic::Unattended-Upgrade 1
# Run `apt autoremove` after upgrading
# This may be set in /etc/apt/apt.conf.d/50unattended-upgrades
# You might want to set this in that other file to avoid
# getting confused about what goes where
Unattended-Upgrade::Remove-Unused-Dependency "true"
答案2
请注意,这是我设置的方式无人值守升级。
Debian 软件包
我必须安装无人值守升级
sudo apt install unattended-upgrades
然后
sudo nano /etc/apt/apt.conf.d/50unattended-upgrades
修改配置文件,至少将以下几行取消注释:... "origin=Debian,codename=${distro_codename}-updates"; "origin=Debian,codename=${distro_codename}-proposed-updates"; "origin=Debian,codename=${distro_codename},label=Debian"; "origin=Debian,codename=${distro_codename},label=Debian-Security"; ... Unattended-Upgrade::AutoFixInterruptedDpkg "true"; Unattended-Upgrade::MinimalSteps "true"; ... Unattended-Upgrade::Remove-Unused-Kernel-Packages "true"; ... Unattended-Upgrade::Remove-New-Unused-Dependencies "true"; Unattended-Upgrade::Remove-Unused-Dependencies "true"; ... Unattended-Upgrade::OnlyOnACPower "false";
然后,为了在启动时启动更新(因为计算机使用的次数不多,所以可能需要安全补丁),我需要一个新服务:
sudo nano /etc/systemd/system/unattended-upgrades.service
包含:
[Unit] Description=Unattended Upgrades After=apt-daily.service apt-daily-upgrade.service apt-daily-upgrade.timer apt-get-upgrade.service [Service] ExecStart=/usr/bin/unattended-upgrade [Install] WantedBy=multi-user.target
现在,启用该服务:
systemctl enable unattended-upgrades.service
然后为了每天得到这个,我们必须运行
sudo nano /etc/apt/apt.conf.d/20auto-upgrades
并使用以下内容修改它:
APT::Periodic::Download-Upgradeable-Packages "1";
APT::Periodic::Unattended-Upgrade "1";
APT::Periodic::AutocleanInterval "1";
APT::Periodic::CleanInterval 1;
- 最后,为了在启动时得到这个(如我所愿),您必须首先使用
sudo systemctl edit apt-daily.timer
以下内容运行(定时 apt 更新服务):
[Unit]
Description=Daily apt download activities
[Timer]
OnStartupSec=20
RandomizedDelaySec=5
Persistent=true
[Install]
WantedBy=timers.target
并运行sudo systemctl edit apt-daily-upgrade.timer
以下内容:
[Unit]
Description=Daily apt upgrade and clean activities
After=apt-daily.timer
[Timer]
OnStartupSec=60
RandomizedDelaySec=10
Persistent=true
[Install]
WantedBy=timers.target
弗莱帕克
- 对于 Flatpak 来说也是如此,我们首先要运行
sudo nano /etc/systemd/system/flatpak-update.service
以下内容:
[Unit]
Description=Update Flatpak
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/bin/flatpak update --noninteractive --assumeyes
[Install]
WantedBy=multi-user.target
- 我们还必须运行
sudo nano /etc/systemd/system/flatpak-update.timer
以下内容:
[Unit]
Description=Update Flatpak
[Timer]
OnBootSec=2m
OnActiveSec=2m
OnUnitInactiveSec=24h
OnUnitActiveSec=24h
AccuracySec=1h
RandomizedDelaySec=10m
[Install]
WantedBy=timers.target
- 最后,我们必须连续运行:
systemctl enable flatpak-update.service
systemctl enable flatpak-update.timer
systemctl start flatpak-update.service
systemctl start flatpak-update.timer
感谢Stewart,所有帮助我的成员,还有ChatGPT!