.deb 패키지를 설치하고 postrm을 두 번 호출합니다.

.deb 패키지를 설치하고 postrm을 두 번 호출합니다.

아래 포함 스크립트로 작성된 기본 .deb 패키지 문제, 특히 .deb 를 통해 두 번 설치했을 때의 작업 문제를 해결하고 있습니다 dpkg -i <package-name>. postrm스크립트가 항상 호출된다는 것을 알았습니다 .

이것공식 관리자 스크립트동일한 패키지가 두 번 설치되는 것을 표시하지 않습니다. 다음 스크립트를 두 번 설치하면 와 postrm(또는 prerm구성 패키지를 사용하는 경우) 사이에 실행됩니다 .preisntpostinst

설치를 위해 이 프로세스를 다시 따라야 하는 이유는 무엇입니까? 이 프로세스가 이해가 되지 않는 것 같습니다.

  1. 프리앤스터
  2. 프리렘
  3. 후기 단계
  4. 뒤쪽

rm의 어떤 것이든 실행된다면 다음과 같을 것이라고 생각합니다:

  1. 프리렘
  2. 후기 단계
  3. 프리앤스터
  4. 뒤쪽

두 번째 실행되더라도 preinsta 가 반환 exit code 0되므로 prermor 는 실행되지 않습니다 postrm.

내 질문은: 이 상황에서 전화를 피하는 방법이 있습니까 prerm? postrm스크립트 자체가 호출되거나 prerm호출되는 방식을 결정하는 방법이 있습니까? postrm(정상 설치 중에는 호출되지 않기 때문입니다.)

유용한 경우를 대비해 스크립트는 다음과 같습니다.

#!/bin/bash
# Command line parameters
USERNAME="$1"
PUBKEY_FILE="$2"
TEMP_DIR="$3"
OUTPUT_PATH=$4
MAINTAINER_EMAIL="$5"

# Verify required args
if [ -z "${USERNAME}" ] || [ -z "${PUBKEY_FILE}" ] || [ -z "${TEMP_DIR}" ] || [ -z "${OUTPUT_PATH}" ]; then
    echo "Usage: $0 USERNAME PUBKEY_FILE TEMP_DIR OUTPUT_PATH" >&2
    exit 1
fi

# Ensure maintainer email
if [ -z "${MAINTAINER_EMAIL}" ]
then
  MAINTAINER_HOSTNAME="$(hostname)"
  if [ -z "$HOSTNAME" ]
  then
    MAINTAINER_HOSTNAME="localhost"
  fi
  MAINTAINER_EMAIL="admin@${MAINTAINER_HOSTNAME}"
fi

# Constants
# Package data
PACKAGE_NAME="xyz-lsc-target-${USERNAME}"
PACKAGE_VERSION="0.5-1"
PACKAGE_NAME_VERSION="${PACKAGE_NAME}_${PACKAGE_VERSION}"
MAINTAINER="Maintainer Name  <${MAINTAINER_EMAIL}>"
PACKAGE_DATE=$(date "+%a, %d %b %Y %H:%M:%S %z")
# Used for identifying username entry in /etc/passwd
USER_COMMENT="XYZ Local Security Checks"
USER_COMMENT_GREP="XYZ\\ Local\\ Security\\ Checks"

# Paths
PACKAGE_BASE_DIR="${TEMP_DIR}/${PACKAGE_NAME_VERSION}"

# Data paths
DATA_DIR="${PACKAGE_BASE_DIR}"
HOME_SUBDIR="home/${USERNAME}"
HOME_DATA_DIR="${DATA_DIR}/${HOME_SUBDIR}"
SSH_DATA_DIR="${HOME_DATA_DIR}/.ssh"
DOC_SUBDIR="usr/share/doc/${PACKAGE_NAME}"
DOC_DATA_DIR="${DATA_DIR}/${DOC_SUBDIR}"

# Control file path
CONTROL_DIR="${PACKAGE_BASE_DIR}/DEBIAN"

#
# Test dependencies
#
if [ -z "$(which dpkg)" ]
then
  echo "dpkg not found" >&2
  exit 1
fi

if [ -z "$(which fakeroot)" ]
then
  echo "fakeroot not found" >&2
  exit 1
fi

if [ -z "$(which md5sum)" ]
then
  echo "md5sum not found" >&2
  exit 1
fi


#
# Create data files
#

# Create .ssh directory
mkdir -p "${SSH_DATA_DIR}"

# Copy public key
AUTH_KEYS_FILE="${SSH_DATA_DIR}/authorized_keys"
cp "${PUBKEY_FILE}" "${AUTH_KEYS_FILE}"

# Create doc directory
mkdir -p "${DOC_DATA_DIR}"

# Create Changelog
cd "${DOC_DATA_DIR}"
CHANGELOG_FILE="${DOC_DATA_DIR}/changelog.Debian"
{
  echo "${PACKAGE_NAME} (${PACKAGE_VERSION}) experimental; urgency=low"
  echo ""
  echo "  * Automatically generated local security check credential package"
  echo "  "
  echo ""
  echo " -- ${MAINTAINER}  ${PACKAGE_DATE}"
} > "${CHANGELOG_FILE}"

# Compress Changelog
gzip -f --best "${CHANGELOG_FILE}"
CHANGELOG_FILE="${CHANGELOG_FILE}.gz"

# Create Copyright info
COPYRIGHT_FILE="${DOC_DATA_DIR}/copyright"
{
  echo "Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/"
  echo ""
  echo "Files: *"
  echo "Copyright: 2018-2020 Greenbone AG"
  echo "License: GPL-2+ (/usr/share/common-licenses/GPL-2)"
} > "${COPYRIGHT_FILE}"

# Create data archive
cd "${DATA_DIR}"
tar -C "${DATA_DIR}" -z -cf "../data.tar.gz" "${HOME_SUBDIR}" "${DOC_SUBDIR}"


#
# Create control files
#

# Create directory
mkdir -p "${CONTROL_DIR}"
chmod "0755" "${CONTROL_DIR}"

# Create "control" file
CONTROL_FILE="${CONTROL_DIR}/control"
{
  echo "Package: ${PACKAGE_NAME}"
  echo "Version: ${PACKAGE_VERSION}"
  echo "Maintainer: ${MAINTAINER}"
  echo "Priority: optional"
  echo "Architecture: all"
  echo "Description: XYZ local security check preparation"
  echo " This package prepares a system for XYZ local security checks."
  echo " A user is created with a specific SSH authorized key."
  echo " The corresponding private key is located at the respective"
  echo " XYZ installation."
} > "${CONTROL_FILE}"

# Create "preinst" file run before installation
PREINST_FILE="${CONTROL_DIR}/preinst"
touch "${PREINST_FILE}"
chmod "0755" "${PREINST_FILE}"
{
  echo "#!/bin/sh"
  echo "# Delete XYZ Local Security Checks by username and comment"
  echo "grep \"${USERNAME}.*${USER_COMMENT_GREP}\" /etc/passwd && userdel -fr ${USERNAME}"
  echo "# XYZ Local Security Checks user and create home directory"
  echo "useradd -c \"${USER_COMMENT}\" -d /home/${USERNAME} -m -s /bin/bash ${USERNAME}"
  echo "# Return exit status 0 to prevent instrm from being triggered"
  echo "# https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html"
  echo "exit 0"
} > "${PREINST_FILE}"

# Create "postinst" file run after installation
POSTINST_FILE="${CONTROL_DIR}/postinst"
touch "${POSTINST_FILE}"
chmod "0755" "${POSTINST_FILE}"
{
  echo "#!/bin/sh"
  echo "# Change file permissions"
  echo "chown -R ${USERNAME}:${USERNAME} /home/${USERNAME}"
  echo "chmod 500 /home/${USERNAME}/.ssh"
  echo "chmod 400 /home/${USERNAME}/.ssh/authorized_keys"
  echo "exit 0"
} > "${POSTINST_FILE}"

# Create "postinst" file run after removal or on error
POSTRM_FILE="${CONTROL_DIR}/prerm"
touch "${POSTRM_FILE}"
chmod "0755" "${POSTRM_FILE}"
{
  echo "#!/bin/sh"
  echo "echo 'prerm file called!!'"
  echo "# Remove user only if it was created by this package."
  echo "# The debian package will run the postun script in case of errors"
  echo "# (e.g. user already existed)."
  echo "# Delete the user only if /etc/passwd lists content that suggests"
  echo "# that the user was created by this package."
  # echo "set -e  # abort on errors"
  echo "grep \"${USERNAME}.*${USER_COMMENT_GREP}\" /etc/passwd && userdel -fr ${USERNAME}"
} > "${POSTRM_FILE}"

# Calculate md5 checksums
MD5SUMS_FILE="${CONTROL_DIR}/md5sums"
cd "${DATA_DIR}"
{
  md5sum "${HOME_SUBDIR}/.ssh/authorized_keys"
  md5sum "${DOC_SUBDIR}/changelog.Debian.gz"
  md5sum "${DOC_SUBDIR}/copyright"
} > "${MD5SUMS_FILE}"

#
# Build package
#

# Combine into .deb file
cd "${TEMP_DIR}"
fakeroot -- dpkg --build "${PACKAGE_NAME_VERSION}" "${OUTPUT_PATH}"

답변1

초기 설치, 업그레이드, 반복 설치를 구별하는 postrm대신 purge. 이런 방식으로 사용자는 업그레이드 등 동안 유지되며 패키지가 apt purge또는 dpkg --purge(또는 이에 상응하는)을 사용하여 제거될 때만 제거됩니다.

이를 수행하려면 postrm첫 번째 매개변수를 확인하고, 그렇다면 purge사용자를 삭제하고, 그렇지 않으면 아무 작업도 수행하지 마십시오. preinst기존 사용자를 삭제하지 않고 아직 존재하지 않는 경우에만 사용자를 생성하도록 사용자를 변경할 수도 있습니다 .

답변2

prermor 를 호출하는 데 사용되는 프로시저는 첫 번째 인수에서 얻을 수 있습니다 . 동일한 버전을 설치하는 경우 이 절차를 사용하십시오.postrm$1upgrade

다이어그램은 프로세스를 보여줍니다 upgrade.

여기에 이미지 설명을 입력하세요.

prerm따라서 postrm또는 파일에 다음 조건문을 추가하면 두 번 실행될 때 패키지 삭제 프로세스가 실행되지 않지만, 패키지를 업그레이드할 때는 실행되지 않습니다.

if [ $1 != "upgrade" ]; then
  # do regular remove process
fi

관련 정보