当前位置: 首页 > 科技观察

圣诞节快乐!教你用Shell脚本实现一棵圣诞树!

时间:2023-03-16 11:33:26 科技观察

那么怎么才能写出这棵有特效的圣诞树呢?让我教你怎么做!只想运行脚本的同学可以直接跳到最后!一、Shell脚本知识1、Shell变量变量是任何编程语言必不可少的组成部分,变量用来存储各种数据。脚本语言在定义变量时通常不需要指定类型,直接赋值即可,Shell变量也遵循这一规则。Shell支持以下三种定义变量的方式:variable=valuevariable='value'variable="value"variable是变量的名字,value是赋给变量的值。如果该值不包含任何空格(例如空格、制表符缩进等),则不能使用引号;如果该值包含空格,则必须用引号将其括起来。使用单引号和使用双引号也有区别,我们稍后会详细说明。注意赋值号=两边不能有空格,这可能和你熟悉的大多数编程语言不一样。shell变量的命名约定与大多数编程语言相同:变量名由数字、字母和下划线组成;它们必须以字母或下划线开头;shell中的关键字不能使用(可以通过help命令查看保留关键字)。使用变量要使用定义的变量,只需在变量名前加一个美元符号$即可,如:skill="C,Linux"echo"Iamgoodat${skill}Script"变量名外的花括号{}是optional是的,加不加都无所谓。添加花括号是为了帮助解释器识别变量的边界。如果不给skill变量加花括号写echo"Iamgoodat$skillScript",解释器会把$skillScript当作一个变量(它的值为空),代码执行的结果不是我们期望的.修改变量的值lin=2letlin++单引号和双引号的区别定义变量时,变量的值可以用单引号''括起来,也可以用双引号""括起来。它们之间有什么区别?我们用下面的代码以此为例:#!/bin/bashname="一口Linux"gzh1='公众号:${name}'gzh2="C语言中文网址:${name}"echo$gzh1echo$gzh2运行结果:公众号:${name}公众号:一口Linux变量的值用单引号''括起来时,单引号内的内容都会输出,即使有内容中是变量和命令(命令需要倒过来),也会输出都是原样输出。这种方式比较适合定义和显示纯字符串,即不想解析变量、命令等的场景。当用双引号""括住变量的值时,里面的变量和命令将是输出时先解析,而不是原样输出双引号内的变量名和命令。这种方法更适用于在字符串中附加了变量和命令并希望在输出之前解析它们的变量定义。建议:如果变量的内容是数字,可以不用引号;如果确实需要原样输出,加单引号;其他没有特殊要求的字符串最好加双引号。在定义变量的时候加上双引号是最好的常见使用场景。2.traptrap命令专门用于捕获信号。比如像ctrl+c给终端发送的中断信号等,捕获到信号后,就可以进行一系列的操作了。用法:trap'COMMAND'INTCOMMAND表示trap命令接收到INT信号后要执行的动作。可以捕获的信号有:HUPINT其他不适合捕获的信号:KILLTERM信号响应方式trap捕获到信号后,有3种响应方式:1.执行一个程序处理这个信号2.接受信号31的默认操作。忽略此信号。它有三种形式对应三种不同的信号响应方式。第一种:trap""commands""signal-list当脚本接收到signal-list列表中列出的信号时,trap命令执行双引号中的命令。第二种:trapsignal-listtrap不指定任何命令,接受信号的默认操作。默认操作是结束进程的运行。第三种:trap""""signal-listtrap命令指定一个空命令串,允许忽略信号。使用trap-l命令查看哪些信号是:#trap-l1)SIGHUP2)SIGINT3)SIGQUIT4)SIGILL5)SIGTRAP6)SIGABRT7)SIGBUS8)SIGFPE9)SIGKILL10)SIGUSR111)SIGSEGV12)SIGUSR213)SIGPIPE14)SIGALRM15)SIGTERM16)SIGSIGFLT18))SIGCONT19)SIGSTOP20)SIGTSTP21)SIGTTIN22)SIGTTOU23)SIGURG24)SIGXCPU25)SIGXFSZ26)SIGVTALRM27)SIGPROF28)SIGWINCH29)SIGIO30)SIGPWR31)SIGSYS34)SIGRTMIN35)SIGRTMIN+136)SIGRTMIN+237)SIGRTMIN+338)SIGRTMIN+439)SIGRTMIN+540)SIGRTMIN+641)SIGRTMIN+742)SIGRTMIN+843)SIGRTMIN+944)SIGRTMIN+1045)SIGRTMIN+1146)SIGRTMIN+1247)SIGRTMIN+1348)SIGRTMIN+1449)SIGRTMIN+1550)SIGRTMAXG-1451)1352)SIGRTMAX-1253)SIGRTMAX-1154)SIGRTMAX-1055)SIGRTMAX-956)SIGRTMAX-857)SIGRTMAX-758)SIGRTMAX-659)SIGRTMAX-560)SIGRTMAX-461)SIGRTMAX-362)SIGRTMAX-263)SIGRTMAX-164)SIGRTMAX3.clear清除终端屏幕4.tputtput命令将通过terminfo数据库到您的终端会话初始化和操作通过使用tput,您可以更改多个终端功能,例如移动或更改光标、更改文本属性以及清除终端屏幕的特定区域。光标属性tputsc##记录光标位置tputcupxy###移动光标到x列y行tputrc##返回光标位置tputcivis##隐藏光标tputcnorm##显示光标tputsetafColorNumber##设置前景色tputsetabColorNumber##设置背景色tputclear#Clear屏幕tputcupxy#光标根据设置的坐标点移动文字属性tputblink#文字闪烁tputbold#文字加粗tputel#清除到行尾tputsmso#开启高亮模式tputrmso#停止高亮模式tputsmul#下划线模式tputrmul#取消下划线模式tputsgr0#恢复默认Terminaltputrev#Reverseterminal另外还可以改变文字的颜色)#Redred=$(tputsetaf1)#greengreen=$(tputsetaf2)下面是一个带闪烁功能的时钟#!/bin/bashfor((i=0;i<8;i++))dotputsc;tputcivis#记录下光标位置,并隐藏光标tputblink;tputsetf$i#文字闪烁,改变文字颜色echo-ne$(date+'%Y-%m-%d%H:%M:%S')#显示时间sleep1tputrc#恢复光标到记录位置doneputel;tputcnorm#Clean退出时up终端,恢复光标显示效果5.for循环for循环的运行方式是提取连续元素的含义,依次放入指定变量中,然后重复执行封闭的命令区(在do和done之间),直到所有元素都用完。其中,serial是一些字符串的组合,相互之间用$IFS定义的分隔符(如空格字符)分隔,这些字符串称为字段。for的语法结构如下:1.forvariableinserial2.do3.执行命令4.done解释:第1行,将serial中的字段迭代放入变量第2-4行,然后重复执行之间的do和done命令区域,直到序列中的每个字段都已处理。比如用for循环在home目录下创建aaa1-aaa10,然后在aaa1-aaa10下创建bbb1-bbb10的目录1.#!/bin/bash2.forkin$(seq110)3.do4.mkdir/home/peng/aaa${k}5.cd/home/peng/aaa${k}6.forlin$(seq110)7.do8.mkdirbbb${l}9.cd/home/peng/aaa${k}10.done11.cd。.done列出了var目录下每个子目录占用的磁盘空间。#!/bin/bashDIR="/var"cd$DIRforkin$(ls$DIR)do[-d$k]&&du-sh$kdone6.while循环while循环的语法:1.while条件测试2.do3.execution命令4.done说明:第1行,首先进行条件测试,如果返回值为0(条件测试为真),则进入循环并执行命令区,否则不进入循环,引入while命令行3,执行命令区,在这些命令中,应该有改变条件测试的命令,这样有限个数后才有机会结束while循环步骤(除非你想做一个无限循环)。第4行,回到第1行,执行while命令流程图:示例计算1+2+3…………10#!/bin/bashdeclare-ii=1declare-isum=0while((i<=10))doletsum+=ilet++idoneecho$sum2.圣诞树脚本文件#!/bin/bash#用shell写圣诞树#创建时间2021-12-23trap"tputreset;tputcnorm;exit"2cleartputcivislin=2col=$(($(tputcols)/2))c=$((col-1))est=$((c-2))color=0tputsetaf2;tputbold#printleavesfor((i=1;i<20;i+=2)){tputcup$lin$colfor((j=1;j<=i;j++)){echo-n\*}letlin++letcol--}tputsgr0;tputsetaf3#printtrunkfor((i=1;i<=2;i++)){tputcup$((lin++))$cecho'||'}new_year=$(date+'%Y')letnew_year++tputsetaf222;tputboldtputcup$lin$((c-10));echo$new_year圣诞快乐!!!color=122tputsetaf$color;tputboldtputcup$((lin+1))$((c-10));echo跟随公众号:满口Linux!letc++k=1#decoratewhiletrue;dofor((i=1;i<=35;i++)){#Turnoffthelights[$k-gt1]&&{tputsetaf2;tputboldtputcup${line[$[k-1]$i]}${column[$[k-1]$i]};echo\*unsetline[$[k-1]$i];unsetcolumn[$[k-1]$i]}li=$((RANDOM%9+3))start=$((c-li+2))co=$((RANDOM%(li-2)*2+1+start))tputsetaf$color;tputboldtputcup$li$coechooline[$k$i]=$licolumn[$k$i]=$cocolor=$(((color+1)%8))sh=1#forlinMONEYforlin一口Linux!dotputcup$((lin+1))$((c+sh))echo$lletsh++letsh++sleep0.02done}k=$((k%2+1))done3.执行脚本root@ubuntu:/home/peng/work/test#chmod777peng.shroot@ubuntu:/home/peng/work/test#./peng.sh你还在等什么?快点运行吧!