【问题标题】:Printing shell script doesn't print anything打印 shell 脚本不打印任何东西
【发布时间】:2014-07-09 20:55:19
【问题描述】:

我正在尝试在我的树莓派上创建打印服务。这个想法是有一个用于打印作业的 pop3 帐户,我可以在其中发送 PDF 文件并在家中打印它们。因此我设置了fetchmail & rarr; procmail & rarr; uudeview 收集电子邮件(使用白名单),提取文档并将其保存到/home/pi/attachments/。到目前为止,一切正常。

为了打印文件,我想设置一个 shell 脚本,我计划每分钟通过一个 cronjob 执行该脚本。这就是我现在卡住的地方,因为我收到“权限被拒绝”消息,并且脚本在手动执行命令时工作时根本没有打印任何内容。

这是我的脚本的样子:

#!/bin/bash
fetchmail                 # gets the emails, extracts the PDFs to ~/attachments
wait $!                   # takes some time so I have to wait for it to finish
FILES=/home/pi/attachments/*
for f in $FILES; do       # go through all files in the directory
   if  $f == "*.pdf"      # print them if they're PDFs
   then
      lpr -P ColorLaserJet1525 $f
   fi
   sudo rm $f             # delete the files
done;
sudo rm /var/mail/pi      # delete emails

脚本执行后,我得到以下反馈:

1 message for print@MYDOMAIN.TLD at pop3.MYDOMAIN.TLD (32139 octets).
Loaded from /tmp/uudk7XsG: 'Test 2' (Test): Stage2.pdf part 1   Base64
Opened file /tmp/uudk7XsG
procmail: Lock failure on "/var/mail/pi.lock"
reading message print@MYDOMAIN.TLD@SERVER.HOSTER.TLD:1 of 1 (32139 octets) flushed
mail2print.sh: 6: mail2print.sh: /home/pi/attachments/Stage2.pdf: Permission denied

从 pop3 帐户获取电子邮件,提取附件并在 ~/attachements/ 中出现一小段时间,然后被删除。但是没有打印输出。

任何想法我做错了什么?

【问题讨论】:

  • 实际执行脚本的用户是什么(换句话说,您执行crontab 的用户是什么用户)?是您可以手动运行脚本的同一用户吗?
  • 执行 crontab 和运行脚本的用户是同一用户。问题是即使运行脚本我也遇到了错误。但是执行单个命令(fetchmail、lpr -P ColorLaserJet1525 test.pdf、sudo rm test.pdf、sudo rm /var/mail/pi)有效。

标签: bash shell permission-denied procmail


【解决方案1】:
if  $f == "*.pdf"

应该是

if  [[ $f == *.pdf ]]

我也觉得

FILES=/home/pi/attachments/*

应该被引用:

FILES='/home/pi/attachments/*'

建议:

#!/bin/bash
fetchmail                      # gets the emails, extracts the PDFs to ~/attachments
wait "$!"                      # takes some time so I have to wait for it to finish
shopt -s nullglob              # don't present pattern if no files are matched
FILES=(/home/pi/attachments/*)
for f in "${FILES[@]}"; do                              # go through all files in the directory
    [[ $f == *.pdf ]] && lpr -P ColorLaserJet1525 "$f"  # print them if they're PDFs
done
sudo rm -- "${FILES[@]}" /var/mail/pi         # delete files and emails at once

【讨论】:

  • +1 用于修复条件。虽然引用/home/pi/attachments/* 并没有什么坏处,但它没有必要 - 路径名扩展应用于bash 变量分配的RHS。使用for f in $FILESrm -- $FILES 效果很好(只要$FILES 未引用)- 不需要辅助数组。
  • 我不得不承认我使用sh mail2print.sh 而不是bash mail2print.sh 运行脚本。使用shopt 导致我犯了这个错误。我仍然是初学者,今天吸取了教训;)
  • @mklement0 我不确定是否将文件名扩展两次,但这并不是很糟糕,有时可能是一种偏好。可能在调用lpr 期间可能会生成一些流氓文件,因此您的想法可能会对它有所帮助,因为它们也会被删除。
  • @konsolebox:好点;感谢您解释差异。
  • 为什么不简单地使用for f in /home/pi/attachments/* 或者——考虑到你在以后删除所有文件——.../*.pdf
【解决方案2】:

首先使用下面的过滤器过滤 pdf 文件,然后您可以在 for 循环中删除该 if 语句。

FILES="ls /home/pi/attachments/*.pdf" 

【讨论】:

  • 感谢您的建议,但这会使 ~/attachments/ 文件夹中的非 pdf 文件未被删除。
  • 同时将ls 分配给变量几乎没有用或正确。如果意图是执行ls,则语法不正确,但无论如何它都是无用的。
  • @tripleee 我同意 ls 的语法不正确,但我不明白为什么它不会“正确”?
  • 在最好的情况下,使用ls在shell已经扩展通配符之后打印文件名只是浪费。在最坏的情况下,会有子目录,ls 会打印它们的内容而不是它们的名字,所以输出会不正确。
猜你喜欢
  • 2016-03-25
  • 1970-01-01
  • 1970-01-01
  • 2021-11-28
  • 2016-12-11
  • 2018-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多