我经常使用的一个例程是检查调用脚本时传递的有效参数。理想情况下,我想制作这些以及其他类似的例程,我可以从任何脚本调用外部函数来处理这些更简单的过程。但是,我无法从所述函数中检索所需的值,而不会使该过程更复杂。
我尝试过使用命令替换(例如,将外部函数的输出回显到调用脚本本地的变量名),这似乎至少适用于更简单的函数。但是,使用此文件检查功能需要循环中的read命令,因此需要用户交互性,这会导致脚本在尝试解析存储函数调用的变量时挂起:
#!/bin/bash
# This is a simple function I want to call from other scripts.
exist(){
# If the first parameter passed is not a directory, then the input is
#+ invalid.
if [ ! -d "$1" ]; then
# Rename $1, so we can manipulate its value.
userDir="$1"
# Ask the user for new input while his input is invalid.
while [ ! -d "$userDir" ]; do
echo "\"$userDir\" does not exist."
echo "Enter the path to the directory: "
read userDir
# Convert any tildes in the variable b/c the shell didn't get to
#+ perform expansion.
userDir=`echo "$userDir" | sed "s|~|$HOME|"`
done
fi
}
exist "$1"
如何在不增加(太多)复杂性的情况下检索调用脚本中userDir的值?
答案 0 :(得分:0)
马上就可以说我可以回复' stderr上的用户,并在stdout上回显您的预期答案。 我不得不重新排列以使其正常工作,但这已经过测试:
exist(){
# If the first parameter passed is not a directory, then the input is
#+ invalid.
userDir="$1"
if [ ! -d "$userDir" ]; then
# Ask the user for new input while his input is invalid.
while [ ! -d "$userDir" ]; do
>&2 echo "\"$userDir\" does not exist."
>&2 echo "Enter the path to the directory: "
read userDir
done
else
>&2 echo "'$1' is indeed a directory"
fi
echo "$userDir"
}
当我测试时,我将其保存到名为exist.inc.func
的文件中然后我写了另一个使用它的脚本:
#!/bin/sh
source ./exist.inc.func
#Should work with no input:
varInCallingProg=$(exist /root)
echo "Got back $varInCallingProg"
#Should work after you correct it interactively:
varInCallingProg2=$(exist /probablyNotAdirOnYourSystem )
echo "Got back $varInCallingProg2"
答案 1 :(得分:0)
您可以让exists函数通过stderr与用户交互,并仍然使用命令替换捕获变量。我们来看一个简化的例子:
exist() { read -u2 -p "Enter dir: " dir; echo "$dir"; }
选项-u2
告诉read
使用文件描述符2(stderr)与用户进行交互。即使已通过命令替换重定向stdout,这仍将继续有效。选项-p "Enter dir: "
允许read
设置提示并在一个命令中捕获用户输入。
作为其工作原理的一个例子:
$ d=$(exist)
Enter dir: SomeDirectory
$ echo "$d"
SomeDirectory
exist() {
local dir="$1"
while [ ! -d "$dir" ]; do
echo "'$dir' is not a directory." >&2
read -u2 -p "Enter the path to the directory: " dir
dir="${dir/\~/$HOME}"
done
echo "$dir"
}
作为使用中的一个例子:
$ d=$(exist /asdf)
'/asdf' is not a directory.
Enter the path to the directory: /tmp
$ echo "new directory=$d"
new directory=/tmp
注意:
不需要if
语句和 while
循环。 while
就足够了。
单引号可以放在没有转义的双引号字符串中。因此,如果我们将错误消息写为"'$dir' is not a directory."
,则不需要转义。
所有shell变量都应该是双引号,除非人们希望它们受到分词和路径名扩展的影响。