2016-11-19 4 views
0

Я сжимаю свой pdf-файл, используя ghostscript, который выдает ошибку на защищенном паролем случае, с которым я должен обращаться.Как grep для шаблона строки из вывода команды в сценарии оболочки?

Shell скрипт

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. 

При управлении AWK на сообщение об ошибке 2

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 

Просьба разъяснить мне следующее

  1. Почему awk ведет себя странно здесь? Что мне не хватает?
  2. Как grep для шаблона в строке, содержащей специальные символы?
  3. Имеет ли Ghostscript какие-либо предопределенные сообщения об ошибках? Если возможно, предложите какую-либо документацию для ссылки.
  4. Можно ли сжать защищенный паролем pdf-файл с помощью ghostscript?
  5. Как я могу обеспечить успех сжатия gs в вышеуказанном случае? Так как я могу не знать о различной возможной ошибке, которую Ghostscript может бросить, чтобы я мог перекреститься с моим результатом выполнения команды.

Я совершенно новый для этого сценария оболочки. Кто-нибудь, пожалуйста, помогите мне в этом.

PS: Я редактировал свой вопрос с дополнительной информацией. Пожалуйста, изучите его. Если что-то нужно добавить, я добавлю его.

+0

@ mklement0 ищет строку (например, «Этот файл требует доступа к доступу») из выходного файла команды - передал этот процесс как «grep». – lsof

+0

И я не уверен, что думаю, что 'awk' играет в проводку, когда мой вывод команды содержит в себе некоторые специальные символы. – lsof

+0

Специальные символы похожи на (',") в выходном файле команды - который я добавил в сообщении об ошибке 2. Пожалуйста, загляните в него. – lsof

ответ

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) к (все еще оригинал) стандартный вывод (1), так что сообщения об ошибках посылаются на стандартный вывод и может быть захвачен как часть команды подстановки ($(...)); 1>/dev/null затем перенаправляет stdout на нулевое устройство, эффективно отключая все выходные данные stdout. Обратите внимание, что ранее перенаправление stderr на оригинал stdout равно , но не, поэтому на самом деле то, что общая команда отправляет в stdout, это только исходный вывод stderr.
      Если вы хотите узнать больше, см. this answer.
  • Я использую более современный и гибкий синтаксис $(..) командной подстановки вместо формы наследие `...` (справочную информацию см here).

  • Я переименовал GS_RES к gs_res, потому что лучше не использовать все прописные оболочки переменных имен, чтобы avoid conflicts with environment variables and special shell variables.

  • Я использую простое сопоставление образцов, чтобы найти нужную подстроку в выводах gs sderder. Учитывая, что у вас уже есть вход для тестирования в переменной, будут использоваться собственные функции сопоставления строк Bash (которые на самом деле весьма разнообразны), и нет необходимости использовать внешнюю утилиту, такую ​​как awk.


Что касается , почему ваша команда awk не удалось:

Это звучит, как вы используете BSDawk, такие как тот, который поставляется с MacOS, как в 10.12 (ваш вопрос помечен linux, однако):

BSD awk не поддерживает newlines в значениях переменных, прошедших через -v, если вы не \ -используете символы новой строки.
С неэкранированными многострочными строками ваш вызов awk происходит неудачно, прежде чем index() когда-либо называется.

В отличие от этого, GNU Awk и Mawk поддерживают многострочные строки как-то через -v.

Читайте дальше для факультативная справочная информация.


Чтобы определить, какие awk реализации вы используете, запустите awk --version и проверьте вывод:

  • awk version 20070501 -> BSD Awk

  • GNU Awk 4.1.3, API: 1.1 ... -> GNU Awk

  • mawk: not an option: --version -> 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.

+0

Спасибо за ваше время @ mklement0. Если я не спрашиваю больше, можете ли вы объяснить мне немного о том, что делает '2> & 1 1>/dev/null'? У меня нет идеи по этому поводу. Пожалуйста, помогите мне узнать об этом. – lsof

+0

Также я использую этот 'awk' как в linux, так и в centos. – lsof

+0

@subramanianrasapan: Re '2> & 1 1>/dev/null': см. Мое обновление. – mklement0

2

сообщения об ошибках в программе Ghostscript все по той же схеме, однако есть несколько подводных камней:

Часть продукции является дамп стека операндов в момент ошибки. Поскольку PostScript является языком программирования, содержимое стека зависит от программы и совершенно непредсказуемо. Несмотря на то, что вы имеете дело с файлами PDF, а не с программами PostScript, интерпретатор сам записывается в PostScript, так что это все равно применяется.

The

'Error: /syntaxerror...'

ограничивается небольшим числом реальных возможных ошибок, то PostScript Language Reference Manual определяет их.

Программы PostScript (но не PDF) могут устанавливать обработчик ошибок, который может полностью изменить вывод ошибки и даже полностью проглотить ошибку.

Что касается «сжатия файлов PDF», то это абсолютно не что вы делаете. Пожалуйста, прочитайте here, в котором объясняется, что происходит на самом деле. Короче говоря, вы создаете новый PDF-файл, не сжимая старый.

Вы можете, конечно же, обработать защищенный паролем файл PDF с помощью Ghostscript, если знаете пароль. Ищите PDFPassword в документации here

Теперь сообщение об ошибке вы цитируете выше не из-файла, (защищенный паролем) зашифрованы, есть что-то еще не так с ним. Фактически, учитывая простую командную строку, которую вы используете, я бы сказал, что с ней что-то совершенно серьезно. Конечно, не видя файл, я не могу сказать наверняка.

Теперь, если файл зашифрован, то выход из Ghostscript должен читать что-то вроде:

GPL Ghostscript GIT PRERELEASE 9.21 (2016-09-14) Copyright (C) 2016 Artifex Software, Inc. All rights reserved. This software comes with NO WARRANTY: see the file PUBLIC for details.

**** This file requires a password for access.

Error: /invalidfileaccess in pdf_process_Encrypt

Operand stack:

Execution stack: %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 Dictionary stack: --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)- - Current allocation mode is local GPL Ghostscript GIT PRERELEASE 9.21: Unrecoverable error, exit code 1

Так просто для оглавлению «Этот файл требует пароля» должно быть достаточно, чтобы идентифицировать зашифрованные файлы.

Теперь, как отмечено mklement0, если вы хотите объяснить, что это касается вашего фактического сценария, который вызывает проблему, возможно, мы тоже сможем помочь с этим. Вы не указали результат своего сценария или не объяснили, что не работает, как вы ожидаете.