gpt4 book ai didi

bash - 从第一个用户输入定义的选项中接受第二个用户输入的最佳方式是什么?

转载 作者:行者123 更新时间:2023-12-04 07:38:06 24 4
gpt4 key购买 nike

我的背景是 SQL,但我一直在学习 Bash 来创建工具来帮助非 Linux 用户从我的 Linux 系统中找到他们需要的东西——我对 Bash 非常熟悉,如果这看起来有点愚蠢,我深表歉意。
该脚本的目标本质上是向用户显示当前目录中的所有目录,并允许他们输入 1-9 以导航到较低的目录。
我的症结在于我正在尝试使用数组来定义潜在的文件路径,因为实际上随着时间的推移会添加新目录,并且每次添加文件路径时都编辑脚本是不切实际的。
到目前为止,这是我的原型(prototype),目前它导航到 Test1、Test2 或 Test3,然后回显 pwd 以证明它在那里。

#Global Variables
DIR_MAIN='/home/admin/Testhome'

#Potential Filepaths
#/home/admin/Testhome/Test1/Test1-1/
#/home/admin/Testhome/Test1/Test1-2/
#/home/admin/Testhome/Test2/Test2-1/
#/home/admin/Testhome/Test2/Test2-2/
#/home/admin/Testhome/Test3/Test3-1/
#/home/admin/Testhome/Test3/Test3-2/

#Defining Array for first user input
arr=($(ls $DIR_MAIN))

#System to count total number of directories in filepath, then present to user for numbered selection

cnt=0
for i in ${arr[@]}
do
cnt=$(($cnt+1))
echo "$cnt) $i"
done

read -p "Select a folder from the list: " answer
case $answer in
1)
cd $DIR_MAIN/${arr[0]}
echo "Welcome to $(pwd)"
;;
2)
cd $DIR_MAIN/${arr[1]}
echo "Welcome to $(pwd)"
;;
3)
cd $DIR_MAIN/${arr[2]}
echo "Welcome to $(pwd)"
;;
esac
我尝试了以下方法,但它不喜欢这种语法(对于有经验的人来说,我确信这些 case 语句看起来就像是 vim 中的手榴弹)。
我开始怀疑我要走的 SELECT CASE 路是否合适,或者是否有更好的方法。
#User Input Start
echo "What is the secret number?"
while :
do
read STRING1
case $STRING1 in
1)
echo "Enter the number matching the directory you want and I will go there"
echo "1 - ${arr[0]}"
echo "2 - ${arr[1]}"
echo "3 - ${arr[2]}"
read STRING2
case $STRING2 in
1)
cd $DIR_MAIN/${arr[0]}
echo "Welcome to" $(pwd)
2)
cd $DIR_MAIN/${arr[1]}
echo "Welcome to" $(pwd)
3)
cd $DIR_MAIN/${arr[2]}
echo "Welcome to" $(pwd)
*)
echo "Thats not an option and you know it"
*)
echo "1 is the secret number, enter 1 or nothing will happen"
;;
esac
#break needs to be down here somewhere
done
最终我知道,例如,一旦我在 Test2 中,我将需要对本地数组进行可变化(因为在实践中,这可能会下降到/Test2/Test2-9 并且会有大量冗余代码来手动解决这个问题)。
现在,我只是在寻找向用户展示/Test2-1 和/Test2-2 文件路径并允许他们在导航到/Test2/后做出选择的最佳方式

最佳答案

这可能会做你想要的。

#!/usr/bin/env bash

shopt -s nullglob

n=1
for i in /home/admin/Testhome/Test[0-9]*/*; do
printf '%d) %s\n' "$n" "$i"
array[n]="$i"
((n++))
done

(( ${#array[*]} )) || {
printf 'It looks like there is/are no directory listed!\n' >&2
printf 'Please check if the directories in question exists!\n' >&2
return 1
}

dir_pattern_indices=$(IFS='|'; printf '%s' "@(${!array[*]})")

printf '\n'
read -rp "Select a folder from the list: " answer

if [[ -z $answer ]]; then
printf 'Please select a number and try again!' >&2
exit 1
elif [[ $answer != $dir_pattern_indices ]]; then
printf 'Invalid option %s\n' "$answer" >&2
exit 1
fi

for j in "${!array[@]}"; do
if [[ $answer == "$j" ]]; then
cd "${array[j]}" || exit
printf 'Welcome to %s\n' "$(pwd)"
break
fi
done
脚本需要是 sourced例如
source ./myscript
因为 cd命令。 See Why can't I change directory using a script .

使用函数而不是脚本。
让我们将函数命名为 list_dir
list_dir() {

shopt -s nullglob

declare -a array
local answer dir_pattern_indices i j n

n=1
for i in /home/admin/Testhome/Test[0-9]*/*; do
printf '%d) %s\n' "$n" "$i"
array[n]="$i"
((n++))
done

(( ${#array[*]} )) || {
printf 'It looks like there is/are no directory listed!\n' >&2
printf 'Please check if the directories in question exists!\n' >&2
return 1
}

dir_pattern_indices=$(IFS='|'; printf '%s' "@(${!array[*]})")

printf '\n'
read -rp "Select a folder from the list: " answer

if [[ -z $answer ]]; then
printf 'Please select a number and try again!' >&2
return 1
elif [[ $answer != $dir_pattern_indices ]]; then
printf 'Invalid option %s\n' "$answer" >&2
return 1
fi

for j in "${!array[@]}"; do
if [[ $answer == "$j" ]]; then
cd "${array[j]}" || return
printf 'Welcome to %s\n' "$(pwd)"
break
fi
done
}
所有数组名称和变量都声明为函数的本地变量,以免污染交互式/环境 shell 变量。
把它放在你的 shellrc 文件的某个地方,比如 ~/.bashrc然后在编辑完该 shellrc 文件后再次获取它。
source ~/.bashrc
然后只需调用函数名称。
list_dir

关于bash - 从第一个用户输入定义的选项中接受第二个用户输入的最佳方式是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67641709/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com