Bashスクリプト:ファイルがテキストファイルであることを確認してください。

Bashスクリプト:ファイルがテキストファイルであることを確認してください。

私はメニューベースのbashスクリプトを書いていますが、メニューオプションの1つはテキストファイル付きの電子メールを送信することです。私のファイルがテキストファイルであることを確認できません。これが私が持っているものです:

fileExists=10
until [ $fileExists -eq 9 ]
do
  echo "Please enter the name of the file you want to attach: "
  read attachment
  isFile=$(file $attachment | cut -d\ -f2)
  if [[ $isFile = "ASCII" ]]
    then
      fileExists=0
    else
      echo "$attachment is not a text file, please use a different file"
  fi
done

エラーが発生し続けます。区切り文字は単一文字でなければなりません。

答え1

  1. file $attachment 代わりにという事実を判断すると、file "$attachment"あなたのスクリプトはスペースを含むファイル名を処理できないようです。ただし、ファイル名にはスペースを含めることができ、よく書かれたスクリプトを使用してそれを処理できます。それから注意してください:

    $ file "foo bar"
    foo bar:  ASCII text
    
    $ file "foo bar" | cut -d' ' -f2
    bar:
    

    広く使用され、強く推奨される方法は、ファイル名をnullで終了することです。

    $ file -0 "foo bar" | cut -d $'\0' -f2
    :  ASCII text
    
  2. このfileコマンドは、ファイルのファイル形式に関する情報に基づいて推測します。もちろん推測が間違っている場合もある。たとえば、file時にはプレーンテキストファイルを見て、それがシェルスクリプト、Cプログラム、または他のものであると推測します。したがって、出力があるかどうかを確認したくありません。file はい ASCII text、あなたが知りたいことは説明するファイルはテキストファイルです。マニュアルページを見ると、ファイルがテキストファイルの場合、出力にその単語が含まれているfileことがわかりますが。出力には次の単語が含まれます。textshell commands textfiletext

    isFile=$(file -0 "$attachment" | cut -d $'\0' -f2)
    case "$isFile" in
       (*text*)
          echo "$attachment is a text file"
          ;;
       (*)
          echo "$attachment is not a text file, please use a different file"
          ;;
    esac
    

答え2

case $(file -b --mime-type - < "$attachment") in
  (text/*)
     printf '%s\n' "$attachment is probably text according to file"
     case $(file -b --mime-encoding - < "$attachment") in
       (us-ascii) echo "and probably in ASCII encoding"
     esac
esac

答え3

cut -d\ -f2に変更すると問題が発生します。cut -d\ -f2

の場合、cutパラメータは次のとおりです。

# bash: args(){ for i; do printf '%q \\\n' "$i"; done; }
# args cut -d\ -f2
cut \
-d\ -f2 \

それが問題だ。\シェル内の引数の間の区切り文字ではなく、スペースリテラルでスペースをエスケープし、余分なスペースを追加しないため、部分全体が1つの引数-d\ -f2として表示されます。追加のスペースを追加して2つのパラメータとして表示する必要があり-d\ます-f2

混乱を避けるために、多くの人が代わりに引用符を使用しています-d' '

PS:ファイルを使うよりもむしろファイルを使い、すべてをASCIIに設定したいです。

if file "$attachment2" | grep -q text$; then
    # is text
else
    # file doesn't think it's text
fi

答え4

別のオプションは、正規表現を使用せずにcut次の出力全体に一致させることですfile

#...
isFile=$(file $attachment)
if [[ "$var" =~ ^[^:]*:\ ASCII ]]
#...

関連情報