@while+do。。。done和case。。。esac或者if。。。then。。fi的嵌套使用@

本文深入探讨了Shell脚本中的高级循环(如while-do-done)与条件语句(如case-esac)的嵌套使用,通过案例展示了如何实现复杂功能,包括用户交互、命令执行和状态检查。同时,介绍了自定义函数getappInfo的实现,涉及管道命令、数组操作和条件判断,旨在提高脚本的灵活性和效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(一)while do。。。done和case。。。esac嵌套使用

cpsDeploy_menu(){
echo " --- CPS APP Menu--- "
echo " help app command: getdeploy app_name "
#echo "deploy $size $app_name "
echo " Check app status: status app_name:app_name "
echo " Deploy Command : deploy IP app_name source_path/"
#echo

while true ; do
read -p "App> " appcomm deploylist(两个变量)

case "$appcomm" in
"quit")

break
;;
"getdeploy")
echo " Search $deploylist :"
num=`grep "^$deploylist" cpsapplist.prop | wc -l`
if [ $num > 0 ];then
getdeployapp $deploylist
else
echo " Please sure the app name is correct! "
fi
;;
"deploy")
echo " cps app deployment now...."
echo "deploy directory: $deploylist"
deploywarapp $deploylist
#getdeploylist $deploylist
;;
"status")
getappstatus $deploylist
;;
esac

done

}

注意:

在测试的过程中我发现了一个错误,就是那个if [ $num > 0 ]中不能够用>,正确的用法应该是

if [ $num-gt 0 ]

或者

if [ $num\>0 ]

或者

if [[ $num>0 ]]

(二)while do。。。done和if。。。then。。。fi的嵌套使用

getappInfo(){
app=$1
i=0
sed -n "/^$app=/p" "$sordir"cpsapplist.prop | cut -d= -f2 |
while read i
do
if [ ! -z "$i" ]
then
array=( `echo $i`)
size=${#array[*]}

ip=${array[0]}
appid=${array[1]}
appdir=${array[2]}
startcmd=${array[3]}
apptype=${array[4]}
fi
done
}

点评:

首先getappInfo()是自定义的函数

然后用到一个管道命令

再有就是while do。。。done和if。。。then。。。fi的嵌套使用

最后在if。。。then判断语句中又用到了数组

这些都是这个函数的一大亮点~

ps:

break跳出整个循环

continue跳出本次循环,进行下次循环

#!/system/bin/sh # 双缓冲倒计时脚本 - 修复 "Interrupted system call" 错误 # 初始化变量 target_year=0 target_month=0 target_day=0 target_hour=0 target_minute=0 target_second=0 remaining_seconds=0 is_paused=true is_running=false last_update=0 refresh_rate=1 # 刷新频率(秒) # 双缓冲系统初始化 init_double_buffer() { # 创建两个临时文件作为缓冲区 buffer1=$(mktemp) buffer2=$(mktemp) # 设置当前显示缓冲区后台缓冲区 current_buffer=$buffer1 back_buffer=$buffer2 # 隐藏光标 echo -ne "\033[?25l" # 保存初始光标位置 echo -ne "\033[s" } # 切换缓冲区 swap_buffers() { # 恢复光标到初始位置 echo -ne "\033[u" # 显示后台缓冲区内容 cat $back_buffer # 交换缓冲区 temp=$current_buffer current_buffer=$back_buffer back_buffer=$temp # 清空新的后台缓冲区 > $back_buffer } # 绘制内容到后台缓冲区 draw_to_back_buffer() { # 将内容追加到后台缓冲区 echo -e "$@" >> $back_buffer } # 清理资源 cleanup() { # 显示光标 echo -ne "\033[?25h" # 删除临时文件 rm -f $buffer1 $buffer2 # 清屏 echo -ne "\033[2J\033[H" } # 计算剩余秒数 calculate_remaining() { current_epoch=$(date +%s) # 计算目标时间的Unix时间戳 target_date="${target_year}-${target_month}-${target_day} ${target_hour}:${target_minute}:${target_second}" target_epoch=$(date -d "$target_date" +%s 2>/dev/null) if [ -z "$target_epoch" ]; then draw_to_back_buffer "错误:无效的日期格式" return 1 fi remaining_seconds=$((target_epoch - current_epoch)) return 0 } # 格式化时间显示 format_time() { local seconds=$1 # 计算总天数 local total_days=$((seconds / 86400)) local years=$((seconds / 31536000)) seconds=$((seconds % 31536000)) local months=$((seconds / 2592000)) seconds=$((seconds % 2592000)) local days=$((seconds / 86400)) seconds=$((seconds % 86400)) local hours=$((seconds / 3600)) seconds=$((seconds % 3600)) local minutes=$((seconds / 60)) local secs=$((seconds % 60)) # 优化显示格式 printf "总天数:%d | %d年%02d月%02d日 %02d:%02d:%02d" $total_days $years $months $days $hours $minutes $secs } # 更新剩余时间 update_remaining() { if [ $is_running = true ] && [ $is_paused = false ]; then current_time=$(date +%s) # 确保每秒只更新一次 if [ $current_time -gt $last_update ]; then if [ $remaining_seconds -gt 0 ]; then remaining_seconds=$((remaining_seconds - 1)) last_update=$current_time return 0 # 需要刷新 else # 时间到处理 is_running=false draw_to_back_buffer "时间到!" echo -e "\a" # 发出提示音 return 1 # 需要刷新 fi fi fi return 2 # 不需要刷新 } # 构建菜单内容 build_menu() { # 清空后台缓冲区 > $back_buffer # 绘制菜单框架 draw_to_back_buffer "======== 双缓冲倒计时菜单 ========" draw_to_back_buffer "1. 设置目标时间" draw_to_back_buffer "2. 开始倒计时" draw_to_back_buffer "3. 暂停/继续" draw_to_back_buffer "4. 重置倒计时" draw_to_back_buffer "5. 退出程序" draw_to_back_buffer "===============================" # 显示目标时间 draw_to_back_buffer -n "当前目标: " if [ $target_year -ne 0 ]; then draw_to_back_buffer "$(printf "%d-%02d-%02d %02d:%02d:%02d" $target_year $target_month $target_day $target_hour $target_minute $target_second)" else draw_to_back_buffer "未设置" fi # 显示剩余时间 draw_to_back_buffer -n "剩余时间: " if [ $target_year -ne 0 ]; then if [ $is_running = true ] && [ $is_paused = false ]; then # 动态更新模式 draw_to_back_buffer "$(format_time $remaining_seconds) [运行中]" else # 静态显示模式 if calculate_remaining; then draw_to_back_buffer "$(format_time $remaining_seconds) [暂停]" else draw_to_back_buffer "计算错误" fi fi else draw_to_back_buffer "未设置" fi draw_to_back_buffer "===============================" draw_to_back_buffer -n "请选择操作 [1-5]: " } # 设置目标时间 set_target() { # 临时保存当前缓冲区状态 temp_buffer=$(mktemp) cat $back_buffer > $temp_buffer # 显示输入提示 draw_to_back_buffer "请输入年份 (YYYY): " swap_buffers # 修复: 使用替代方法读取输入 read_target() { # 使用替代方法读取输入,避免系统调用中断 while true; do # 尝试读取输入 if read input 2>/dev/null; then echo "$input" return 0 fi # 如果读取失败,短暂延迟后重试 sleep 0.1 done } target_year=$(read_target) draw_to_back_buffer "请输入月份 (1-12): " swap_buffers target_month=$(read_target) draw_to_back_buffer "请输入日期 (1-31): " swap_buffers target_day=$(read_target) draw_to_back_buffer "请输入小时 (0-23): " swap_buffers target_hour=$(read_target) draw_to_back_buffer "请输入分钟 (0-59): " swap_buffers target_minute=$(read_target) draw_to_back_buffer "请输入秒数 (0-59): " swap_buffers target_second=$(read_target) # 验证输入 valid=true case $target_year in [0-9][0-9][0-9][0-9]) ;; *) draw_to_back_buffer "错误: 年份必须是4位数字"; valid=false ;; esac case $target_month in 0[1-9]|1[0-2]|[1-9]) ;; *) draw_to_back_buffer "错误: 月份必须是1-12"; valid=false ;; esac case $target_day in 0[1-9]|[12][0-9]|3[01]|[1-9]) ;; *) draw_to_back_buffer "错误: 日期必须是1-31"; valid=false ;; esac case $target_hour in [01][0-9]|2[0-3]|[0-9]) ;; *) draw_to_back_buffer "错误: 小时必须是0-23"; valid=false ;; esac case $target_minute in [0-5][0-9]|[0-9]) ;; *) draw_to_back_buffer "错误: 分钟必须是0-59"; valid=false ;; esac case $target_second in [0-5][0-9]|[0-9]) ;; *) draw_to_back_buffer "错误: 秒数必须是0-59"; valid=false ;; esac if [ $valid = true ]; then # 计算剩余时间 if calculate_remaining; then if [ $remaining_seconds -le 0 ]; then draw_to_back_buffer "错误: 目标时间已过去!" else draw_to_back_buffer "目标时间已设置!" last_update=$(date +%s) fi fi fi swap_buffers sleep 1 # 恢复菜单状态 cat $temp_buffer > $back_buffer rm -f $temp_buffer } # 主程序入口 main() { # 初始化双缓冲系统 init_double_buffer # 初始构建菜单 build_menu swap_buffers # 主循环 while true; do # 更新剩余时间 update_remaining refresh_needed=$? # 检查是否需要刷新显示 if [ $refresh_needed -lt 2 ]; then build_menu swap_buffers fi # 修复: 使用替代方法进行非阻塞读取 # 替代方法: 检查标准输入是否有数据 if [ -t 0 ]; then # 检查是否有输入可用 if read -t 0; then # 读取单个字符 if read -n 1 choice 2>/dev/null; then case $choice in 1) set_target ;; 2) if [ $target_year -eq 0 ]; then draw_to_back_buffer "请先设置目标时间!" swap_buffers sleep 1 elif [ $is_running = true ]; then draw_to_back_buffer "倒计时已在运行中!" swap_buffers sleep 1 else is_running=true is_paused=false last_update=$(date +%s) draw_to_back_buffer "倒计时已开始!" swap_buffers sleep 0.5 fi ;; 3) if [ $is_running = true ]; then is_paused=$([ "$is_paused" = true ] && echo false || echo true) draw_to_back_buffer "已${is_paused:+"暂停":"继续"}" swap_buffers sleep 0.5 else draw_to_back_buffer "倒计时未运行!" swap_buffers sleep 0.5 fi ;; 4) target_year=0 target_month=0 target_day=0 target_hour=0 target_minute=0 target_second=0 remaining_seconds=0 is_running=false is_paused=true draw_to_back_buffer "已重置倒计时" swap_buffers sleep 0.5 ;; 5) cleanup echo "退出程序" exit 0 ;; *) draw_to_back_buffer "无效选择,请重新输入" swap_buffers sleep 0.5 ;; esac # 操作后重建菜单 build_menu swap_buffers fi fi fi # 添加短暂延迟,减少CPU使用率 sleep 0.1 done } # 启动主程序 main 不能用菜单了输入数字选项过后没有任何反应
08-17
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值