前言

圣诞节到了!

一口君在这祝各位粉丝朋友圣诞节快乐!

祝各位考研的同学金榜题名!

祝找工作的朋友offer接到爆!

祝各位老板新年大发财源!

在此一口君特地用shell脚本画了一个圣诞树!

先来看下执行结果吧!

那么要如何才能编写出这个特效的圣诞树呢?

下面一口君手把手教大家!

只想运行脚本的同学可以调到最后面!

一、shell脚本知识

1. shell变量

变量是任何一种编程语言都必不可少的组成部分,变量用来存放各种数据。脚本语言在定义变量时通常不需要指明类型,直接赋值就可以,Shell 变量也遵循这个规则。

Shell 支持以下三种定义变量的方式:

variable=value
variable='value'
variable="value"

variable 是变量名,value 是赋给变量的值。如果 value 不包含任何空白符(例如空格、Tab 缩进等),那么可以不使用引号;如果 value 包含了空白符,那么就必须使用引号包围起来。使用单引号和使用双引号也是有区别的,稍后我们会详细说明。

注意,赋值号=的周围不能有空格,这可能和你熟悉的大部分编程语言都不一样。

Shell 变量的命名规范和大部分编程语言都一样:

  • 变量名由数字、字母、下划线组成;
  • 必须以字母或者下划线开头;
  • 不能使用 Shell 里的关键字(通过 help 命令可以查看保留关键字)。

使用变量

使用一个定义过的变量,只要在变量名前面加美元符号$即可,如:

skill="C、Linux"
echo "I am good at ${skill}Script"

变量名外面的花括号{ }是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界.

如果不给 skill 变量加花括号,写成echo "I am good at $skillScript",解释器就会把 $skillScript 当成一个变量(其值为空),代码执行结果就不是我们期望的样子了。

修改变量的值

lin=2
let lin++

单引号和双引号的区别

定义变量时,变量的值可以由单引号' '包围,也可以由双引号" "包围,它们到底有什么区别呢?不妨以下面的代码为例来说明:

#!/bin/bash
name="一口Linux"
gzh1='公众号:${name}'
gzh2="C语言中文网:${name}"
echo $gzh1
echo $gzh2

运行结果:

公众号:${name}
公众号:一口Linux

以单引号' '包围变量的值时,单引号里面是什么就输出什么,即使内容中有变量和命令(命令需要反引起来)也会把它们原样输出。这种方式比较适合定义显示纯字符串的情况,即不希望解析变量、命令等的场景。

以双引号" "包围变量的值时,输出时会先解析里面的变量和命令,而不是把双引号中的变量名和命令原样输出。这种方式比较适合字符串中附带有变量和命令并且想将其解析后再输出的变量定义。

建议:

如果变量的内容是数字,那么可以不加引号;如果真的需要原样输出就加单引号;其他没有特别要求的字符串等最好都加上双引号,定义变量时加双引号是最常见的使用场景。

2. trap

trap命令是专用于捕捉信号的。比如像ctrl+c发送给终端的中断信号等等。在捕捉到信号之后,可以进行一系列的操作。

用法:

trap  'COMMAND' INT

COMMAND表示trap命令接收到INT信号后要执行的动作什么。

可以捕捉的信号有:HUP INT

不适用捕捉的信号:KILL TERM

信号回应方式

trap捕捉到信号之后,可以有三种反应方式:

  • 1、执行一段程序来处理这一信号
  • 2、接受信号的默认操作
  • 3、忽视这一信号

它有三种形式分别对应三种不同的信号回应方式

第一种:

trap ""commands"" signal-list

当脚本收到signal-list清单内列出的信号时,trap命令执行双引号中的命令.

第二种:

trap signal-list

trap不指定任何命令,接受信号的默认操作.默认操作是结束进程的运行.

第三种:

trap "" "" signal-list

trap命令指定一个空命令串,允许忽视信号.

使用trap -l命令可以查看信号有哪些:

# trap -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX

3. clear

清除终端屏幕

4. tput

tput 命令将通过 terminfo 数据库对您的终端会话进行初始化和操作。通过使用tput,您可以更改几项终端功能,如移动或更改光标、更改文本属性,以及清除终端屏幕的特定区域。

光标属性

tput sc          ##记录光标位置
tput cup x y ###移动光标至x列y行
tput rc ##返回光标位置
tput civis ##隐藏光标
tput cnorm ## 显示光标
tput setaf ColorNumber ## 设置前景色
tput setab ColorNumber ##设置背景色
tput clear # 清除屏幕
tput cup x y # 光标按设定坐标点移动

文本属性

tput blink      # 文本闪烁
tput bold # 文本加粗
tput el # 清除到行尾
tput smso # 启动突出模式
tput rmso # 停止突出模式
tput smul # 下划线模式
tput rmul # 取消下划线模式
tput sgr0 # 恢复默认终端
tput rev # 反相终端

此外,还可以改变文本的颜色

tput setb 颜色代号
tput setf 颜色代号

举例

#加粗
bold=$(tput bold)
#下划线
underline=$(tput sgr 0 1)
#重置规则
reset=$(tput sgr0)
#红色
red=$(tput setaf 1)
#绿色
green=$(tput setaf 2)

下面是一个带闪烁功能的时钟

#!/bin/bash

for ((i=0;i<8;i++))
do
tput sc; tput civis # 记录光标位置,及隐藏光标
tput blink; tput setf $i # 文本闪烁,更改文本颜色
echo -ne $(date +'%Y-%m-%d %H:%M:%S') # 显示时间
sleep 1
tput rc # 恢复光标到记录位置
done tput el; tput cnorm # 退出时清理终端,恢复光标显示

效果

5. for循环

for循环的运作方式,是讲串行的元素意义取出,依序放入指定的变量中,然后重复执行含括的命令区域(在do和done 之间),直到所有元素取尽为止。

其中,串行是一些字符串的组合,彼此用$IFS所定义的分隔符(如空格符)隔开,这些字符串称为字段。

for的语法结构如下:

1. for 变量 in 串行
2. do
3. 执行命令
4. done

说明:

行1,讲串行中的字段迭代放入变量中

行2-4,接着将重复执行do和done之间的命令区域,直到串行中每一个字段均处理过为止。

举例

用for循环在家目录下创建aaa1-aaa10,然后在aaa1-aaa10创建bbb1-bbb10的目录

1. #!/bin/bash
2. for k in $( seq 1 10 )
3. do
4. mkdir /home/peng/aaa${k}
5. cd /home/peng/aaa${k}
6. for l in $( seq 1 10 )
7. do
8. mkdir bbb${l}
9. cd /home/peng/aaa${k}
10. done
11. cd ..
done

列出var目录下各子目录占用磁盘空间的大小。

#!/bin/bash
DIR="/var"
cd $DIR
for k in $(ls $DIR)
do
[ -d $k ] && du -sh $k
done

6. while循环

while循环的语法:

1. while 条件测试
2. do
3. 执行命令
4. done

说明:

行1,首先进行条件测试,如果传回值为0(条件测试为真),则进入循环,执行命令区域,否则
不进入循环,介绍while 命令
行3,执行命令区域,这些命令中,应该要有改变条件测试的命令,这样,才有机会在
有限步骤后结束执行while循环(除非想要执行无穷循环)。
行4,回到行1,执行while命令

流程图:

实例

计算1+2+3…………10

#!/bin/bash
declare -i i=1
declare -i sum=0
while ((i<=10))
do
let sum+=i
let ++i
done
echo $sum

二、圣诞树脚本文件

#!/bin/bash
#用shell编写一个圣诞树
#创建时间2021-12-23
trap "tput reset; tput cnorm; exit" 2
clear
tput civis
lin=2
col=$(($(tput cols) / 2))
c=$((col-1))
est=$((c-2))
color=0
tput setaf 2; tput bold # 打印树叶
for ((i=1; i<20; i+=2))
{
tput cup $lin $col
for ((j=1; j<=i; j++))
{
echo -n \*
}
let lin++
let col--
} tput sgr0; tput setaf 3 # 打印树干
for ((i=1; i<=2; i++))
{
tput cup $((lin++)) $c
echo '||'
}
new_year=$(date +'%Y')
let new_year++
tput setaf 222; tput bold
tput cup $lin $((c - 10)); echo $new_year 圣 诞 节 快 乐!!!
color=122
tput setaf $color; tput bold
tput cup $((lin + 1)) $((c - 10)); echo 关注公众号: 一口Linux!
let c++
k=1 #装饰一下
while true; do
for ((i=1; i<=35; i++)) {
# Turn off the lights
[ $k -gt 1 ] && {
tput setaf 2; tput bold
tput cup ${line[$[k-1]$i]} ${column[$[k-1]$i]}; echo \*
unset line[$[k-1]$i]; unset column[$[k-1]$i]
} li=$((RANDOM % 9 + 3))
start=$((c-li+2))
co=$((RANDOM % (li-2) * 2 + 1 + start))
tput setaf $color; tput bold
tput cup $li $co
echo o
line[$k$i]=$li
column[$k$i]=$co
color=$(((color+1)%8)) sh=1
#for l in M O N E Y
for l in 一 口 Li nu x!
do
tput cup $((lin+1)) $((c+sh))
echo $l
let sh++
let sh++
sleep 0.02
done
}
k=$((k % 2 + 1))
done

三、执行脚本

root@ubuntu:/home/peng/work/test# chmod 777 peng.sh
root@ubuntu:/home/peng/work/test# ./peng.sh

还等什么呢?抓紧运行起来吧!

圣诞节快乐,教你用shell脚本实现一颗圣诞树。【小酷炫】的更多相关文章

  1. 该死的端口占用!教你用 Shell 脚本一键干掉它!

    1. 前言 大家好,我是安果! 在 Web 开发中,经常会遇到「端口被占用」的场景 常规解决方案是: 使用 lsof -i 命令查询占用端口的进程 PID 利用 kill -9 PID 干掉目标进程 ...

  2. shell脚本编程之变量的小用法

    变量赋值 ${parameter:-word}:如果parameter为空或未定义,则变量展开为"word":否则,展开为parameter的值: ${parameter:+wor ...

  3. 浅谈自底向上的Shell脚本编程及效率优化

    作者:沐星晨 出处:http://blog.csdn.net/sosodream/article/details/6276758 浅谈自底向上的Shell脚本编程及效率优化 小论文,大家多批评指导:) ...

  4. 拾遗:Perl 在 Shell 脚本编程中的应用

    Perl 对我用途,仅是作为 Shell 脚本中的文本处理器:在较大的软件工程里,更多的是使用 C.go 等编译型语言. Perl 是一种历史比较悠久的动态编程语言,在各种类 Unix 系统中得到了应 ...

  5. 使用C#给Linux写Shell脚本

    在这个逼格决定人格,鄙视链盛行的年头,尤其是咱们IT界,请问您今天鄙视与被鄙视的次数分别是多少?如果手中没有一点压箱的本事,那就只有看的份了.今天我们也要提升下自己的格调,学习些脑洞大开的东西,学完之 ...

  6. 教你用shell写CGI程序

    以前用shell写过一些cgi的例子.今天向大家介绍一下. CGI是一种接口的标准,并不区分编程语言,也就是说,CGI可以用任何一种语言编写,只要这种语言具有标准输入.输出和环境变量.CGI会将标准输 ...

  7. shell脚本一键同步集群时间

    shell脚本一键同步集群时间 弋嘤捕大 椿澄辄 ψ壤 茇徜燕 ㄢ交涔沔 阚龇棚绍 テ趼蜱棣 灵打了个寒颤也没有去甩脱愣是拖着 喇吉辔 秋北酏崖 琮淄脸酷 茇呶剑 莲夤罱 陕遇骸淫  ...

  8. curl命令,curl实现post,curl监控网页shell脚本,curl多进程实现并控制进程数,

    cURL > Docs > Tutorial:  http://curl.haxx.se/docs/httpscripting.html 下载单个文件,默认将输出打印到标准输出中(STDO ...

  9. 通过java程序(JSch)运行远程linux主机上的shell脚本

    如果您看完文章之后,觉得对您有帮助,请帮我点个赞,您的支持是我不竭的创作动力! 如果您看完文章之后,觉得对您有帮助,请帮我点个赞,您的支持是我不竭的创作动力! 如果您看完文章之后,觉得对您有帮助,请帮 ...

  10. 用 shell 脚本做命令行工具扩展

    问题的提出 公司开发机与远程服务器之间有严格的隔离策略,不能直接使用 ssh 登录,而必需通过跳板机.这样一来,本地与服务器之间的一些文件传输变得非常不便.经过咨询,运维教了我一招: $ nc -l ...

随机推荐

  1. 认真学习css3--01-全是日志没有技术内容

    由于某些原因,还是要写写前端代码. 虽然这不是我的主要责任,但也有表率的必要性. css3这个东西没有什么大难度,难点主要集中在: 1)样式比较多 2)精准定位 3)性能优化 其中第2个是日常经常面对 ...

  2. C#/.NET这些实用的技巧和知识点你都知道吗?

    前言 今天大姚给大家分享一些C#/.NET中的实用的技巧和知识点,它们可以帮助我们提升代码质量和编程效率,希望可以帮助到有需要的同学. .NET使用CsvHelper快速读取和写入CSV文件 本文主要 ...

  3. 安卓内核编译:关闭"error, forbidden warning"

    安卓内核编译:关闭error, forbidden warning 背景 最近在编译Android kernel时,遇到error, forbidden warning, 导致编译中断,大大降低了de ...

  4. Freertos学习:01 移植到STM32

    --- title: rtos-freertos-01-移植到STM32 EntryName: rtos-freertos-01-porting-on-stm32 date: 2020-06-17 1 ...

  5. 随机数据下 Sqrt Tree 的平替实现

    原理 在随机数据下,把原序列分成 \(\sqrt n\) 个块,维护每个块的前缀后缀最大值,那么,在随机询问下,对于在一个块中的询问,暴力查询. 复杂度 概率 $ n ^ {-\frac{1}{2}} ...

  6. Spring注解之参数校验@Validated和@Valid

    @Validated和@Valid的区别 Spring Validation验证框架对参数的验证机制提供了@Validated(Spring's JSR-303 规范,是标准 JSR-303 的一个变 ...

  7. Docker开启远程安全访问

    一.编辑docker.service文件 vi /usr/lib/systemd/system/docker.service 找到 [Service] 节点,修改 ExecStart 属性,增加 -H ...

  8. Java-Filter:过滤器请求拦截

    1.概念 web中的过滤器:当访问服务器资源时,过滤器可以将请求拦截下来,完成一些特殊的功能 过滤器的作用: 一般用于完成通用的操作,如:登录验证,统一编码处理,敏感字符过滤 2.快速入门 1.步骤 ...

  9. BS架构和CS架构应用

    概述     B/S结构即浏览器和服务器结构.它是随着Internet技术的兴起,对C/S结构的一种变化或者改进的结构.在这种结构下,用户工作界面是通过WWW浏览器来实现,极少部分事务逻辑在前端(Br ...

  10. tp5生命周期

    https://www.kancloud.cn/manual/thinkphp5/118011 1.入口文件 用户发起的请求都会经过应用的入口文件,通常是 public/index.php文件.当然, ...