1

バックグラウンド

Ispell は Linux の基本的なコマンド ライン スペリング プログラムです。これを呼び出して、以前に収集したファイル名のリストを取得したいと考えています。これらのファイル名は、たとえば latex ルート ファイルから再帰的に収集されます。これは、再帰的に含まれるすべてのラテックス ファイルのスペルを指定する必要があり、他のファイルは指定しない場合に役立ちます。ただし、コマンド ラインから ispell を呼び出すと、ispell が「非対話型の使用はまだ処理できません」という形式のエラーを返すため、自明ではありません。ある場合には。

(反対に、理想的には、ProcessBuilder クラスを使用して、bash を必要とせずに Java からプログラムで ispell を呼び出したいと思います。ただし、同じエラーがこのアプローチを悩ませているようです。)

質問

ispell が「まだ非対話的な使用を処理できません」というエラーを出すのはなぜですか。以下のコード例に示すように、特定のケースでは、read メソッドを含むループから bash で呼び出されたときですが、他のケースでは呼び出されませんでしたか?

以下の最小限のコード例では、2 つの小さなファイル ( testFileOne.txttestFileTwo.txt ) と、作成された 2 つのファイルのパスを含むファイル ( testFilesListTemp.txt ) を作成します。次に、次の 3 つの方法で testFilesListTemp.txt に対して ispell が呼び出されます。彼ら。3. testFilesListTemp.txtの内容を直接ループし、抽出されたパスに対して ispell を呼び出します。

いくつかの理由により、3 番目の方法は機能せず、「非インタラクティブな使用はまだ処理できません。」というエラーが発生します。このエラーが発生する正確な理由と、それを防ぐ方法、および/またはエラーなしで機能する3番目のアプローチの別のバリエーションがある可能性がありますか?

#!/bin/bash 

#ispell ./testFiles/ispellTestFile1.txt

# Creating two small files and a file with file paths for testing
printf "file 1 contents" > testFileOne.txt
printf "file 2 contents. With a spelling eeeeror." > testFileTwo.txt
printf "./testFileOne.txt\n./testFileTwo.txt\n" > testFilesListTemp.txt

COLLECTED_LATEX_FILE_NAMES_FILE=testFilesListTemp.txt


# Approach 1: produce list of file names with cat and 
# pass as argumentto ispell
# WORKS
ispell $(cat $COLLECTED_LATEX_FILE_NAMES_FILE)

# Second approach, first collecting file names as long string, 
# then looping over substrings and calling ispell for each one of them 
FILES=""
while read p; do
echo "read file $p" 
FILES="$FILES $p"
done < $COLLECTED_LATEX_FILE_NAMES_FILE

printf "files list: $FILES\n"

for latexName in $FILES; do
    echo "filename: $latexName" 
    ispell $latexName
done


# Third approach, not working 
# ispell compmlains in this case about not working in non-interactive 
# mode 
#: "Can't deal with non-interactive use yet."
while read p; do   
    ispell "$p" 
done < $COLLECTED_LATEX_FILE_NAMES_FILE 
4

1 に答える 1

0

標準入力をリダイレクトするため、3 番目の例は機能しません。ispell端末とユーザーとの対話が必要です。次のようなコードを書くと:

while read p; do   
    ispell "$p" 
done < $COLLECTED_LATEX_FILE_NAMES_FILE 

ループ内のプログラムによって標準入力から読み取られるものはすべて、$COLLECTED_LATEX_FILE_NAMES_FILEファイルから取得されます。ispellを検知し、操作を拒否します。ただし、「説明のリダイレクト」を使用read pして、ファイルからispell "$p"読み取り、「実際の」端末から読み取ることができます。ただ行う:

exec 3<&0
while read p; do   
    ispell "$p" 0<&3
done < $COLLECTED_LATEX_FILE_NAMES_FILE 

exec 3<&0標準入力 (0、「端末」) を記述子 3 に「コピー」 (保存) します。その後、入力して、標準入力 (0) をispellその記述子からリダイレクトします0<&3(必要に応じて 0 を省略できます)。

于 2016-01-28T22:10:16.400 に答える