我目前正在打包一个打印机驱动程序,它使用 shell 脚本作为 CUPS 过滤器。显然,CUPS 需要能够运行该脚本。然而,目前,它在尝试时给我一个执行格式错误。 shell 脚本以#!/bin/sh
shebang 开头。
下面的包代码将会非常丑陋/hacky,因为我对 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
(我知道,非常抱歉,但这实际上只是他们在原始兄弟安装脚本中所做的修改版本,所以这是我的借口)。
另外,这是 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!
当您在那里时,引用的此处结束标记将确保您包含的内容这里文本也被引用,因此您不需要使用$
反斜杠转义和其他重要字符。