기존 Nix 패키지의 바이너리를 활성화하여 다른 패키지의 쉘 스크립트를 실행하려면 어떻게 해야 합니까?

기존 Nix 패키지의 바이너리를 활성화하여 다른 패키지의 쉘 스크립트를 실행하려면 어떻게 해야 합니까?

현재 쉘 스크립트를 CUPS 필터로 사용하는 프린터 드라이버를 패키징하고 있습니다. 분명히 CUPS는 이 스크립트를 실행할 수 있어야 합니다. 그러나 현재는 시도할 때 실행 형식 오류가 발생합니다. 쉘 스크립트는 #!/bin/shshebang으로 시작됩니다.

다음 패키지 코드는 Nix에 대한 나의 지식이 매우 기초적이기 때문에 매우 추악하고 해킹될 것이므로 미리 죄송합니다. 개선 사항을 제안하고 싶다면 계속 진행하세요. 하지만 지금 제가 가장 걱정하는 것은 이를 어떻게 작동시킬 수 있느냐입니다.

with import <nixpkgs> {};

let
  srcs = {
    lpr-deb = fetchurl {
      url = "http://download.brother.com/welcome/dlf101620/mfc9332cdwlpr-1.1.3-0.i386.deb";
      sha256 = "0mmqcwpbw4dx2hqaxhnvm52jm84vq8c55xrixsvapxwrdbpkdcca";
      name = "mfc9332cdwlpr-1.1.3-0.i386.deb";
    };
    cupswrapper-deb = fetchurl {
      url = "http://download.brother.com/welcome/dlf101621/mfc9332cdwcupswrapper-1.1.4-0.i386.deb";
      sha256 = "1q9y90hdrgl80zwqk2vn7b1znjvf15l8q0zg868sv0by6rdq8r5w";
      name = "mfc9332cdwcupswrapper-1.1.4-0.i386.deb";
    };
  };
in stdenv.mkDerivation rec {
  name="brother-mfc9332cdw";
  rev = "1.1.4-0";

  buildInputs = [ pkgs.wget pkgs.dpkg pkgs.perl pkgs.bash ];

  unpackPhase = ''
    dpkg-deb -x ${srcs.lpr-deb} .
    dpkg-deb -x ${srcs.cupswrapper-deb} .
    '';

  dontBuild = true;

  installPhase = ''
    perl -i -pe 's#printcap\.local#printcap#g' opt/brother/Printers/mfc9332cdw/inf/setupPrintcapij
    cp -rf usr $out/
    cp -rf opt $out/
    mkdir -p $out/share/cups/model/Brother
    cp $out/opt/brother/Printers/mfc9332cdw/cupswrapper/brother_mfc9332cdw_printer_en.ppd $out/share/cups/model/Brother
    chmod 644 $out/share/cups/model/Brother/brother_mfc9332cdw_printer_en.ppd
    cat $out/opt/brother/Printers/mfc9332cdw/cupswrapper/cupswrappermfc9332cdw | sed -n "/ENDOFWFILTER/,/ENDOFWFILTER/p" | tail -n +2 | sed "$ d" > brother_lpdwrapper_mfc9332cdw
    perl -i -pe 's#/usr/#$out/#g' brother_lpdwrapper_mfc9332cdw && perl -i -pe 's#/opt/#$out/opt/#g' brother_lpdwrapper_mfc9332cdw
    cat <<!ENDOFWFILTER! > brother_lpdwrapper_mfc9332cdw
      #!/bin/sh
      #
      # Copyright (C) 2005-2016 Brother. Industries, Ltd.
      #                                    Ver1.10

      # This program is free software; you can redistribute it and/or modify it
      # under the terms of the GNU General Public License as published by the Free
      # Software Foundation; either version 2 of the License, or (at your option)
      # any later version.
      #
      # This program is distributed in the hope that it will be useful, but WITHOUT
      # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
      # more details.
      #
      # You should have received a copy of the GNU General Public License along with
      # this program; if not, write to the Free Software Foundation, Inc., 59 Temple
      # Place, Suite 330, Boston, MA  02111-1307  USA
      #

      LOGFILE="/dev/null"
      LOGLEVEL="1"
      LOGCLEVEL="7"
      DEBUG=0
      NUPENABLE=1
      LOG_LATESTONLY=1


      touch /tmp/mfc9332cdw_latest_print_info
      chmod 600 -R /tmp/mfc9332cdw_latest_print_info

      errorcode=0

      if [ \$DEBUG != 0 ]; then
          LOGFILE=/tmp/br_cupsfilter_debug_log
      fi

      PPDC=\`printenv | grep "PPD="\`
      PPDC=\`echo \$PPDC | sed -e 's/PPD=//'\`

      if [ "\$PPDC" = "" ]; then
          PPDC="$out/share/cups/model/Brother/brother_mfc9332cdw_printer_en.ppd"
      fi


      if [ \$LOGFILE != "/dev/null" ]; then
        if [ \$LOG_LATESTONLY == "1" ]; then
          rm -f \$LOGFILE
          date                                                           >\$LOGFILE
        else
          if [ -e \$LOGFILE ]; then
              date                                                        >>\$LOGFILE
          else
              date                                                        >\$LOGFILE
          fi
        fi
          echo "arg0 = \$0"                                           >>\$LOGFILE
          echo "arg1 = \$1"                                           >>\$LOGFILE
          echo "arg2 = \$2"                                           >>\$LOGFILE
          echo "arg3 = \$3"                                           >>\$LOGFILE
          echo "arg4 = \$4"                                           >>\$LOGFILE
          echo "arg5 = \$5"                                           >>\$LOGFILE
          echo "arg6 = \$6"                                           >>\$LOGFILE
          echo "PPD  = \$PPD"                                         >>\$LOGFILE
      fi

      cp  $out/opt/brother/Printers/mfc9332cdw/inf/brmfc9332cdwrc  /tmp/brmfc9332cdwrc_\$$
      chmod 777 -R /tmp/brmfc9332cdwrc_\$$
      export BRPRINTERRCFILE=/tmp/brmfc9332cdwrc_\$$

      INPUT_TEMP_PS=\`mktemp /tmp/br_input_ps.XXXXXX\`

      nup="cat"
      if [ "\`echo \$5 | grep 'Nup='\`" != "" ] && [ \$NUPENABLE != 0 ]; then

          if   [ "\`echo \$5 | grep 'Nup=64'\`" != "" ]; then
              nup="psnup -64"
          elif [ "\`echo \$5 | grep 'Nup=32'\`" != "" ]; then
              nup="psnup -32"
          elif [ "\`echo \$5 | grep 'Nup=25'\`" != "" ]; then
              nup="psnup -25"
          elif [ "\`echo \$5 | grep 'Nup=16'\`" != "" ]; then
              nup="psnup -16"
          elif [ "\`echo \$5 | grep 'Nup=8'\`" != "" ]; then
              nup="psnup -8"
          elif [ "\`echo \$5 | grep 'Nup=6'\`" != "" ]; then
              nup="psnup -6"
          elif [ "\`echo \$5 | grep 'Nup=4'\`" != "" ]; then
              nup="psnup -4"
          elif [ "\`echo \$5 | grep 'Nup=2'\`" != "" ]; then
              nup="psnup -2"
          elif [ "\`echo \$5 | grep 'Nup=1'\`" != "" ]; then
              nup="cat"
          fi
          echo   "NUP=\$nup"                                      >>\$LOGFILE
         if [ -e /usr/bin/psnup ]; then
             if [ \$# -ge 7 ]; then
                 cat \$6  | \$nup > \$INPUT_TEMP_PS
             else
                 cat       | \$nup > \$INPUT_TEMP_PS
             fi
         else
             if [ \$# -ge 7 ]; then
                 cp \$6  \$INPUT_TEMP_PS
             else
                 cat    > \$INPUT_TEMP_PS
             fi
         fi
      else
         if [ \$# -ge 7 ]; then
            cp \$6  \$INPUT_TEMP_PS
         else
            cat    > \$INPUT_TEMP_PS
         fi
      fi
      if [ -e "$out/opt/brother/Printers/mfc9332cdw/lpd/filtermfc9332cdw" ]; then
             :
      else
          echo "ERROR: /opt/brother/Printers/mfc9332cdw/lpd/filtermfc9332cdw does not exist"   >>\$LOGFILE
          echo "ERROR: /opt/brother/Printers/mfc9332cdw/lpd/filtermfc9332cdw does not exist"   >>/tmp/mfc9332cdw_latest_print_info
          errorcode=30
          exit
      fi

      CUPSOPTION=\`echo "\$5 Copies=1" | sed -e 's/BrMirror=OFF/MirrorPrint=OFF/' -e 's/BrMirror=ON/MirrorPrint=ON/' -e 's/BrChain/Chain/' -e 's/BrBrightness/Brightness/' -e 's/BrContrast/Contrast/' -e 's/BrHalfCut/HalfCut/' -e 's/BrAutoTapeCut/AutoCut/' -e 's/BrHalftonePattern/Halftone/' -e 's/Binary/Binary/' -e 's/Dither/Dither/' -e 's/ErrorDiffusion/ErrorDiffusion/' -e 's/BrSheets/Sheets/' -e 's/multiple-document-handling/Collate/' -e 's/separate-documents-collated-copies/ON/' -e 's/separate-documents-uncollated-copies/OFF/'\`
      if [ -e "$out/opt/brother/Printers/mfc9332cdw/cupswrapper/brcupsconfpt1" ]; then

        if [ \$DEBUG = 0 ]; then
           $out/opt/brother/Printers/mfc9332cdw/cupswrapper/brcupsconfpt1  MFC9332CDW  \$PPDC 0 "\$CUPSOPTION" "mfc9332cdw" \$BRPRINTERRCFILE>> /dev/null
        else
           $out/opt/brother/Printers/mfc9332cdw/cupswrapper/brcupsconfpt1  MFC9332CDW  \$PPDC \$LOGCLEVEL "\$CUPSOPTION" "mfc9332cdw" \$BRPRINTERRCFILE>>\$LOGFILE
        fi
      fi

      if [ \$DEBUG -lt 10 ]; then
          cat    \$INPUT_TEMP_PS | $out/opt/brother/Printers/mfc9332cdw/lpd/filtermfc9332cdw 
          echo brmfc9332cdwrc_\$$   > /tmp/mfc9332cdw_latest_print_info
          cat  /tmp/brmfc9332cdwrc_\$$  >> /tmp/mfc9332cdw_latest_print_info
          rm -f /tmp/brmfc9332cdwrc_\$$

          if [ \$LOGLEVEL -gt 2 ];  then
             if [ \$LOGFILE != "/dev/null" ]; then
               echo ""                                                >>\$LOGFILE
               echo "    ------PostScript Data-------"                >>\$LOGFILE
               cat    \$INPUT_TEMP_PS                                  >>\$LOGFILE
             fi
          fi
      fi
      rm -f  \$INPUT_TEMP_PS

      exit $errorcode
    !ENDOFWFILTER!
    chmod 755 brother_lpdwrapper_mfc9332cdw
    mkdir -p $out/lib/cups/filter
    cp brother_lpdwrapper_mfc9332cdw $out/lib/cups/filter
    '';
}

cat제가 이야기하고 있는 bash 스크립트는 다음 위치에 설정되어 있습니다. installPhase(알고 있습니다. 매우 죄송하지만 실제로는 원래 Brother 설치 스크립트에서 수행한 작업을 수정한 버전이므로 변명입니다.)

또한 CUPS 로그의 관련 부분은 다음과 같습니다.

Jan 29 15:43:22 kenix-vaio cupsd[11674]: Started filter /nix/store/v0vlk9dni6kn077i3ilfkml4cr8w979b-cups-progs/lib/cups/filter/pdftopdf (PID 11799)
Jan 29 15:43:22 kenix-vaio cupsd[11674]: Started filter /nix/store/v0vlk9dni6kn077i3ilfkml4cr8w979b-cups-progs/lib/cups/filter/pdftops (PID 11800)
Jan 29 15:43:22 kenix-vaio cupsd[11674]: Started filter /nix/store/v0vlk9dni6kn077i3ilfkml4cr8w979b-cups-progs/lib/cups/filter/brother_lpdwrapper_mfc9332cdw (PID 11801)
Jan 29 15:43:22 kenix-vaio cupsd[11674]: Started backend /nix/store/v0vlk9dni6kn077i3ilfkml4cr8w979b-cups-progs/lib/cups/backend/lpd (PID 11802)
Jan 29 15:43:22 kenix-vaio cupsd[11674]: REQUEST localhost - - POST /printers/MFC9332CDW HTTP/1.1 200 127388 Send-Document successful-ok
Jan 29 15:43:22 kenix-vaio cupsd[11674]: execv failed: Exec format error
Jan 29 15:43:22 kenix-vaio cupsd[11674]: PID 11801 (/nix/store/v0vlk9dni6kn077i3ilfkml4cr8w979b-cups-progs/lib/cups/filter/brother_lpdwrapper_mfc9332cdw) stopped with status 108 (Exec format error)

답변1

생성한 필터 스크립트가 올바르지 않습니다. 각 줄(특히 첫 번째 줄)은 공백 두 개만큼 들여쓰기됩니다. 이는 귀하의 #!/bin/sh라인이 실제로 ..#!/bin/sh(점을 사용하여 공백을 나타냄) 의미한다는 것을 의미합니다. 이는 커널이 귀하가 의미하는 바를 파악할 수 없음을 의미하며 결과적으로 exec format error.

모든 항목을 공백 두 개로 들여쓰기했으므로 이 줄을 변경하는 것이 좋습니다.

cat <<!ENDOFWFILTER! > brother_lpdwrapper_mfc9332cdw
...
!ENDOFWFILTER!

이를 위해

sed 's/^  //' <<'!ENDOFWFILTER!' > brother_lpdwrapper_mfc9332cdw
...
!ENDOFWFILTER!

거기 있는 동안 인용문의 여기를 닫는 태그를 사용하면 포함할 내용이 확실해집니다.여기$텍스트도 인용되어 있으므로 백슬래시 이스케이프 및 기타 중요한 문자를 사용할 필요가 없습니다 .

관련 정보