現在、シェルスクリプトを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
生成したフィルタスクリプトが正しくありません。各行(特に最初の行)は2つのスペースでインデントされます。これは、あなたの#!/bin/sh
行が実際に..#!/bin/sh
(ドットを使用してスペースを表す)ことを意味します。これはカーネルがあなたが何を意味するのかを知ることができないことを意味し、その結果exec format error
。
すべての項目を2つのスペースにインデントしたので、この行を変更することをお勧めします。
cat <<!ENDOFWFILTER! > brother_lpdwrapper_mfc9332cdw
...
!ENDOFWFILTER!
そのために
sed 's/^ //' <<'!ENDOFWFILTER!' > brother_lpdwrapper_mfc9332cdw
...
!ENDOFWFILTER!
そこにいる間に引用符のここを閉じるタグを使用すると、含める内容が確実になります。ここ$
テキストも引用されているため、バックスラッシュエスケープやその他の重要な文字を使用する必要はありません。