私はメニューベースの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文字でなければなりません。
問題はcut -d\ -f2
で発生します。 cut -d\ -f2
に変更します。
cut
の場合、引数は次のようになります。
# bash: args(){ for i; do printf '%q \\\n' "$i"; done; }
# args cut -d\ -f2
cut \
-d\ -f2 \
そしてここに問題があります。 \
は、シェルの引数間の区切り文字の代わりにスペースリテラルにスペースをエスケープし、余分なスペースを追加しなかったため、-d\ -f2
部分全体が1つの引数として表示されます。 -d\
と-f2
が2つの引数として表示されるように、スペースを1つ追加する必要があります。
混乱を避けるために、多くの人々は代わりに-d' '
のような引用符を使用しています。
PS:ファイルを使用してすべてをASCIIにする代わりに、私はむしろ
if file "$attachment2" | grep -q text$; then
# is text
else
# file doesn't think it's text
fi
file $attachment
ではなくfile "$attachment"
と表示されていることから、スクリプトではスペースを含むファイル名を処理できないと思います。ただし、ファイル名にはスペースを含めることができ、適切に記述されたスクリプトはそれらを処理できることに注意してください。注意してください:
$ file "foo bar"
foo bar: ASCII text
$ file "foo bar" | cut -d' ' -f2
bar:
ファイル名をnullで終了することは、一般的で強く推奨されるアプローチの1つです。
$ file -0 "foo bar" | cut -d $'\0' -f2
: ASCII text
file
コマンドは、ファイルがどのタイプのファイルであるかについて、知識に基づいた推測を行います。当然、推測は時々間違っています。たとえば、file
は、通常のテキストファイルを見て、それがシェルスクリプト、Cプログラム、またはその他のものであると推測する場合があります。したがって、file
isASCII text
からの出力がファイルであるかどうかを確認する必要はありませんsaysテキストファイル。 file
のmanページを見ると、ファイルがテキストファイルの場合、出力にWord text
を含めることが多少なりとも約束されていることがわかりますが、これはShell commands text
のようなコンテキストにあるしたがって、file
からの出力にWord text
が含まれているかどうかを確認することをお勧めします。
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
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
私は脱出を回避して行います:
... | cut -d' ' -f2
このように、区切り文字(3文字のシーケンス' '
で指定)と次のオプションの間にスペースが必要であることは明らかです。 -d\ -f2
を使用すると、-d\ -f2
を実行する必要があるはずです。
別のオプションは、cut
を使用せず、file
の完全な出力に対して正規表現を照合することです。
#...
isFile=$(file $attachment)
if [[ "$var" =~ ^[^:]*:\ ASCII ]]
#...