那么要如何才能編寫出這個(gè)特效的圣誕樹(shù)呢?
下面一口君手把手教大家!
只想運(yùn)行腳本的同學(xué)可以跳到最后面!
一、shell腳本知識(shí)
1. shell變量
變量是任何一種編程語(yǔ)言都必不可少的組成部分,變量用來(lái)存放各種數(shù)據(jù)。腳本語(yǔ)言在定義變量時(shí)通常不需要指明類型,直接賦值就可以,Shell 變量也遵循這個(gè)規(guī)則。Shell 支持以下三種定義變量的方式:
- variable=value
- variable='value'
- variable="value"
variable 是變量名,value 是賦給變量的值。如果 value 不包含任何空白符(例如空格、Tab 縮進(jìn)等),那么可以不使用引號(hào);如果 value 包含了空白符,那么就必須使用引號(hào)包圍起來(lái)。使用單引號(hào)和使用雙引號(hào)也是有區(qū)別的,稍后我們會(huì)詳細(xì)說(shuō)明。
注意,賦值號(hào)=的周圍不能有空格,這可能和你熟悉的大部分編程語(yǔ)言都不一樣。
Shell 變量的命名規(guī)范和大部分編程語(yǔ)言都一樣:
- 變量名由數(shù)字、字母、下劃線組成;
- 必須以字母或者下劃線開(kāi)頭;
- 不能使用 Shell 里的關(guān)鍵字(通過(guò) help 命令可以查看保留關(guān)鍵字)。
使用變量
使用一個(gè)定義過(guò)的變量,只要在變量名前面加美元符號(hào)$即可,如:
- skill="C、Linux"
- echo "I am good at ${skill}Script"
變量名外面的花括號(hào){ }是可選的,加不加都行,加花括號(hào)是為了幫助解釋器識(shí)別變量的邊界. 如果不給 skill 變量加花括號(hào),寫成echo "I am good at $skillScript",解釋器就會(huì)把 $skillScript 當(dāng)成一個(gè)變量(其值為空),代碼執(zhí)行結(jié)果就不是我們期望的樣子了。
修改變量的值
- lin=2
- let lin++
單引號(hào)和雙引號(hào)的區(qū)別
定義變量時(shí),變量的值可以由單引號(hào)' '包圍,也可以由雙引號(hào)" "包圍,它們到底有什么區(qū)別呢?不妨以下面的代碼為例來(lái)說(shuō)明:
- #!/bin/bash
- name="一口Linux"
- gzh1='公眾號(hào):${name}'
- gzh2="C語(yǔ)言中文網(wǎng):${name}"
- echo $gzh1
- echo $gzh2
運(yùn)行結(jié)果:
- 公眾號(hào):${name}
- 公眾號(hào):一口Linux
以單引號(hào)' '包圍變量的值時(shí),單引號(hào)里面是什么就輸出什么,即使內(nèi)容中有變量和命令(命令需要反引起來(lái))也會(huì)把它們?cè)瓨虞敵觥_@種方式比較適合定義顯示純字符串的情況,即不希望解析變量、命令等的場(chǎng)景。
以雙引號(hào)" "包圍變量的值時(shí),輸出時(shí)會(huì)先解析里面的變量和命令,而不是把雙引號(hào)中的變量名和命令原樣輸出。這種方式比較適合字符串中附帶有變量和命令并且想將其解析后再輸出的變量定義。
建議:如果變量的內(nèi)容是數(shù)字,那么可以不加引號(hào);如果真的需要原樣輸出就加單引號(hào);其他沒(méi)有特別要求的字符串等最好都加上雙引號(hào),定義變量時(shí)加雙引號(hào)是最常見(jiàn)的使用場(chǎng)景。
2. trap
trap命令是專用于捕捉信號(hào)的。比如像ctrl+c發(fā)送給終端的中斷信號(hào)等等。在捕捉到信號(hào)之后,可以進(jìn)行一系列的操作。
用法:
- trap 'COMMAND' INT
COMMAND表示trap命令接收到INT信號(hào)后要執(zhí)行的動(dòng)作什么。
可以捕捉的信號(hào)有:HUP INT等 不適用捕捉的信號(hào):KILL TERM
信號(hào)回應(yīng)方式
trap捕捉到信號(hào)之后,可以有三種反應(yīng)方式:
1、執(zhí)行一段程序來(lái)處理這一信號(hào)
2、接受信號(hào)的默認(rèn)操作
3、忽視這一信號(hào)
它有三種形式分別對(duì)應(yīng)三種不同的信號(hào)回應(yīng)方式 第一種:
- trap ""commands"" signal-list
當(dāng)腳本收到signal-list清單內(nèi)列出的信號(hào)時(shí),trap命令執(zhí)行雙引號(hào)中的命令.
第二種:
- trap signal-list
trap不指定任何命令,接受信號(hào)的默認(rèn)操作.默認(rèn)操作是結(jié)束進(jìn)程的運(yùn)行. 第三種:
- trap "" "" signal-list
trap命令指定一個(gè)空命令串,允許忽視信號(hào).
使用trap -l命令可以查看信號(hào)有哪些:
- # 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 命令將通過(guò) terminfo 數(shù)據(jù)庫(kù)對(duì)您的終端會(huì)話進(jìn)行初始化和操作。通過(guò)使用tput,您可以更改幾項(xiàng)終端功能,如移動(dòng)或更改光標(biāo)、更改文本屬性,以及清除終端屏幕的特定區(qū)域。
光標(biāo)屬性
- tput sc ##記錄光標(biāo)位置
- tput cup x y ###移動(dòng)光標(biāo)至x列y行
- tput rc ##返回光標(biāo)位置
- tput civis ##隱藏光標(biāo)
- tput cnorm ## 顯示光標(biāo)
- tput setaf ColorNumber ## 設(shè)置前景色
- tput setab ColorNumber ##設(shè)置背景色
- tput clear # 清除屏幕
- tput cup x y # 光標(biāo)按設(shè)定坐標(biāo)點(diǎn)移動(dòng)
文本屬性
- tput blink # 文本閃爍
- tput bold # 文本加粗
- tput el # 清除到行尾
- tput smso # 啟動(dòng)突出模式
- tput rmso # 停止突出模式
- tput smul # 下劃線模式
- tput rmul # 取消下劃線模式
- tput sgr0 # 恢復(fù)默認(rèn)終端
- tput rev # 反相終端
此外,還可以改變文本的顏色
- tput setb 顏色代號(hào)
- tput setf 顏色代號(hào)
舉例
- #加粗
- bold=$(tput bold)
- #下劃線
- underline=$(tput sgr 0 1)
- #重置規(guī)則
- reset=$(tput sgr0)
- #紅色
- red=$(tput setaf 1)
- #綠色
- green=$(tput setaf 2)
下面是一個(gè)帶閃爍功能的時(shí)鐘
- #!/bin/bash
- for ((i=0;i<8;i++))
- do
- tput sc; tput civis # 記錄光標(biāo)位置,及隱藏光標(biāo)
- tput blink; tput setf $i # 文本閃爍,更改文本顏色
- echo -ne $(date +'%Y-%m-%d %H:%M:%S') # 顯示時(shí)間
- sleep 1
- tput rc # 恢復(fù)光標(biāo)到記錄位置
- done
- tput el; tput cnorm # 退出時(shí)清理終端,恢復(fù)光標(biāo)顯示
效果
5. for循環(huán)
for循環(huán)的運(yùn)作方式,是講串行的元素意義取出,依序放入指定的變量中,然后重復(fù)執(zhí)行含括的命令區(qū)域(在do和done 之間),直到所有元素取盡為止。
其中,串行是一些字符串的組合,彼此用$IFS所定義的分隔符(如空格符)隔開(kāi),這些字符串稱為字段。
for的語(yǔ)法結(jié)構(gòu)如下:
- 1. for 變量 in 串行
- 2. do
- 3. 執(zhí)行命令
- 4. done
說(shuō)明:
行1,講串行中的字段迭代放入變量中 行2-4,接著將重復(fù)執(zhí)行do和done之間的命令區(qū)域,直到串行中每一個(gè)字段均處理過(guò)為止。
舉例 用for循環(huán)在家目錄下創(chuàng)建aaa1-aaa10,然后在aaa1-aaa10創(chuàng)建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循環(huán)
while循環(huán)的語(yǔ)法:
- 1. while 條件測(cè)試
- 2. do
- 3. 執(zhí)行命令
- 4. done
說(shuō)明:
- 行1,首先進(jìn)行條件測(cè)試,如果傳回值為0(條件測(cè)試為真),則進(jìn)入循環(huán),執(zhí)行命令區(qū)域,否則
- 不進(jìn)入循環(huán),介紹while 命令
- 行3,執(zhí)行命令區(qū)域,這些命令中,應(yīng)該要有改變條件測(cè)試的命令,這樣,才有機(jī)會(huì)在
- 有限步驟后結(jié)束執(zhí)行while循環(huán)(除非想要執(zhí)行無(wú)窮循環(huán))。
- 行4,回到行1,執(zhí)行while命令
流程圖:
實(shí)例 計(jì)算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
二、圣誕樹(shù)腳本文件
- #!/bin/bash
- #用shell編寫一個(gè)圣誕樹(shù)
- #創(chuàng)建時(shí)間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
- # 打印樹(shù)葉
- 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
- # 打印樹(shù)干
- 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 圣 誕 節(jié) 快 樂(lè)!!!
- color=122
- tput setaf $color; tput bold
- tput cup $((lin + 1)) $((c - 10)); echo 關(guān)注公眾號(hào): 一口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
三、執(zhí)行腳本
- root@ubuntu:/home/peng/work/test# chmod 777 peng.sh
- root@ubuntu:/home/peng/work/test# ./peng.sh
還等什么呢?抓緊運(yùn)行起來(lái)吧!
本文轉(zhuǎn)載自微信公眾號(hào)「一口Linux」
原文鏈接:https://mp.weixin.qq.com/s/QzhzGEjSrxWgg_FGbCtjLg