현재 쉘 스크립트를 CUPS 필터로 사용하는 프린터 드라이버를 패키징하고 있습니다. 분명히 CUPS는 이 스크립트를 실행할 수 있어야 합니다. 그러나 현재는 시도할 때 실행 형식 오류가 발생합니다. 쉘 스크립트는 #!/bin/sh
shebang으로 시작됩니다.
다음 패키지 코드는 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!
거기 있는 동안 인용문의 여기를 닫는 태그를 사용하면 포함할 내용이 확실해집니다.여기$
텍스트도 인용되어 있으므로 백슬래시 이스케이프 및 기타 중요한 문자를 사용할 필요가 없습니다 .