我正在使用ghostscript压缩我的pdf文件,这会在我必须处理的密码保护的情况下抛出错误。
外壳脚本
GS_RES=`gs -sDEVICE=pdfwrite -sOutputFile=$gsoutputfile -dNOPAUSE -dBATCH $2 2>&1`
if [ "$GS_RES" != "" ]
then
gspassmsg="This file requires a password for access"
echo "Error message is :::::: "$GS_RES
gspassworddoc=`awk -v a="$GS_RES" -v b="$gspassmsg" 'BEGIN{print index(a,b)}'`
if [ $gspassworddoc -ne 0 ]
then
exit 3 #error code - password protected pdf
fi
fi
执行命令后我的GS_RES
值类似于以下
错误消息1:
GPL Ghostscript 9.19 (2016-03-23) Copyright (C) 2016 Artifex Software, Inc. All
rights reserved. This software comes with NO WARRANTY: see the file PUBLIC for d
etails. Error: /syntaxerror in -file- Operand stack: Execution stack: %interp_ex
it .runexec2 --nostringval-- --nostringval-- --nostringval-- 2 %stopped_push --n
ostringval-- --nostringval-- --nostringval-- false 1 %stopped_push 1967 1 3 %opa
rray_pop 1966 1 3 %oparray_pop 1950 1 3 %oparray_pop 1836 1 3 %oparray_pop --nos
tringval-- %errorexec_pop .runexec2 --nostringval-- --nostringval-- --nostringva
l-- 2 %stopped_push Dictionary stack: --dict:1196/1684(ro)(G)-- --dict:0/20(G)--
--dict:78/200(L)-- Current allocation mode is local Current file position is 1
错误消息2:
GPL Ghostscript 9.19 (2016-03-23) Copyright (C) 2016 Artifex Software, Inc. All rights reserved. This software comes with NO WARRANTY: see the file PUBLIC for details. gs.pdf gsempty.pdf new_sathishks_protected.html sathishks_protected.html Error: Cannot find a 'startxref' anywhere in the file. Output may be incorrect. gs.pdf gsempty.pdf new_sathishks_protected.html sathishks_protected.html Error: An error occurred while reading an XREF table. gs.pdf gsempty.pdf new_sathishks_protected.html sathishks_protected.html The file has been damaged. This may have been caused gs.pdf gsempty.pdf new_sathishks_protected.html sathishks_protected.html by a problem while converting or transfering the file. gs.pdf gsempty.pdf new_sathishks_protected.html sathishks_protected.html Ghostscript will attempt to recover the data. gs.pdf gsempty.pdf new_sathishks_protected.html sathishks_protected.html However, the output may be incorrect. gs.pdf gsempty.pdf new_sathishks_protected.html sathishks_protected.html Error: Trailer dictionary not found. Output may be incorrect. No pages will be processed (FirstPage > LastPage). gs.pdf gsempty.pdf new_sathishks_protected.html sathishks_protected.html This file had errors that were repaired or ignored. gs.pdf gsempty.pdf new_sathishks_protected.html sathishks_protected.html Please notify the author of the software that produced this gs.pdf gsempty.pdf new_sathishks_protected.html sathishks_protected.html file that it does not conform to Adobe's published PDF gs.pdf gsempty.pdf new_sathishks_protected.html sathishks_protected.html specification. gs.pdf gsempty.pdf new_sathishks_protected.html sathishks_protected.html The rendered output from this file may be incorrect.
在错误消息2上运行awk
gspassmsg="This file requires a password for access"
gspassworddoc=`awk -v a="$GS_RES" -v b="$gspassmsg" 'BEGIN{print index(a,b)}'`
它引发了以下错误
错误:awk: newline in string GPL Ghostscript 9.19... at source line 1
错误消息3
**** Error: Cannot find a 'startxref' anywhere in the file.
**** Warning: An error occurred while reading an XREF table.
**** The file has been damaged. This may have been caused
**** by a problem while converting or transfering the file.
**** Ghostscript will attempt to recover the data.
**** Error: Trailer is not found.
**** This file had errors that were repaired or ignored.
**** Please notify the author of the software that produced this
**** file that it does not conform to Adobe's published PDF
**** specification.
我无法使用以下答案中的代码段捕获此错误
if ! gs_res=$(gs -sDEVICE=pdfwrite -sOutputFile="$gsoutputfile" -dNOPAUSE -dBATCH "$2" 2>&1 1>/dev/null); then
echo "Error message is :::::: $gs_res" >&2
gspassmsg='This file requires a password for access'
[[ $gs_res == *"$gspassmsg"* ]] && exit 3 # password protected pdf
echo "Some other error !"
fi
请澄清以下内容
awk
在这里表现得很奇怪?我缺少什么?我对这个shell脚本很新。有人请帮帮我。
PS:我已经用其他细节编辑了我的问题。请仔细研究一下。如果必须添加某些内容,我会添加它。
答案 0 :(得分:2)
Ghostscript的错误消息都遵循相同的模式,但是有一些问题:
输出的一部分是错误发生时操作数堆栈的转储。由于PostScript是一种编程语言,因此堆栈的内容取决于程序,并且完全不可预测。即使您正在处理PDF文件而不是PostScript程序,解释器本身也是用PostScript编写的,因此仍然适用。
'错误:/ syntaxerror ...'
仅限于少数实际可能的错误,PostScript语言参考手册定义了它们。
PostScript(但不是PDF)程序可以安装错误处理程序,它可以完全改变错误输出,甚至可以完全吞下错误。
关于压缩PDF文件',这绝对是不你在做什么。请阅读here,其中说明了实际发生的情况。简而言之,您正在生成一个新的PDF文件,而不是压缩旧文件。
当然,只要您知道密码,就可以使用Ghostscript处理受密码保护的PDF文件。在文档here
中查找PDFPassword现在,由于文件被加密(受密码保护),上面引用的错误消息不,还有其他问题。实际上,考虑到您使用的简单命令行,我会说它有一些非常严重的错误。当然,如果没有看到文件,我无法确定。
现在,如果文件已加密,Ghostscript的输出应为:
GPL Ghostscript GIT PRERELEASE 9.21(2016-09-14) 版权所有(C)2016 Artifex Software,Inc。保留所有权利。 本软件不附带任何担保:有关详细信息,请参阅PUBLIC文件。
****此文件需要密码才能访问。
错误:/ pdf_process_Encrypt中的/ invalidfileaccess
操作数堆栈:
执行堆栈:%interp_exit .runexec2 --nostringval--
--nostringval-- --nostringval- - 2%stopped_push --nostringval---nostringval-- --nostringval-- fa lse 1%stopped_push 1983 1 3%oparray_pop 1982 1 3%oparray_ pop 1966 1 3
%oparray_pop --nostringval-- --nostringval-- --nostri ngval--
--nostringval-- false 1%stopped_push字典堆栈: - dict:1199/1684(ro)(G) - --dict:1/20(G) - --dict:83/200(L) - - --dict:83/200(L) - --dict:135/256(ro)(G) - --dict:291/300(ro)(G) - --dict:26/32 (L) - - 当前分配模式是本地GPL Ghostscript GIT PRERELEASE 9.21:不可恢复的错误,退出代码1
所以只需要点击"这个文件需要密码"应该足以识别加密文件。
现在,正如mklement0所指出的,如果您想解释导致问题的实际脚本是什么,也许我们也可以帮助解决这个问题。您还没有显示脚本的输出,或者解释了无法正常工作的内容。
答案 1 :(得分:2)
KenS's helpful answer解决了有关Ghostscript本身的问题 这是一个应该有效的代码的简化版本:
# Run `gs` and capture its stderr output.
gs_res=$(gs -sDEVICE=pdfwrite -sOutputFile="$gsoutputfile" -dNOPAUSE -dBATCH "$2" 2>&1 1>/dev/null)
ec=$? # Save gs's exit code.
# Assume that something went wrong, IF:
# - gs reported a nonzero exit code
# - but *also* if any stderr output was produced, as
# not all problems may be reflected in a nonzero exit code.
if [[ $ec -ne 0 || -n $gs_res ]]; then
echo "Error message is :::::: $gs_res" >&2
gspassmsg='This file requires a password for access'
[[ $gs_res == *"$gspassmsg"* ]] && exit 3 # password protected pdf
fi
我在gs command
中引用了变量和参数引用。
我已将您的重定向从2>&1
更改为2>&1 1>/dev/null
,以便仅捕获stderr输出。
2>&1
将stderr(2
)重定向到(仍然是原始的)stdout(1
),以便将错误消息发送到stdout并作为命令的一部分捕获替代($(...)
); 1>/dev/null
然后将stdout重定向到空设备,有效地消除所有stdout输出。请注意,早期将stderr重定向到原始标准输出不受此影响,因此实际上整体命令发送到stdout的是原始的stderr输出。我使用的是更现代,更灵活的$(..)
命令替换语法,而不是旧版`...`
表单(有关背景信息,请参阅here)。
我已将GS_RES
重命名为gs_res
,因为最好不要使用全大写的shell变量名称来avoid conflicts with environment variables and special shell variables。
我正在使用简单模式匹配在gs
的stderr输出中找到所需的子字符串。鉴于您已经在变量中测试了输入,Bash自己的字符串匹配功能将会执行(实际上变化很大),并且不需要使用外部实用程序,例如awk
。
至于为什么awk
命令失败:
听起来好像你正在使用 BSD awk
,例如10.12之后macOS附带的那个(你的问题标记为linux
):< / p>
BSD awk
不支持通过-v
传递的变量值中的换行符,除非您\
- 转义换行符。
使用未转义的多行字符串时,awk
调用会在调用index()
之前从根本上失败。
相比之下,GNU Awk和Mawk确实支持通过-v
传递的多行字符串。
继续阅读可选背景信息。
要确定您正在使用的awk
实施,请运行awk --version
并检查输出:
awk version 20070501
- &gt; BSD Awk
GNU Awk 4.1.3, API: 1.1 ...
- &gt; GNU Awk
mawk: not an option: --version
- &gt; Mawk
这是一个尝试使用Awk版本的简单测试:
awk -v a=$'1\n2' -v b=2 'BEGIN { print index(a, b) }'
按照预期, Gnu Awk和Mawk输出3
,而BSD Awk以awk: newline in string 1
失败。
另请注意 \
- 转义换行仅适用于BSD Awk (例如,
awk -v var=$'1\\\n2' 'BEGIN { print var }'
),遗憾的是,没有可移植的方式将多行变量值传递给Awk 。