[Документация Yandex Cloud](../../index.md) > [Практические руководства](../index.md) > [Прикладные решения](index.md) > Прочее > Настройка печати с Cloud Desktop на локальный принтер в Linux

# Настройка печати с Yandex Cloud Desktop на локальный принтер в Linux


{% note warning %}

Часть ресурсов, необходимых для прохождения практического руководства, доступны только в [регионе Россия](../../overview/concepts/region.md).

{% endnote %}


Это руководство поможет настроить печать файлов из [Yandex Cloud Desktop](../../cloud-desktop/index.md) на принтер, подключенный к локальной машине под управлением Linux. Решение основано на использовании общего каталога: задания на печать из облачной среды сохраняются в общий каталог, а локальная система перехватывает их и направляет на физический принтер.

{% note info %}

В руководстве приведен пример подключения виртуального принтера для печати в PDF-файл. Чтобы распечатывать на принтере, который подключен к вашей локальной машине (серверу), добавьте этот принтер в сервере печати [CUPS](https://docs.freebsd.org/ru/articles/cups/). При этом не потребуется установка драйвера печати в PDF `printer-driver-cups-pdf`.

{% endnote %}

Чтобы настроить печать с рабочего стола Cloud Desktop на локальном принтере в Linux:

1. [Подготовьте облако к работе](#before-you-begin).
1. [Подготовьте инфраструктуру](#create-infrastructure).
1. [Настройте локальную машину](#config-local).
1. [Настройте рабочий стол](#config-desktop).
1. [Проверьте результат](#check-result).

Если созданные ресурсы вам больше не нужны, [удалите их](#clear-out).


## Перед началом работы {#before-you-begin}

Зарегистрируйтесь в Yandex Cloud и создайте [платежный аккаунт](../../billing/concepts/billing-account.md):
1. Перейдите в [консоль управления](https://kz.console.yandex.cloud), затем войдите в Yandex Cloud или зарегистрируйтесь.
1. На странице **[Yandex Cloud Billing](https://kz.console.yandex.cloud/billing)** убедитесь, что у вас подключен платежный аккаунт, и он находится в [статусе](../../billing/concepts/billing-account-statuses.md) `ACTIVE` или `TRIAL_ACTIVE`. Если платежного аккаунта нет, [создайте его](../../billing/quickstart/index.md) и [привяжите](../../billing/operations/pin-cloud.md) к нему облако.

Если у вас есть активный платежный аккаунт, вы можете создать или выбрать [каталог](../../resource-manager/concepts/resources-hierarchy.md#folder), в котором будет работать ваша инфраструктура, на [странице облака](https://kz.console.yandex.cloud/cloud).

[Подробнее об облаках и каталогах](../../resource-manager/concepts/resources-hierarchy.md).


### Необходимые платные ресурсы {#paid-resources}

В стоимость поддержки инфраструктуры входят:

* Плата за использование вычислительных ресурсов, дисков и исходящий трафик рабочего стола ([тарифы Yandex Cloud Desktop](../../cloud-desktop/pricing.md)).
* Плата за время использования [NAT-шлюза](../../vpc/concepts/gateways.md) и исходящий через него трафик ([тарифы Yandex Virtual Private Cloud](../../vpc/pricing.md)).


## Подготовьте инфраструктуру {#create-infrastructure}

Если у вас еще нет рабочего стола, создайте его:

1. Создайте [сеть](../../vpc/operations/network-create.md) и [подсеть](../../vpc/operations/subnet-create.md) для рабочего стола.
1. [Настройте](../../vpc/operations/create-nat-gateway.md) NAT-шлюз для рабочего стола.
1. [Создайте](../../cloud-desktop/operations/desktop-groups/create.md) группу рабочих столов. При создании выберите образ с ОС на базе Linux, например Ubuntu 20.04.

    {% note info %}

    Рекомендуется использовать одинаковые или близкие версии ОС на локальной машине и удаленном рабочем столе. При использовании разных версий, например Ubuntu 20.04 и Ubuntu 24.04, возможны ошибки совместимости.

    {% endnote %}

1. [Создайте](../../cloud-desktop/operations/desktops/create.md) рабочий стол.


## Настройте локальную машину {#config-local}

Настройте локальную машину для приема файлов с рабочего стола.

{% list tabs group=operating_system %}

- Linux {#linux}

  1. Установите необходимые инструменты:

      * Сервер печати [CUPS](https://ru.wikipedia.org/wiki/Common_UNIX_Printing_System).
      * Пакет printer-driver-cups-pdf — для проверки печати на виртуальном принтере PDF. Для настройки физического принтера установите драйвер этого принтера.

      Для этого выполните команды:

      ```bash
      sudo apt update
      sudo apt install cups printer-driver-cups-pdf
      ```

  1. Создайте файл `install-print-watcher.sh` и вставьте в него код скрипта:

      {% cut "install-print-watcher.sh" %}

      ```bash
      #!/usr/bin/env bash
      # install-print-watcher.sh
      # Install print-watcher service and script.
      set -euo pipefail

      WATCH_DIR="/srv/printdrop"
      PRINTER=""
      PRINT_USER=""
      FW_DIR="yc-print"

      show_help() {
        cat <<EOF
      Usage: $0 [--dir DIR] [--printer NAME] [--user USER] [--fwdir FW_DIR] [--yes|-y]
        --dir DIR        directory to watch (default: /srv/printdrop)
        --printer NAME   CUPS printer name (or empty for DEFAULT printer)
        --user USER      username
        --fwdir FW_DIR   forwarding directory name (default: $FW_DIR)
        -y, --yes        do not ask for confirmation
        -h, --help       show this help
      EOF
      }

      # parse args
      CONFIRM=yes
      while [[ $# -gt 0 ]]; do
        case "$1" in
          --dir) WATCH_DIR="$2"; shift 2 ;;
          --printer) PRINTER="$2"; shift 2 ;;
          --user) PRINT_USER="$2"; shift 2 ;;
          --fwdir) FW_DIR="$2"; shift 2 ;;
          -y|--yes) CONFIRM=no; shift ;;
          -h|--help) show_help; exit 0 ;;
          *) echo "Unknown arg: $1"; show_help; exit 1 ;;
        esac
      done

      if [[ $EUID -ne 0 ]]; then
        echo "This script must be run as root (sudo)." >&2
        exit 1
      fi

      echo "Install print-watcher with parameters:"
      echo "  WATCH_DIR: $WATCH_DIR"
      echo "  PRINTER:   $PRINTER"
      echo "  USER:      $PRINT_USER"
      echo "  FW_DIR:    $FW_DIR"
      if [[ "$CONFIRM" != "no" ]]; then
        read -rp "Continue? [y/N] " ans
        case "${ans,,}" in y|yes) ;; *) echo "Aborted."; exit 1 ;; esac
      fi

      timestamp() { date +%Y%m%d%H%M%S; }

      # detect package manager
      PKG_MGR=""
      if command -v apt-get >/dev/null 2>&1; then
        PKG_MGR="apt"
      elif command -v dnf >/dev/null 2>&1; then
        PKG_MGR="dnf"
      elif command -v yum >/dev/null 2>&1; then
        PKG_MGR="yum"
      elif command -v pacman >/dev/null 2>&1; then
        PKG_MGR="pacman"
      elif command -v zypper >/dev/null 2>&1; then
        PKG_MGR="zypper"
      fi

      install_packages() {
        echo "Installing packages: cups, inotify-tools (if available) and freerdp using $PKG_MGR"
        case "$PKG_MGR" in
          apt)
            apt-get update
            apt-get install -y --no-install-recommends cups inotify-tools freerdp2-x11
            ;;
          dnf)
            dnf install -y cups inotify-tools xfreerdp || true
            ;;
          yum)
            yum install -y cups inotify-tools freerdp2-x11 || true
            ;;
          pacman)
            pacman -Sy --noconfirm cups inotify-tools freerdp2-x11 || true
            ;;
          zypper)
            zypper --non-interactive install cups inotify-tools freerdp2-x11 || true
            ;;
          *)
            echo "Package manager not detected. Please install 'cups' and 'inotify-tools' manually." >&2
            ;;
        esac
      }

      install_packages

      # create/watch directory
      if [[ ! -d "$WATCH_DIR" ]]; then
        mkdir -p "$WATCH_DIR"
        echo "Created $WATCH_DIR"
      fi

      # try to set ownership to lp:lp and permissions
      chown lp:lp "$WATCH_DIR" || echo "Warning: cannot chown $WATCH_DIR to lp:lp (maybe lp does not exist)"
      chmod 0777 "$WATCH_DIR" || true
      echo "Adjusted ownership/permissions for $WATCH_DIR"

      # paths
      SCRIPT_PATH="/usr/local/bin/print-watcher.sh"
      SERVICE_PATH="/etc/systemd/system/print-watcher.service"

      backup_if_exists() {
        local f="$1"
        if [[ -e "$f" ]]; then
          local bak="${f}.bak.$(timestamp)"
          mv "$f" "$bak"
          echo "Backed up existing $f -> $bak"
        fi
      }
      # write desktop file for freerdp
      set +u

      cat  <<EOF > /usr/share/applications/freerdp.desktop
      [Desktop Entry]
      Version=1.0
      Name=XFreeRDP
      Comment=XFreeRDP
      Exec=bash -c '/usr/bin/xfreerdp \$1 /drive:$FW_DIR,$WATCH_DIR ; read -p pressEnter' dummy %F
      Path=/usr/bin
      #for any error being visible after app closed
      Terminal=true
      Type=Application
      Categories=GTK;GNOME;X-GNOME-NetworkSettings;Network;
      Keywords=remote desktop;rdp;vnc;nx;ssh;spice;xdmcp;
      EOF

      set -u

      # register application associations
      cat  <<EOF > /usr/share/mime/packages/freerdp.xml
      <?xml version="1.0" encoding="utf-8"?>
      <mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
      <mime-type type="application/x-freerdp">
        <comment>XFreeRDP file</comment>
        <glob pattern="*.rdp"/>
        <glob pattern="*.rdpx"/>
        <glob pattern="*.RDP"/>
      </mime-type>   
      </mime-info>
      EOF

      xdg-mime install --novendor --mode system /usr/share/mime/packages/freerdp.xml
      update-mime-database /usr/share/mime

      # assign mime-type to desktop application
      if [[ "$(sudo -u $PRINT_USER xdg-mime query default application/x-freerdp)" != "freerdp.desktop" ]]
      then
        echo "setting mime type to freerdp.desktop"
        sudo -u $PRINT_USER xdg-mime default freerdp.desktop application/x-remmina 
        sudo -u $PRINT_USER xdg-mime default freerdp.desktop application/x-freerdp
      else
        echo "freerdp mime type has been already set to freerdp.desktop"
      fi

      # write watcher script
      backup_if_exists "$SCRIPT_PATH"
      cat > "$SCRIPT_PATH" <<'EOF'
      #!/usr/bin/env bash
      # /usr/local/bin/print-watcher.sh
      set -euo pipefail

      usage() {
        cat <<E
      Usage: $0 [-d WATCH_DIR] [-p PRINTER] [-u USER]
      E
        exit 1
      }

      # defaults
      WATCH_DIR="${WATCH_DIR:-/srv/printdrop}"
      PRINTER="${PRINTER:-PDF}"
      USER="${USER:-username}"

      while getopts "d:p:u:h" opt; do
        case "$opt" in
          d) WATCH_DIR="$OPTARG" ;;
          p) PRINTER="$OPTARG"  ;;
          u) USER="$OPTARG"     ;;
          h) usage ;;
          *) usage ;;
        esac
      done

      log() {
        echo "$(date +'%F %T') [print-watcher] $*" >&2
        logger -t print-watcher "$*"
      }

      command -v inotifywait >/dev/null
      2>&1 || { log "inotifywait not found. Exiting."; exit 2; }
      command -v lp >/dev/null 2>&1 || { log "lp not found. Exiting."; exit 2; }

      if [[ ! -d "$WATCH_DIR" ]]; then
        log "Watch dir $WATCH_DIR missing. Exiting."
        exit 3
      fi

      log "Starting watch on $WATCH_DIR for *.pdf, printer='$PRINTER', user='$USER'"

      stopping=0
      term_handler() {
        stopping=1
        log "Term received, exiting..."
      }
      trap term_handler SIGINT SIGTERM

      inotifywait -m -e close_write,moved_to --format '%w%f' --quiet "$WATCH_DIR" | while IFS= read -r FILE; do
        if [[ "$stopping" -ne 0 ]]; then
          log "Stopping watcher loop"
          break
        fi
        case "${FILE,,}" in
          *.pdf)
            if [[ -f "$FILE" ]]; then
              log "Detected PDF: $FILE — submitting to printer '$PRINTER' as user '$USER'"
              if lp -U "$USER" -d "$PRINTER" "$FILE"; then
                rm -f -- "$FILE"
                log "Printed and removed $FILE"
              else
                log "Failed to print $FILE"
              fi
            else
              log "File no longer exists: $FILE"
            fi
            ;;
          *) ;;
        esac
      done

      log "Watcher stopped"
      EOF

      chmod 0755 "$SCRIPT_PATH"
      echo "Installed watcher script at $SCRIPT_PATH"

      # write systemd unit
      backup_if_exists "$SERVICE_PATH"
      cat > "$SERVICE_PATH" <<EOF
      [Unit]
      Description=Watch printdrop and print PDF files
      After=network.target

      [Service]
      ExecStart=${SCRIPT_PATH} -d ${WATCH_DIR} $(if [[ ! -z "$PRINTER" ]];then echo "-p $PRINTER";fi) -u ${PRINT_USER}
      Restart=always
      RestartSec=5
      User=lp
      Group=lp
      TimeoutStopSec=10

      [Install]
      WantedBy=multi-user.target
      EOF

      echo "Installed systemd unit at $SERVICE_PATH"

      # reload systemd and enable service
      systemctl daemon-reload
      systemctl enable --now print-watcher.service

      echo "Service enabled and started. Status:"
      systemctl status --no-pager -l print-watcher.service || true

      echo
      echo "To view logs: journalctl -u print-watcher -f"
      echo "If you need to change parameters later, edit $SERVICE_PATH and run 'systemctl daemon-reload && systemctl restart print-watcher'"
      echo "Done."
      ```

      {% endcut %}

      При запсуке скрипт `install-print-watcher.sh` создаст автоматическую систему для перехвата PDF-файлов из удаленного рабочего стола и печати на локальном принтере. Он установит фоновую службу, которая следит за появлением файлов в специальной папке, и будет автоматически отправлять их на печать через систему CUPS. Скрипт требует права администратора для установки системной службы и использует стандартные инструменты Linux.

  1. Сделайте файл исполняемым и запустите скрипт:

      ```bash
      sudo chmod +x install-print-watcher.sh
      sudo ./install-print-watcher.sh \
        --user <имя_пользователя> \
        --dir <путь_к_папке> \
        --printer <имя_принтера> \
        --fwdir <путь_к_папке>
      ```

      Где:

      * `--user` — имя пользователя локальной машины. Обязательный параметр.
      * `--dir` — папка, за которой нужно следить. По умолчанию `/srv/printdrop`.
      * `--printer` — имя принтера CUPS. Если не указано, будет использоваться принтер, который установлен в системе по умолчанию.
      * `--fwdir` — имя папки на удаленном рабочем столе для пересылки. По умолчанию `yc-print`.

  1. Проверьте статус сервиса:

      ```bash
      systemctl status print-watcher.service
      ```

      Результат:

      ```text
            ● print-watcher.service - Watch printdrop and print PDF files
                Loaded: loaded (/etc/systemd/system/print-watcher.service; enabled; preset>
                ...
      ```

{% endlist %}


## Настройте рабочий стол {#config-desktop}

Настройте рабочий стол для отправки файлов на локальную машину.

{% list tabs group=operating_system %}

- Linux {#linux}

  1. [Подключитесь](../../cloud-desktop/operations/desktops/connect.md) к рабочему столу.
  1. Создайте файл `install-printdrop-backend.sh` и вставьте в него код скрипта:

      {% cut "install-printdrop-backend.sh" %}

      ```bash
      #!/usr/bin/env bash
      # install-printdrop-backend.sh
      # Requires: --user USERNAME and --dir DROP_DIR (they must be already exist).
      set -euo pipefail

      PROG="$(basename "$0")"
      DEFAULT_PRINTER="DropPrinter"
      DEFAULT_DROP_DIR="yc-print"

      usage() {
        cat <<EOF
      Usage: $PROG --user USERNAME [--dir DROP_DIR --printer PRINTER_NAME] [-y|--yes] [-h|--help]

        --user USERNAME       local user who owns DROP_DIR and to whom helper will switch (required)
        --dir DROP_DIR        existing directory to place print jobs (required)
        --printer PRINTER     CUPS printer name to create (default: ${DEFAULT_PRINTER})
        -y, --yes             automatic yes (no interactive prompt)
        -h, --help            show this help
      EOF
      }

      # Defaults
      AUTO_NO_PROMPT="no"
      PRINTER_NAME="$DEFAULT_PRINTER"
      USERNAME=""
      DROP_DIR="$DEFAULT_DROP_DIR"
      FULL_DROP_DIR=""

      # parse args
      while [[ $# -gt 0 ]]; do
        case "$1" in
          --user) USERNAME="$2"; shift 2 ;;
          --dir) DROP_DIR="$2"; shift 2 ;;
          --printer) PRINTER_NAME="$2"; shift 2 ;;
          -y|--yes) AUTO_NO_PROMPT="yes"; shift ;;
          -h|--help) usage; exit 0 ;;
          *) echo "Unknown arg: $1"; usage; exit 1 ;;
        esac
      done


      FULL_DROP_DIR="/home/$USERNAME/thinclient_drives/$DROP_DIR"
      echo "Final directory to put print jobs set to $FULL_DROP_DIR"

      if [[ -z "$USERNAME" ]] ; then
        echo "Error: --user and --dir are required." >&2
        usage
        exit 2
      fi

      if [[ $EUID -ne 0 ]]; then
        echo "This script must be run as root." >&2
        exit 3
      fi

      echo "Parameters:"
      echo "  USER:          $USERNAME"
      echo "  FULL_DROP_DIR: $FULL_DROP_DIR"
      echo "  PRINTER:       $PRINTER_NAME"

      if [[ "$AUTO_NO_PROMPT" != "yes" ]]; then
        read -rp "Continue? [y/N] " ans
        case "${ans,,}" in y|yes) ;; *) echo "Aborted."; exit 1 ;; esac
      fi

      # Validate that user exists
      if ! id -u "$USERNAME" >/dev/null 2>&1; then
        echo "Error: user '$USERNAME' does not exist. Exiting." >&2
        exit 4
      fi

      # Validate that the user can write into FULL_DROP_DIR (best-effort)
      if ! sudo -u "$USERNAME" test -w "$FULL_DROP_DIR" >/dev/null 2>&1; then
        echo "Warning: user '$USERNAME' may not have write permission to '$FULL_DROP_DIR'." >&2
        echo "Please ensure the user can write into the directory before using the backend."
      fi

      timestamp() { date +%Y%m%d%H%M%S; }

      # detect package manager
      PKG_MGR=""
      if command -v apt-get >/dev/null 2>&1; then
        PKG_MGR="apt"
      elif command -v dnf >/dev/null 2>&1; then
        PKG_MGR="dnf"
      elif command -v yum >/dev/null 2>&1; then
        PKG_MGR="yum"
      elif command -v pacman >/dev/null 2>&1; then
        PKG_MGR="pacman"
      elif command -v zypper >/dev/null 2>&1; then
        PKG_MGR="zypper"
      fi

      install_cups() {
        echo "Installing cups (package manager: ${PKG_MGR:-unknown})..."
        case "$PKG_MGR" in
          apt)
            apt-get update
            apt-get install -y --no-install-recommends cups
            ;;
          dnf)
            dnf install -y cups
            ;;
          yum)
            yum install -y cups
            ;;
          pacman)
            pacman -Sy --noconfirm cups
            ;;
          zypper)
            zypper --non-interactive install cups
            ;;
          *)
            echo "Warning: package manager not detected. Please install 'cups' manually and re-run the script." >&2
            ;;
        esac
      }

      install_cups

      # prepare /tmp/cups-shared
      TMP_SHARED="/tmp/cups-shared"
      mkdir -p "$TMP_SHARED"
      chmod 0777 "$TMP_SHARED"
      echo "Prepared $TMP_SHARED (0777)"

      # find backend dir
      BACKENDDIR=""
      if [[ -d /usr/lib/cups/backend ]]; then
        BACKENDDIR="/usr/lib/cups/backend"
      elif [[ -d /usr/libexec/cups/backend ]]; then
        BACKENDDIR ="/usr/libexec/cups/backend"
      else
        # create standard location if neither exists (best-effort)
        BACKENDDIR="/usr/lib/cups/backend"
        mkdir -p "$BACKENDDIR"
      fi
      BACKENDPATH="${BACKENDDIR}/printdrop"

      # backup existing files if present
      backupifexists() {
        local f="$1"
        if [ -e "$f" ]; then
          local bak="${f}.bak.$(timestamp)"
          mv "$f" "$bak"
          echo "Backed up existing $f -> $bak"
        fi
      }
      backupifexists "$BACKENDPATH"

      # write backend (embed FULL_DROP_DIR and USERNAME)
      cat > "$BACKENDPATH" <<EOF
      #!/bin/bash
      # CUPS backend 'printdrop' generated by install-printdrop-backend.sh
      # When called without args, list device URI
      if test "\$#" = "0"; then
        echo 'file printdrop:/ "${PRINTER_NAME}" "/"'
        exit 0
      fi

      DROPDIR="${FULL_DROP_DIR}"
      mkdir -p /tmp/cups-shared

      JOBFILE="\$6"  # CUPS may pass filename as 6th argument
      TS=\$(date +%s)-\$RANDOM
      OUT="\$DROPDIR/job-\$TS.pdf"
      SHAREDOUT="/tmp/cups-shared/job-\$TS.pdf"

      if [ -n "\$JOBFILE" ] && [ -f "\$JOBFILE" ]; then
        cp "\$JOBFILE" "\$SHAREDOUT"
        chmod -R 0777 /tmp/cups-shared
        sudo -u ${USERNAME} /usr/local/bin/copy-as-user.sh "\$SHAREDOUT" "\$OUT"
      else
        cat - > "\$SHAREDOUT"
        sudo -u ${USERNAME} /usr/local/bin/copy-as-user.sh "\$SHAREDOUT" "\$OUT"
      fi
      EOF

      chmod 0755 "$BACKENDPATH"
      chown root:root "$BACKENDPATH"
      echo "Installed CUPS backend at $BACKENDPATH (owned root:root, mode 0755)"

      # helper script
      HELPERPATH="/usr/local/bin/copy-as-user.sh"
      backupifexists "$HELPERPATH"
      cat > "$HELPERPATH" <<'EOF'
      #!/bin/bash
      # copy-as-user.sh
      # Moves a temporary file atomically into final location.
      # Usage: copy-as-user.sh /tmp/cups-shared/job-xxx.pdf /home/username/...
      set -euo pipefail

      if [[ $# -ne 2 ]]; then
        echo "Usage: $0 <src> <dst>"
        exit 1
      fi

      SRC="$1"
      DST="$2"

      # atomic move: move src -> dst.tmp then rename
      mv -- "$SRC" "$DST.tmp"
      mv -- "$DST.tmp" "$DST"
      EOF

      chmod 0755 "$HELPERPATH"
      chown root:root "$HELPERPATH"
      echo "Installed helper $HELPERPATH (owned root:root, mode 0755)"

      # sudoers entry to allow lp to run helper as the target USERNAME without password
      SUDOERSFILE="/etc/sudoers"
      cat >> "$SUDOERSFILE" <<EOF
      # Allow CUPS lp user to run the helper as ${USERNAME}
      lp ALL=(${USERNAME}) NOPASSWD: ${HELPERPATH}
      EOF

      # ensure cups service running
      if command -v systemctl >/dev/null 2>&1; then
        systemctl daemon-reload || true
        systemctl enable --now cups || systemctl start cups || true
      else
        service cups start || true
      fi

      # create printer via lpadmin
      if command -v lpadmin >/dev/null 2>&1; then
        echo "Creating printer '${PRINTER_NAME}' with URI printdrop:/"
        if lpstat -p 2>/dev/null | grep -q "^printer ${PRINTER_NAME}\b"; then
          echo "Printer ${PRINTER_NAME} already exists. Deleting old one."
          lpadmin -x "${PRINTER_NAME}" || true
        fi

        lpadmin -p "${PRINTER_NAME}" -E -v "printdrop:/" || { echo "lpadmin failed"; }
        cupsenable "${PRINTER_NAME}" || true
        cupsaccept "${PRINTER_NAME}" || true
        echo "Printer ${PRINTER_NAME} created and enabled."
      else
        echo "lpadmin not found — cannot create printer. Please create a printer with:"
        echo "  lpadmin -p ${PRINTER_NAME} -E -v printdrop:/"
      fi

      echo
      echo "Installation complete."
      echo "Backend: $BACKENDPATH"
      echo "Helper:  $HELPERPATH"
      echo "Drop dir: $FULL_DROP_DIR (must exist and be writable by $USERNAME)"
      echo "Sudoers entry: $SUDOERSFILE"
      echo
      echo "To test, run:"
      echo "  lp -d ${PRINTER_NAME} somefile.pdf"
      echo "or"
      echo "  cat somefile.pdf | lp -d ${PRINTER_NAME}"
      echo
      echo "To view logs: journalctl -u cups -f"
      ```

      {% endcut %}

      При запуске скрипт `install-printdrop-backend.sh` настроит рабочий стол для отправки заданий на печать в общую папку. Он создаст виртуальный принтер CUPS, который будет перенаправлять все документы в специальную папку, доступную для локальной машины. Скрипт требует права администратора для настройки системы печати и использует механизмы CUPS для интеграции с облачной средой.

  1. Сделайте файл исполняемым и запустите скрипт:

      ```bash
      sudo chmod +x install-printdrop-backend.sh
      sudo ./install-printdrop-backend.sh \
        --user <имя_пользователя_стола> \
        --dir <путь_к_папке> \
        --printer <имя_принтера>
      ```

      Где:

      * `--user` — имя пользователя рабочего стола, у которого есть права на папку, в которую будут помещаться задания на печать. Утилита будет переключаться на него при выполнении. Обязательный параметр.
      * `--dir` — папка, в которую будут помещаться задания на печать. По умолчанию `yc-print`.
      * `--printer` — имя принтера CUPS, который нужно создать. По умолчанию `DropPrinter`.

  1. Убедитесь, что принтер `DropPrinter` создан:

      ```bash
      lpstat -p
      ```

      Результат:

      ```text
      printer DropPrinter is idle.  enabled since Wed 24 Dec 2025 03:46:54 PM UTC
      ```

{% endlist %}


## Проверьте результат {#check-result}

Чтобы проверить результат, отправьте на печать PDF-файл.

{% list tabs group=operating_system %}

- Linux {#linux}

  1. На рабочем столе создайте или [скачайте](https://pdfobject.com/pdf/sample.pdf) любой PDF-файл.
  1. На рабочем столе отправьте на печать PDF-файл, выбрав созданный виртуальный принтер `DropPrinter`.

      В результате отобразится сообщение о поступлении файла в очередь печати.

  1. На локальной машине проверьте файлы, поступившие на печать с рабочего стола:

      ```bash
      ls -lt ~/PDF
      ```

      Результат:

      ```text
      total 312
      -rw------- 1 your-user your-user 48122 дек 29 14:19 job-1766992742-18941-job_2.pdf
      -rw------- 1 your-user your-user 48122 дек 29 13:36 job-1766990196-17574-job_1.pdf
      ```

{% endlist %}


## Как удалить созданные ресурсы {#clear-out}

Чтобы перестать платить за созданные ресурсы:

1. [Удалите](../../vpc/operations/delete-nat-gateway.md) NAT-шлюз.
1. [Удалите](../../cloud-desktop/operations/desktops/delete.md) рабочий стол.

При необходимости удалите [подсети](../../vpc/operations/subnet-delete.md), [сеть](../../vpc/operations/network-delete.md) и [группу рабочих столов](../../cloud-desktop/operations/desktop-groups/delete.md).