获取使用 apt 安装的原始文件和当前文件之间的差异更改

mde*_*tis 22 ubuntu diff debian apt

php5-fpm使用安装包apt;然后我对 PHP 配置文件进行了一些更改。

现在我会得到原始文件版本(安装的包的版本)和当前版本(由我修改)之间的差异。怎么做?

小智 13

尝试这样的事情:

# exit on failure
set -e

package=php5-fpm
mkdir $package
cd $package

# you could also get the file from a package mirror if you have
#  an older version of apt-get that doesn't support 'download' 
#  or if you would like more control over what package version
#  you are downloading.
# (e.g. http://archive.ubuntu.com/ubuntu/pool/main/)
apt-get download $package

# deb package files are ar archives
ar vx ${package}*.deb
# containing some compressed tar archives
tar xzf data.tar.gz
# now you have the files

# you can get diffs for all of the files in etc if you would like
find etc -type f |
while read file ; do
    diff $file /$file
done
Run Code Online (Sandbox Code Playgroud)

正如其他人所建议的那样,一定要将您的配置文件置于版本控制之下。这样,您就可以准确地看到更改的内容以及更改时间。

  • 你可以使用 `dpkg-deb -x ${package}_*.deb .` 而不是使用 `ar` 和 `tar`。此外`apt-get download $(dpkg-query -W -f='${binary:Package}=${Version}' $package)` 将确保您获取当前安装的版本而不是最新版本,例如如果您是在升级之前执行此操作。 (3认同)
  • 对于最近的 Ubuntu,`tar xzf data.tar.gz` 应该是 `tar xf data.tar.xz` (2认同)

slm*_*slm 8

等目录

要跟踪对/etc目录的更改,您可以按照@Anthon 的建议进行操作,并使用 git、subversion、mercurial 等来控制该目录的版本。您还可以使用etckeeper等工具。这里这里都有教程。

etckeeper 是一组工具,可以让 /etc 存储在 git、mercurial、bazaar 或 darcs 存储库中。它挂接到 apt 以在包升级期间自动提交对 /etc 所做的更改。它跟踪 git 通常不支持的文件元数据,但这对 /etc 很重要,例如/etc/shadow. 它非常模块化和可配置,同时如果您了解使用版本控制的基础知识,则使用起来也很简单。

包文件

据我所知apt,没有办法检查磁盘上的文件与实际.deb. 也没有dpkgapt实际用于管理文件的工具。

但是,您可以使用诸如debsums比较已安装的某些文件之类的工具,它只查看.deb文件中内容与系统磁盘上内容的校验和 (md5sum) 。

看到这个serverfault问题有关的详细信息debsumdpkg校验,以及本askubuntu问题

debsum 例子

% debsums openssh-server
/usr/lib/openssh/sftp-server                                                  OK
/usr/sbin/sshd                                                                OK
/usr/share/lintian/overrides/openssh-server                                   OK
/usr/share/man/man5/sshd_config.5.gz                                          OK
/usr/share/man/man8/sshd.8.gz                                                 OK
/usr/share/man/man8/sftp-server.8.gz                                          OK
Run Code Online (Sandbox Code Playgroud)

  • 请注意,OP 需要运行`debsums -a`,否则配置文件将被排除在检查之外。 (2认同)
  • @DmitryGrigoryev `debums -ce` 非常适合查找要查看的(配置)文件。 (2认同)

a3n*_*3nm 8

我编写了以下简单脚本来自动从正确的 Debian 包中检索原始文件并将当前文件与它进行比较:https : //a3nm.net/git/mybin/tree/debdiffconf

使用方法如下: debdiffconf FILE

#!/bin/bash

# Usage: debdiffconf.sh FILE
# Produce on stdout diff of FILE against the first installed Debian package
# found that provides it.
# Returns the exit code of diff if everything worked, 3 or 4 otherwise.

# /sf/answers/334986291/
command -v apt >/dev/null 2>&1 || {
  echo "apt not found, this is probably not a Debian system. Aborting." >&2;
  exit 4; }
command -v apt-file >/dev/null 2>&1 || {
  echo "Please install apt-file: sudo apt install apt-file. Aborting." >&2;
  exit 4; }
command -v realpath >/dev/null 2>&1 || {
  echo "Please install realpath: sudo apt install realpath. Aborting." >&2;
  exit 4; }

FILE=$(realpath -m "$1")
while read PACKAGE
do
  # verify from first installed package
  if dpkg-query -W --showformat='${Status}\n' | grep installed > /dev/null
  then
    DIR=$(mktemp -d)
    cd "$DIR"
    echo "Trying $PACKAGE..." >&2
    apt download "$PACKAGE" >&2
    # downloaded archive is the only file present...
    ARCHIVE=$(ls)
    mkdir contents
    # extract entire archive
    dpkg-deb -x "$ARCHIVE" contents/ >&2
    if [ -f "contents$FILE" ]
    then
      # package contained required file
      diff "contents$FILE" "$FILE"
      RET=$?
      # cleanup
      cd
      rm -Rf "$DIR"
      # exit entire script as this is the main shell
      # with the return code from diff
      exit $RET
    else
      # cleanup
      cd
      rm -Rf "$DIR"
    fi
  fi
done < <(apt-file -l search "$FILE")
# if we are here, it means we have found no suitable package
echo "Could not find original package for $FILE" >&2
exit 3
Run Code Online (Sandbox Code Playgroud)