从脚本运行ispell时如何理解和避免非交互模式错误?

时间:2016-01-28 13:45:43

标签: linux bash non-interactive ispell

背景

Ispell是linux中的基本命令行拼写程序,我想调用以前收集的文件名列表。例如,从乳胶根文件递归收集这些文件名。当需要拼写所有递归包含的乳胶文件而没有其他文件时,这非常有用。但是,从命令行调用ispell结果是非平凡的,因为ispell会给出表单错误  “还不能处理非交互式使用。”在某些情况下。

(作为一方不是,理想情况下我想使用ProcessBuilder类以编程方式从java调用ispell,而不需要bash。但同样的错误似乎纠缠了这种方法。)

问题

为什么ispell会出现错误“无法处理非交互式使用”。在某些情况下,当从涉及read方法的循环中调用bash时,而不是在其他情况下,如下面的代码示例所示?

以下最小代码示例创建两个小文件 ( testFileOne.txt testFileTwo.txt )以及包含两个已创建文件( testFilesListTemp.txt )的路径的文件。 接下来,以三种不同的方式调用ispell for testFilesListTemp.txt:  1.在“猫”的帮助下  2.首先将名称收集为字符串,然后循环收集的字符串中的子字符串,并为每个字符串调用ispell。  3.直接循环遍历 testFilesListTemp.txt 的内容,并且     为提取的路径调用ispell。

对于某些原因,第三种方法不起作用,并产生错误 “还不能处理非交互式使用。”为什么会出现这个错误  发生,如何防止,和/或是否有另一种变化  第三种方法可以正常工作吗?

#!/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 

1 个答案:

答案 0 :(得分:0)

第三个示例不起作用,因为您重定向标准输入。 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)。