我是 shell 编程新手。我的目标是让用户选择应该运行哪个文件。我使用以下命令在一个 var 中捕获所有可用的脚本:
var=$(find script*)
到目前为止一切顺利,这是输出:
echo $var
script1 script2 script3 scr...
现在我想将每个文件存储在一个变量中以便在以后的选择中运行它
select SEL in script1 script2 script3 ..........
case $SEL in
$Script1) echo ($Script1 will start) && ./$script1 ;;
$Script2) echo ($Script2 will start) && ./$script2 ;;
$Script3) echo ($Script3 will start) && ./$script3 ;;
$Sc..) echo ($Scr.... will start) && ./$scrip.... ;;
$Sc...) echo ($Sc...... will start) && ./$scrip..... ;;
*) echo "choose on of the availabel files";;
esac
done
如果我不知道每个文件的数量和确切长度,我不知道应该如何分隔所有文件。
我尝试用 echo ${var[1]} 和 echo $var[1] 进行分割,但这不起作用。我收到一个空输出或整个字符串。
答案1
你的第一行:
var=$(find script*)
只是创建var
一个包含所有script*
内容的字符串变量。它是不是一个数组,所以我们不能[]
像你想要的那样对其进行索引。
实际上是script*
由 shell 扩展的,所以find
在那里不做任何事情(除非它们是目录,但看起来不像)——它只是获取所有文件名作为参数,检查它们是否存在,然后直接打印它们再次退出。 shell 实际上完成了所有工作..
相反,我们可以制作一个大批,我们可以使用 shell 的全球扩张直接填充它:
files=(script*)
当我们将初始化程序( 的右侧=
)放在括号中时,我们正在创建一个数组,该数组分别保存多个值。script*
将扩展到script
当前目录中以开头的每个文件名。如果文件名中有空格,它们不会导致单词像$()
数组初始值设定项内的命令(反引号或 )那样被分割。
此时我们可以读入一些用户输入:
select SEL in "${files[@]}"
do
if ! [ "$SEL" ]
then
echo "Choose one of the available files."
continue
fi
echo "$SEL will start"
"./$SEL"
break
done
我们编写"${files[@]}"
干净地扩展整个文件名数组以提供给select
.将向用户提供文件选择,然后我们进入该do...done
块。
如果$SEL
为空,则用户选择了一个不存在的条目,因此我们打印提示,并continue
要求他们再次选择。
否则,我们echo
会收到脚本将启动并运行脚本的通知。我们引用该名称"./$SEL"
是为了防止脚本名称中包含空格,否则会导致命令名称被视为./firstword
,其余单词作为参数。break
阻止我们返回并再次询问用户;如果你想这样做,就把它拿出来。
您使用的case...of
似乎在您给出的示例中没有太大影响,但是如果您确实有一些单独的行为,具体取决于所选的脚本(并且它必须位于这脚本),您可以将其放在do...done
块内。
答案2
不是 100% 确定我完全理解你想要做什么,但这对你来说可能会更好:而不是 var=$(find script*) 和一个你可以更好使用的案例
for i in `find script*`
do
echo ($i will start)
./$i
done