1

数日前、フォルダー内のすべての PDF のページ数とファイル サイズを合計する小さな bash スクリプトを開始しました。今はかなりうまくいっていますが、まだ理解できないことが 1 つあります。

が設定されている場合、sed が常に失敗するのはなぜshopt -s nullglobですか? なぜこれが起こるのか誰かが知っていますか?

Ubuntu 14.04 で GNU Bash 4.3 と sed 4.2.2 を使用しています。

set -u
set -e

folder=$1

overallfilesize=0
overallpages=0
numberoffiles=0

#If glob fails nothing should be returned
shopt -s nullglob

for file in $folder/*.pdf
do

  # Disable empty string if glob fails
  # (Necessary because otherwise sed fails ?:|)
  #shopt -u nullglob

  # This command is allowed to fail
  set +e
  pdfinfo="$(pdfinfo "$file" 2> /dev/null)"
  ret=$? 
  set -e  

  if [[ $ret -eq 0 ]]
  then 
    #Remove every non digit in the result
    sedstring='s/[^0-9]//g'
    filesize=$(echo -e "$pdfinfo" | grep -m 1 "File size:" | sed $sedstring)
    pages=$(echo -e "$pdfinfo" | grep -m 1 "Pages:" | sed $sedstring)

    overallfilesize=$(($overallfilesize + $filesize))  
    overallpages=$(($overallpages+$pages))  
    numberoffiles=$(($numberoffiles+1))  
  fi

done

echo -e "Processed files: $numberoffiles"
echo -e "Pagesum: $overallpages"
echo -e "Filesizesum [Bytes]: $overallfilesize"
4

1 に答える 1

3

問題を再現するためのより簡単なテストケースを次に示します。

#!/bin/bash
shopt -s nullglob
pattern='s/[^0-9]//g'
sed $pattern <<< foo42

期待される出力:

42

実際の出力:

Usage: sed [OPTION]... {script-only-if-no-other-script} [input-file]...
(sed usage follows)

これs/[^0-9]//gは、 が有効なグロブ (のような dir 構造に一致するs/c/g) であり、bash に解釈を依頼したために発生します。一致するファイルがないためnullglob、パターンを開始して完全に削除します。

二重引用符は単語の分割とグロブの解釈を防ぎます。これはほとんどの場合、あなたが望むものです:

#!/bin/bash
shopt -s nullglob
pattern='s/[^0-9]//g'
sed "$pattern" <<< foo42

これにより、期待される出力が生成されます。

特別な理由がない限り、常にすべての変数参照を二重引用符で囲む必要があります。

于 2015-03-19T19:46:42.350 に答える