如何在特定包升级后运行脚本?

如何在特定包升级后运行脚本?

我为应用程序创建了一个 systemd 服务,因为它不包含该服务,我希望能够在软件包更新时重新启动相关服务。

我怎样才能做到这一点?

答案1

据我所知,apt 没有特定于软件包的钩子(即,没有办法告诉它在修改给定软件包时运行命令)。它确实有DPkg::Pre-Install-Pkgs

Pre-Install-Pkgs
   This is a list of shell commands to run before invoking dpkg(1).
   Like options this must be specified in list notation. The commands
   are invoked in order using /bin/sh; should any fail APT will abort.

请注意,这是运行用这些包可以做任何事情。

您可以为通过 stdin 传递给命令的信息指定一个版本;信息的级别随着版本的增加而增加:

  • 版本 1 仅发送正在安装的包文件的路径
  • 版本 2 还转储

    • VERSION 2作为第一行,然后
    • 当前 Apt 配置,后跟一个空白行

    对于每个包裹,

    • 操作前后包的版本,
    • 以及操作本身,因此与版本 2 不同,
  • 版本 3 除了 (2) 中的信息外,还添加了架构信息(并VERSION 3作为第一行)

对于简单的情况,你可以使用如下脚本(例如/usr/local/bin/restart-foo):

#! /bin/bash

if grep -q my-package
then
    # schedule an at job to restart it
    at now + 30 min <<<"service restart foo"
fi

并且适当的配置如下/etc/apt/apt.conf.d/99-foo-hook

DPkg::Pre-Install-Pkgs {"/usr/local/bin/restart-foo";};
DPkg::Tools::Options::/usr/local/bin/restart-foo::Version "1";

对于更复杂的情况,您可以通过设置DPkg::Tools::Options::/usr/local/bin/restart-foo::Version"2"或来请求更多信息并进行解析,"3"如下所示:

#! /bin/bash
declare -gA version action ver_index
ver_index["VERSION 2"]=3
ver_index["VERSION 3"]=5
skip_options ()
{
    while IFS= read -r line && [[ -n "$line" ]]
    do
        :
    done
}

IFS= read line
case $line in
    "VERSION "[23])
        ver_index="${ver_index[$line]}"
        skip_options
        while read -ra pack
        do
            echo "${pack[@]}"
            version["${pack[0]}"]="${pack[$ver_index]}"
            action["${pack[0]}"]="${pack[-1]}"
        done
        ;;
    *)
        while read pack ver
        do
            version["$pack"]="$ver"
            action["$pack"]="**CONFIGURE**"
        done < <( (echo "$line"; cat ) | xargs -d '\n' dpkg-deb --show --showformat='${Package} ${Version}\n')
        ;;
esac

for i in "${!version[@]}"
do
    echo "$i" "${version[$i]}" "${action[$i]}"
done

当然,echo你不是根据数据来决定做什么,而是根据数据来决定做什么。

提供的输入示例:

V1:

/var/cache/apt/archives/tcsh_6.18.01-5_amd64.deb

V2版:

VERSION 2
APT::Architecture=amd64
APT::Build-Essential::=build-essential
APT::Install-Recommends=true
[...]
DPkg::Progress-Fancy=1
Binary=apt
CommandLine::AsString=apt%20install%20--reinstall%20tcsh

tcsh - < 6.18.01-5 /var/cache/apt/archives/tcsh_6.18.01-5_amd64.deb
tcsh - < 6.18.01-5 **CONFIGURE**

版本 3:

VERSION 3
APT::Architecture=amd64
APT::Build-Essential::=build-essential
APT::Install-Recommends=true
[...]
DPkg::Progress-Fancy=1
Binary=apt
CommandLine::AsString=apt%20install%20--reinstall%20tcsh
tcsh 6.18.01-5 amd64 none = 6.18.01-5 amd64 none /var/cache/apt/archives/tcsh_6.18.01-5_amd64.deb
tcsh 6.18.01-5 amd64 none = 6.18.01-5 amd64 none **CONFIGURE**

另一种方法是使用 dpkg 触发器。但是,为此,您需要创建一个包,该包会为您想要监视的包中的某些内容安装触发器,但触发器是在配置包后执行的,因此这对于重新启动服务更合适。这Stack Overflow 帖子对此有一个很好的指导。

相关内容