저는 Linux(Fedora 22) 시스템과 열전사 프린터 2대를 갖고 있으며 각각 Digitus 인쇄 서버에 연결되어 있습니다. 모두 동일한 LAN에 있습니다. 각 Digitus 인쇄 서버는 LPD 데몬을 실행하며 각각 하나의 대기열만 제공하도록 구성됩니다 lpd://192.168.1.2/queue
.lpd://192.168.1.3/queue
LPR 클라이언트만 사용하여(전체 CUPS 설치 없이) Fedora에서 LPD 서버로 lpr 파일을 전송할 수 있기를 원합니다. lpr 바이너리를 설치하고 원격 인쇄 서버를 /etc/printcap에 추가하는 cup-client(dnf install cup-client)를 시도했지만 Bad file descriptor
lpr을 실행할 때마다 오류가 발생합니다.
어떤 아이디어가 있나요?
답변1
나는 아주 좋은 해결책을 찾았습니다: rlpr. (여기관심 있는 분들을 위해 링크를 걸어드립니다. 모든 항목은 오래된 gem이지만 rlpr 페이지 하단으로 스크롤하십시오.)
rlpr은 나에게 꼭 필요한 것입니다. 이는 원격 프린터를 로컬로 선언하지 않고도(예: /etc/printcap) LPR 프로토콜을 통해 원격 LPD 데몬과 직접 통신합니다.
rlpr --printer=queue@remotehost file_to_print
tar.gz를 다운로드하고 바이너리를 구성하고 만들어 사용했습니다(설치도 하지 않았습니다).
답변2
rlpr과 같은 클라이언트 전용 기능을 사용할 때 명심해야 할 한 가지는 인쇄 요청을 생성하는 비대화형 배치 프로세스 또는 유사한 프로세스이고 클라이언트 시스템과 프린터/스풀러 사이에 간격이 있는 경우입니다. 네트워크 중단이 발생하면 최선의 경우 목록이 손실되고 최악의 경우 배치 작업이 실패하게 됩니다.
이는 CUPS/LPRng/classic LPD와 같은 로컬 데몬 기능이 필요한 이유 중 하나입니다. 여기서 lpr 클라이언트는 실제로 127.0.0.1:515 또는 :631을 수신하는 로컬 데몬과 통신하고 해당 데몬을 통해 요청을 프록시합니다. 데몬은 저장소를 제공합니다. 앞으로.
네트워크 중단이나 장애로 인해 이 프로세스가 중단될 가능성은 없습니다. 클라이언트는 인쇄 요청을 성공적으로 제출하고 로컬 데몬은 요청을 수락하며 lpd/whatever 데몬은 성공할 때까지 목록을 최종 대상으로 계속 전달하려고 시도합니다. 목록은 손실되지 않으며 일괄 작업/무엇이든 성공적으로 계속됩니다.
rlpr을 사용하면 네트워크가 다운되면 운이 나빠집니다.
이는 lpr.cups 클라이언트를 사용하지만 -H를 사용하여 원격 인쇄 스풀러/프린터를 직접 가리키는 경우에도 문제가 됩니다. 실패는 복구할 수 없습니다.
이는 대화형 사용에서는 문제가 되지 않지만 자동화된 프로세스에서는 염두에 두어야 할 사항입니다.
답변3
RFC 1179그렇지 않으면 클라이언트 작성이 어렵지 않습니다. 대부분의 작업은 오류를 확인하고 입력을 올바르게 형식화하는 것입니다.
#!/usr/bin/perl
# Lobs PostScript at a LPD printer (see RFC 1179). Poorly. Use at own risk,
use strict;
use warnings;
use IO::Socket::INET;
use Sys::Hostname qw(hostname);
my $printer_addr = shift or die "Usage: $0 host [file.ps|-]\n";
my $file = shift;
my $queue = "queue"; # may not be needed?
my $client_host = substr hostname(), 0, 31;
my $user = substr $ENV{USER}, 0, 31;
my $jobnum = sprintf "%03d", rand 1000;
my $sock = IO::Socket::INET->new(
# if server mandates this, client will need to be run as root,
# or Linux capabilities delved into
# LocalPort => 721, # RFC 1179 sec 3.1
PeerAddr => $printer_addr,
PeerPort => 515,
Proto => 'tcp',
ReuseAddr => 1,
) or die "$0: could not connect to $printer_addr: $@\n";
# o - Postscript
# f - ASCII
# l - ASCII, leaving control chars
my $control_file = <<"END_CONTROL_FILE";
H$client_host
P$user
odfA$jobnum$client_host
UdfA$jobnum$client_host
END_CONTROL_FILE
my $control_file_size = length $control_file;
my ($data_file_size, $fh);
if (defined $file and $file ne '-') {
open $fh, '<', $file or die "$0: could not open '$file': $!\n";
$data_file_size = -s $file;
} else {
$fh = \*STDIN;
$data_file_size = 0;
}
sendcmd(sprintf "%c%s\n", 0x02, $queue);
sendcmd(sprintf "%c%u %s\n", 0x02, $control_file_size, "cfA$jobnum$client_host");
$control_file .= "\0"; # must pad message
sendcmd($control_file);
sendcmd(sprintf "%c%u %s\n", 0x03, $data_file_size, "dfA$jobnum$client_host");
binmode $fh;
my $buf;
while (1) {
my $buflen = sysread $fh, $buf, 4096;
die "sysread() failed: $!\n" if !defined $buflen;
last if $buflen == 0; # EOF
syswrite $sock, $buf, $buflen;
}
syswrite $sock, 0x00, 1 if $data_file_size == 0;
# meh, blocks program when input from STDIN
#my $resp;
#sysread $sock, $resp, 1;
#
#syswrite $sock, 0x00, 1;
sub sendcmd {
my $cmd = shift;
my $response;
syswrite $sock, $cmd, length $cmd;
sysread $sock, $response, 1;
chomp $cmd;
die "$0: unexpected lack of response to '$cmd'\n"
if !defined $response;
die sprintf "$0: not-zero response to '$cmd': %vx\n", $response
if $response ne "\0";
}
답변4
Fedora는 CUPS를 인쇄 서버로 사용하여 로컬 및 원격 프린터를 처리합니다. 내가 아는 한, (레거시, 더 이상 사용되지 않는) LP 또는 LPR 프로토콜을 사용하는 기본 패키지는 없으며 한동안 없었습니다. CUPS는 오늘날 사실상의 인쇄 표준입니다. 찾다공개 인쇄특정 짐승을 다루는 방법에 대한 조언을 얻으십시오.
너가능한운이 좋다면 관련 클라이언트와 서버의 소스 코드를 가져와서 실행할 수 있습니다. 아마도 그만한 가치는 없을 것입니다. 하지만 이제 여러분의 시간입니다.
여기에 성공(또는 실패) 경험을 답변으로 추가하세요.