循环查找文件位置,直到文件存在于 bash
loop for file location until file exists in bash
我创建了这个函数:
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 或输入现有文件位置时才会显示回显。
在这种情况下,将打印 echo 消息 * 错误输入的数量,如下所示。
[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]#
我猜发生这种情况是因为循环崩溃并返回打印所有回声,有没有办法避免这种情况并在输入错误的文件位置时只打印回声?
将错误写入标准错误
echo "File does not exist, please try again" >&2
您将函数的所有输出保存到变量 tempLoc
中,因此即使用户输入了有效文件,它也会在变量中包含大量垃圾。
Stderr 是无论如何都应该发送错误消息的地方,所以即使没有这个问题,也最好将它们发送到那里。
这里有几件事:
您不需要 ()
和 "function"(反之亦然)。 ()
通常是首选,(Korn shell 除外)。
始终将错误消息写入标准错误:>&2
,这是它不起作用的主要原因。有两种情况需要这样做。
与您的问题无关,但引用变量值是个好主意,尤其是文件名:"$file"
。这是为了防止有人在文件名中包含 whitespace。并不是说任何头脑正常的人都会用嵌入的 space(程序文件)来命名文件或目录。使用 [[ ]]
而不是单个括号可以减少需求,但不会完全删除它。
始终将函数内的变量声明为 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
我创建了这个函数:
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 或输入现有文件位置时才会显示回显。 在这种情况下,将打印 echo 消息 * 错误输入的数量,如下所示。
[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]#
我猜发生这种情况是因为循环崩溃并返回打印所有回声,有没有办法避免这种情况并在输入错误的文件位置时只打印回声?
将错误写入标准错误
echo "File does not exist, please try again" >&2
您将函数的所有输出保存到变量 tempLoc
中,因此即使用户输入了有效文件,它也会在变量中包含大量垃圾。
Stderr 是无论如何都应该发送错误消息的地方,所以即使没有这个问题,也最好将它们发送到那里。
这里有几件事:
您不需要 ()
和 "function"(反之亦然)。 ()
通常是首选,(Korn shell 除外)。
始终将错误消息写入标准错误:>&2
,这是它不起作用的主要原因。有两种情况需要这样做。
与您的问题无关,但引用变量值是个好主意,尤其是文件名:"$file"
。这是为了防止有人在文件名中包含 whitespace。并不是说任何头脑正常的人都会用嵌入的 space(程序文件)来命名文件或目录。使用 [[ ]]
而不是单个括号可以减少需求,但不会完全删除它。
始终将函数内的变量声明为 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