循环文件位置,直到文件存在于bash中

时间:2015-06-09 08:31:15

标签: bash file loops while-loop echo

我创建了这个功能:

function promptFile()

{

while true;
    do
            read -p "Please provide a full path [q to quit]: " file
            if [ $file == q ]; then
                    echo "Exiting.."
                    return 1
            fi

            if [ ! -f $file ]; then
                    echo "File does not exist, please try again"

            else
                    echo $file
                    break
            fi
    done
}

要提示用户输入文件位置,再次询问文件是否不存在,如果输出保存到变量,则调用该函数:

tempLoc=$(promptFile)
if [ !tempLoc ]; then
        fileLocation=$tempLoc
fi

除非有人写错文件位置,否则一切都运行正常,直到有人点击q或输入现有文件位置才会显示回显。 在这种情况下,回信消息将被打印*坏输入的数量,如下所示。

[root@tsting:0]# ./tst
Please provide a full path [q to quit]: tst1
Please provide a full path [q to quit]: tst2
Please provide a full path [q to quit]: tst3
Please provide a full path [q to quit]: tst4
Please provide a full path [q to quit]: q
File does not exist File does not exist File does not exist File does not exist Exiting..
[root@tsting:0]#

我猜这种情况发生了,因为循环崩溃了所有的回声,因为它发生了,有没有办法避免这种情况,只是在输入错误的文件位置时打印回声?

2 个答案:

答案 0 :(得分:2)

将错误写入stderr

echo "File does not exist, please try again" >&2

您正在将函数的所有输出保存到变量tempLoc中,因此即使用户输入了有效文件,它也会在变量中加载垃圾。

Stderr无论如何都应该出现错误消息,所以即使没有这个问题也可以将它们发送到那里。

答案 1 :(得分:0)

这里有几件事:

您不需要()“功能”(反之亦然)。 ()通常是首选,(Korn shell除外)。

始终向stderr:>&2写入错误消息,这是它无效的主要原因。有两个实例需要这样做。

与您的问题无关,但引用变量值是个好主意,尤其是文件名:"$file"。这是因为有人在文件名中有空格。并不是说心智正常的人会用嵌入空间命名文件或目录(程序文件)。使用[[ ]]而不是单个括号可以减少需要,但不会完全删除它。

始终将函数内的变量声明为local,除非您确实需要使用全局变量(通常不需要)。如果不这样做,那么函数内部的变量可能会踩到外面的变量,特别是如果你在多个脚本中重用该函数。

调用函数后的if语句不正确。您正在测试true / false(它不会是),并且您省略了$前缀。

promptFile()
{
    local file

    while true
    do
        read -p "Please provide a full path [q to quit]: " file
        if [ "$file" == q ]; then
            echo "Exiting.." >&2
            return 1
        fi

        if [ ! -f "$file" ]; then
            echo "File does not exist, please try again" >&2
        else
            echo "$file"
            break
        fi
    done
}

tempLoc=$(promptFile)
if [ -n "$tempLoc" ]; then
   fileLocation=$tempLoc
fi