【问题标题】:What is the call for the "lp filename" command in linux in a c program?c程序中linux中“lp文件名”命令的调用是什么?
【发布时间】:2015-01-13 21:01:20
【问题描述】:

我想在linux的c程序中使用上面的命令。

到目前为止,我已经搜索过可以在代码中进行的系统调用和执行调用。还有其他使用 exec 或 system 命令的方法吗? 使用 system 命令对于多线程服务器来说不是一个理想的命令,您有什么建议?

【问题讨论】:

  • 只做系统(“lp文件名”)
  • 你问这是否可行?你考虑过尝试吗?
  • 您正在使用空环境调用 lp 命令。这可能会也可能不会导致问题。但正如“那个人”问的那样,你在问它是否有效之前尝试过吗?
  • 我想问如果上面的代码不能正常工作,那么你知道在 c 程序中调用打印命令的更简单的方法吗? .我真的很想避免分叉和孩子。
  • 可以在 shell 中键入的命令和可用的 C 库例程之间不一定存在一一对应关系。

标签: c linux system-calls


【解决方案1】:

首先确保您在此路径中安装了lp。 (在终端中使用which lp)。

您可能想了解lp 命令。这是将数据发送到“行式打印机”的经典 unix 命令,但它适用于例如.pdf 现在也有文件,这取决于您的打印机系统。但是,不一定要安装它。有时,lpr 也可能效果更好。

另请参阅:http://en.wikipedia.org/wiki/Lp_%28Unix%29

第二部分是关于执行 unix 命令。 system 是最简单的(也是最容易在您的程序中引入安全问题的!),使用 forkexecve 是众多替代方案之一(请查看 man execve)。

【讨论】:

  • 我实际上从我的 linux 终端测试了 lp 命令,我成功地得到了打印,但我想知道如何在我的 c 程序中使用这个命令。是的,似乎系统是最简单的,但有人提到它会减慢我的程序或将我的代码挂在我的 cmets 上面。
【解决方案2】:

是的,这段代码没问题。如果在/usr/bin 找到lp 并且存在filename 文件,它将打印名为filename 的文件。如果您希望程序报告出现问题,您可以添加检查,除此之外它会完全按照您的预期执行。

如果您不介意在system() 调用之后直到lp 完成之前阻塞您的程序,那么执行system("lp filename"); 会起作用。

【讨论】:

  • 它不适合多线程服务器,对吧?我不希望我的程序在获得系统命令后进入阻塞状态。在我实现多线程服务器时,我希望它在发出系统命令后返回侦听状态。
  • 我还想问一件事。我可以将 char 数组传递给我的 C 程序中的系统调用吗?像下面这样: char filename[1024]:"/home/user/Desktop/texts/hello1.txt" system("lp filename")
  • 不,你需要snprintf,比如char command[SOME_LARGE_ENOUGH_VALUE]; snprintf(command, sizeof(command), "lp %s", filename); system(command);
  • 我明白了,太好了! . 还有另一件事与 fork+exec 相关,只有当您有多个客户端访问打印机时才需要这样的语句,对吗?我的意思是说没有 fork execve 仍然可以正常工作?
  • 不,和那个没有关系,如果你想让你的程序执行lp命令,你可以使用它,并继续执行,fork()创建一个新进程,然后替换为execv(),所以原来的进程继续正常执行,还有popen()也允许与子进程通信。
【解决方案3】:

您也可以使用popen(3)(而不是system(3))。但是你总是需要分叉一个进程(systempopen 都在调用fork(2))。顺便说一句,如果你有一个 CUPS 服务器,你可能会使用一些 HTTP 客户端协议库,比如libcurl,但这可能很不方便。更好的popensystem 一个lp(或lpr)命令。

顺便说一句,打印是一项相对缓慢且复杂的操作,因此分叉进程的开销可以忽略不计(我相信您可以在服务器中做到这一点;毕竟人们通常不会打印数百万页)。某些库可能会为您提供一些 API(例如 Qt 中的 QPrinter)。

注意lp(或lpr)命令实际上并没有进行打印,它只是与一些打印守护进程(cupsdlpd ...)及其假脱机系统进行交互。参见例如CUPS。因此,运行lplpr 命令相当快(比打印本身快得多),通常只需几毫秒(当然与多线程或服务器应用程序兼容)。

通常,传递给popensystem 的命令是构造的(例如使用snprintf(3) 等...),例如

  char cmdbuf[128];
  snprintf (cmdbuf, sizeof(cmdbuf), "lp %s", filename);

但要小心code injection(想想filename 包含foo; rm -rf $HOME)和buffer overflow

当然,请注意 systempopenfopen 等库函数通常构建在现有的 syscalls(2) 之上。阅读Advanced Linux Programming

【讨论】:

  • 伟大的答案 Basile!我不能投票给你,因为该死的反对票,因为我是一个相对较新的用户,所以我不能投票。
  • 我还想问一件事。我可以将 char 数组传递给我的 C 程序中的系统调用吗?像下面这样: char filename[1024]:"/home/user/Desktop/texts/hello1.txt" system("lp filename");
  • @goldriver 不,您必须在 char 数组中形成整个命令。例如:使用sprintf 和“系统”字符数组。
  • @Jasen:从不建议sprintf,而只建议snprintf(或asprintf,如果有的话)
猜你喜欢
  • 1970-01-01
  • 2019-02-10
  • 2019-01-01
  • 2011-06-27
  • 2016-03-20
  • 1970-01-01
  • 1970-01-01
  • 2015-03-21
  • 1970-01-01
相关资源
最近更新 更多