每日积累(20170117-day-22)(shell: set x e $#,$@,$0,$1,$2)

本文详细介绍了Shell脚本中set-e的作用、常见shell变量$#、$@、$0、$1等的含义,并对shell下的set命令进行了深入解析。

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

#!/system/bin/sh # ANSI 颜色定义 red="\e[31m" green="\e[32m" yellow="\e[33m" blue="\e[34m" magenta="\e[35m" cyan="\e极简[36m" reset="\e[0m" bold="\e[1m" reset_bold="\e[22m" # 默认目标时间 target="2028-01-01 00:00:00" # 精确日期计算函数 calculate_date_diff() { # 获取当前日期时间 current_year=$(date +"%Y") current_month=$(date +"%m") current_day=$(date +"%d") current_hour=$(date +"%H") current_minute=$(date +"%M") current_second=$(date +"%S") # 解析目标日期时间 target_year=$(echo "$target" | cut -d'-' -f1) target_month=$(echo "$target" | cut -d'-' -f2) target_day=$(echo "$target" | cut -d' ' -f1 | cut -d'-' -f3) target_time=$(echo "$target" | cut -d' ' -f2) target_hour=$(echo "$target_time" | cut -d':' -f1) target_minute=$(echo "$target_time" | cut -d':' -f2) target_second=$(echo "$target_time" | cut -d':' -f3) # 1. 计算年份差 years=$((target_year - current_year)) # 2. 计算月份差(考虑年份进位) months=$((target_month - current_month)) if [ $months -lt 0 ]; then years=$((years - 1)) months=$((months + 12)) fi # 3. 计算天数差(考虑闰年和月份进位) # 计算当前月份的天数 case $current_month in 01|03|05|07|08|10|12) month_days=31 ;; 04|06|09|11) month_days=30 ;; 02) # 修复闰年判断错误(移除无效的"极简") if [ $((current_year % 4)) -eq 0 ] && [ $((current_year % 100)) -ne 0 ] || [ $((current_year % 400)) -eq 0 ]; then month_days=29 else month_days=28 fi ;; esac days=$((target_day - current_day)) if [ $days -lt 0 ]; then months=$((months - 1)) if [ $months -lt 0 ]; then years=$((years - 1)) months=11 fi days=$((days + month_days)) fi # 4. 计算小时差(考虑天数进位) hours=$((target_hour - current_hour)) if [ $hours -极简lt 0 ]; then days=$((days - 1)) hours=$((hours + 24)) fi # 5. 计算分钟差(考虑小时进位) minutes=$((target_minute - current_minute)) if [ $minutes -lt 0 ]; then hours=$((hours - 1)) minutes=$((minutes + 60)) fi # 6. 计算秒数差(考虑分钟进位) seconds=$((target_second - current_second)) if [ $seconds -lt 0 ]; then minutes=$((minutes - 1)) seconds=$((seconds + 60)) fi # 处理负值(时间已过) if [ $years -lt 0 ] || [ $months -lt 0 ] || [ $days -lt 0 ] || [ $hours -lt 0 ] || [ $minutes -lt 0 ] || [ $seconds -lt 0 ]; then echo "0 0 0 0 0 0" return 1 fi # 计算总天数(用于显示) total_days=$((years * 365 + months * 30 + days)) # 近似值 echo "$years $months $days $hours $minutes $seconds $total_days" return 0 } # 检查目标时间是否已过 check_target() { result=$(calculate_date_diff) if [ $? -ne 0 ]; then echo -e "${red}目标时间已过${reset}" return 1 fi return 0 } # 设置目标时间 set_target() { clear echo -e "${bold}${cyan}===== 设置目标时间 =====${reset}${reset_bold}" # 获取当前时间作为默认值 current_year=$(date +"%Y") current_month=$(date +"%m") current_day=$(date +"%d") current_hour=$(date +"%H") current_minute=$(date +"%M") current_second=$(date +"%S") # 年份验证 while true; do echo -n "请输入年份 (YYYY) [默认 $current_year]: " read year year=${year:-$current_year} if echo "$year" | grep -qE '^[0-9]{4}$'; then break else echo -e "${red}错误: 年份必须是4位数字${reset}" fi done # 月份验证 while true; do echo -n "请输入月份 (1-12) [默认 $current_month]: " read month month=${month:-$current_month} if echo "$month" | grep -qE '^(0[1-9]|1[0-2]|[1-9])$'; then break else echo -e "${red}错误: 月份必须是1-12${reset}" fi done # 日期验证 while true; do echo -n "请输入日期 (1-31) [默认 $current_day]: " read day day=${day:-$current_day} if echo "$day" | grep -qE '^(0[1-9]|[12][0-9]|3[01]|[1-9])$'; then # 验证日期是否有效 case $month in 02) if [ $((year % 4)) -eq 0 ] && [ $((year % 100)) -ne 0 ] || [ $((year % 400)) -eq 0 ]; then max_day=29 else max_day=28 fi ;; 04|06|09|11) max_day=30 ;; *) max_day=31 ;; esac if [ $day -le $max_day ] && [ $day -ge 1 ]; then break else echo -e "${red}错误: $year年$month月最多有 $max_day${reset}" fi else echo -e "${red}错误: 日期必须是1-31${reset}" fi done # 小时验证 while true; do # 修复提示信息(移除"极简") echo -n "请输入小时 (0-23) [默认 $current_hour]: " read hour hour=${hour:-$current_hour} if echo "$hour" | grep -qE '^([01][0-9]|2[0-3]|[0-9])$'; then break else echo -e "${red}错误: 小时必须是0-23${reset}" fi done # 分钟验证 while true; do echo -n "请输入分钟 (0-59) [默认 $current_minute]: " read minute minute=${minute:-$current_minute} if echo "$minute" | grep -qE '^([0-5][0-9]|[0-9])$'; then break else echo -e "${red}错误: 分钟必须是0-59${reset}" fi done # 秒数验证 while true; do echo -n "请输入秒数 (0-59) [默认 $current_second]: " read second second=${second:-$current_second} if echo "$second" | grep -qE '^([0-5][0-9]|[极简0-9])$'; then break else echo -e "${red}错误: 秒数必须是0-59${reset}" fi done # 设置目标时间 target="${year}-${month}-${day} ${hour}:${minute}:${second}" if ! check_target; then return 1 fi echo -e "${green}目标时间已设置为: ${cyan}$target${reset}" sleep 2 return 0 } # 主菜单 show_menu() { while true; do clear echo -e "${bold}${magenta}===== 彩色倒计时菜单 =====${reset}${reset_bold}" echo -e "${green}1. 🕰设置目标时间🕰" echo -e "${blue}2. 👀查看倒计时👀" echo -e "${yellow}3. ✨退出程序✨${reset}" echo -e "${bold}${magenta}====Z=====Z=====J======开源${reset}${reset_bold}" echo -n "请选择操作 [1-3]: " read choice case $choice in 1) set_target ;; 2) if check_target; then main_loop else echo -e "${red}请设置有效的目标时间${reset}" sleep 2 fi ;; 3) clear echo -e "${cyan}⭐感谢使用ZJ彩色倒计时程序⭐${reset}" exit 0 ;; *) echo -e "${red}无效选择,请重新输入${reset}" sleep 1 ;; esac done } # 主循环 - 防闪烁优化版 main_loop() { # 获取终端尺寸 cols=$(stty size 2>/dev/null | awk '{print $2}') [ -z "$cols" ] && cols=80 # 艺术字标题 title="🕒 ZJ倒计时显示器 🕒" title_len=${#title} padding=$(( (cols - title_len) / 2 )) # 隐藏光标 echo -e "\033[?25l" # 初始清屏 clear # 绘制静态框架 echo -ne "\033[1;1H" # 光标定位到左上角 printf "%${padding}s" "" echo -e "${bold}${magenta}$title${reset}${reset_bold}" echo -e "┌──────────────────────┬──────────────────────┐" echo -e "│ ${bold}${cyan}当前时间${reset_bold} │ ${bold}${yellow}目标时间${reset_bold} │" # 修复标题 echo -e "├──────────────────────┼──────────────────────┤" echo -e "│ │ │" # 预留时间行 echo -e "└──────────────────────┴──────────────────────┘" echo -e "\n${bold}${magenta}⏳ 倒计时剩余${reset_bold}" echo -e "┌───────────┬───────────┬───────────┬───────────┬───────────┬───────────┐" echo -e "│ ${bold}${red}年${reset_bold} │ ${bold}${green}月${reset_bold} │ ${bold}${blue}天${reset_bold} │ ${bold}${magenta}时${reset_bold} │ ${bold}${yellow}分${reset_bold} │ ${bold}${cyan}秒${reset_bold} │" echo -e "├───────────┼───────────┼───────────┼───────────┼───────────┼───────────┤" echo -e "│ │ │ │ │ │ │" # 预留数据行 echo -e "└───────────┴───────────┴───────────┴───────────┴───────────┴───────────┘" echo -e " ${bold}📌 总计: ${reset}${reset_bold}" # 预留进度条位置 echo -e "\n${bold}🌞 今日进度${reset_bold}" echo -e "[${yellow}${reset}${blue}${reset}]" echo -e "\n${bold}📅 总体进度${reset_bold}" echo -e "[${red}${reset}${green}${reset}]" # 预留节日提示位置 echo -e "\n\n" # 底部提示 echo -e "\n${bold}${magenta}按 [M] 键返回菜单${reset}${reset_bold}" # 记录静态框架行数 static_lines=18 while true; do loop_start=$(date +%s.%N) # 获取当前时间 current_time=$(date +"%Y-%m-%d %H:%M:%S") hour=$(date +"%H") minute=$(date +"%M") second=$(date +"%S") # 计算精确倒计时 result=$(calculate_date_diff) years=$(echo $result | awk '{print $1}') months=$(echo $result | awk '{print $2}') days=$(echo $result | awk '{print $3}') hours=$(echo $result | awk '{print $4}') minutes=$(echo $result | awk '{print $5}') seconds=$(echo $result | awk '{print $6}') total_days=$(echo $result | awk '{print $7}') # ==== 动态更新区域 ==== # 1. 更新当前时间和目标时间 (第4行) echo -ne "\033[4;1H" printf "│ ${green}%-20s${reset} │ ${blue}%-20s${reset} │" "$current_time" "$target" # 2. 更新倒计时数据 (10) echo -ne "\033[10;1H" printf "│ ${red}%3s${reset} │ ${green}%3s${reset} │ ${blue}%3s${reset} │ ${magenta}%3s${reset} │ ${yellow}%3s${reset} │ ${cyan}%3s${reset} │" $years $months $days $hours $minutes $seconds # 3. 更新总计天数 (12) echo -ne "\033[12;1H" echo -ne " ${bold}📌 总计: ${red}${total_days}${reset}${reset_bold}天" # 4. 更新进度条 # 今日进度 day_progress=$(( (10#$hour * 60 + 10#$minute) * 100 / (24 * 60) )) # 总体进度 total_progress=$(( total_days > 0 ? (years*365 + months*30 + days) * 100 / total_days : 0 )) # 构建进度条 bar_len=$((cols - 10)) day_filled=$((day_progress * bar_len / 100)) total_filled=$((total_progress * bar_len / 100)) # 更新今日进度条 (14行) echo -ne "\033[14;1H" printf "[${yellow}%${day_filled}s${reset}${blue}%$((bar_len - day_filled))s${reset}] ${green}%3d%%${reset}" "" "" $day_progress | sed 's/ /▊/g' # 更新总体进度条 (16行) echo -ne "\033[16;1H" if [ $total_days -gt 0 ]; then printf "[${red}%${total_filled}s${reset}${green}%$((bar_len - total_filled))s${reset}] ${cyan}%3d%%${reset}" "" "" $total_progress | sed 's/ /■/g' else echo -n "" # 清空行 fi # 5. 更新时间艺术装饰 (18行) time_art="" case $((seconds % 4)) in 0) time_art="⏳ → → →" ;; 1) time_art="→ ⏳ → →" ;; 2) time_art="→ → ⏳ →" ;; 3) time_art="→ → → ⏳" ;; esac echo -ne "\033[18;1H" echo -ne "${bold}${cyan}$time_art${reset}${reset_bold}" # 6. 更新节日提示 (19行) echo -ne "\033[19;1H" case "$(date +%m-%d)" in "01-01") echo -ne "${bold}🎉 ${yellow}新年快乐!新的开始!${reset}${reset_bold}" ;; "02-14") echo -ne "${bold}💖 ${magenta}情人节快乐!爱在身边!${reset}${reset_bold}" ;; "05-01") echo -ne "${bold}👷 ${green}劳动节快乐!致敬劳动者!${reset}${reset_bold}" ;; "10-01") echo -ne "${bold}🇨🇳 ${red}国庆节快乐!繁荣昌盛!${reset}${reset_bold}" ;; "12-25") echo -ne "${bold}🎄 ${cyan}圣诞快乐!温暖相伴!${reset}${reset_bold}" ;; *) echo -ne "\033[0J" ;; # 清除行 esac # 清除可能残留内容 echo -ne "\033[$((static_lines+1));1H\033[0J" # 按键检测 if read -t 0.1 -n 1 key; then if [[ $key == "m" || $key == "M" ]]; then # 显示光标 echo -e "\033[?25h" return fi fi # 动态睡眠 loop_end=$(date +%s.%N) loop_time=$(echo "$loop_end - $loop_start" | bc) sleep_time=$(echo "1.0 - $loop_time" | bc) sleep $([ $(echo "$sleep_time > 0" | bc) -eq 1 ] && echo $sleep_time || echo 0.05) done # 显示光标 echo -e "\033[?25h" } # 启动程序 show_menu 里面还是有极简字体,并且选项菜单2进不去提示目标时间已过
最新发布
08-17
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值