程序:算法+數據結構 數據:是程序的核心 數據結構:數據在計算機中的類型和組織方式 算法:處理數據的方式
#面向過程語言 作一件事情,排出個步驟,第一步幹什麼,第二步幹什麼,若是出現狀況A,作什麼處理,如 果出現了狀況B,作什麼處理 問題規模小,能夠步驟化,循序漸進處理 以指令爲中心,數據服務於指令 C,shell #面嚮對象語言 一種認識世界、分析世界的方法論。將萬事萬物抽象爲各類對象 類是抽象的概念,是萬事萬物的抽象,是一類事物的共同特徵的集合 對象是類的具象,是一個實體 問題規模大,複雜系統 以數據爲中心,指令服務於數據 java,C#,python,golang等
計算機:運行二進制指令 編程語言:人與計算機之間交互的語言。分爲兩種:低級語言和高級語言 低級編程語言: 機器:二進制的0和1的序列,稱爲機器指令。與天然語言差別太大,難懂、難寫 彙編:用一些助記符號替代機器指令,稱爲彙編語言 如:ADD A,B 將寄存器A的數與寄存器B的數相加獲得的數放到寄存器A中 彙編語言寫好的程序須要彙編程序轉換成機器指令 彙編語言稍微好理解,即機器指令對應的助記符,助記符更接近天然語言 高級編程語言: 編譯:高級語言-->編譯器-->機器代碼文件-->執行,如:C,C++ 解釋:高級語言-->執行-->解釋器-->機器代碼,如:shell,python,php,JavaScript,perl 編譯和解釋型語言
自動化經常使用命令 執行系統管理和故障排除 建立簡單的應用程序 處理文本或文件
#執行方法1 [root@centos8 ~]#bash /data/hello.sh #執行方法2 [root@centos8 ~]#cat /data/hello.sh | bash #執行方法3 [root@centos8 ~]#chmod +x /data/hello.sh 但你寫了一個腳本卻沒法被執行是由於你的hash裏面沒有這個路徑,路徑沒法被查到,就是在環境變量裏面沒法被查到,要寫到環境變量裏面 並且還要用 .激活一下 #絕對路徑 [root@centos8 ~]#/data/hello.sh #相法路徑 [root@centos8 ~]#cd /data/ [root@centos8 ~]#./hello.sh #執行方法4,本方法能夠實現執行遠程主機的shell腳本 [root@centos8 ~]#yum -y install httpd [root@centos8 ~]#systemctl start httpd [root@centos8 ~]#mv /data/hello.sh /var/www/html/ [root@centos8 ~]#curl -s http://www.wanghua.com/hello.sh|bash #執行互聯網上的腳本 -s 能夠隱藏下載的信息 [root@centos8 ~]#wget -qO - http://www.wangxiaochun.com/testdir/hello.sh |bash hello, world Hello, world! 調用別人寫的腳本,將將腳本放在服務器上,調用服務器上的腳本
[root01:52 PMcentos7 ]#cat a.sh #!/bin/bash echo -e "\033[1;32m 開始備份 \033[0m" sleep 3 cp -a /etc /back/`date +%F_%T` echo -e "\033[1;32m 備份完成 \033[0m"
只檢測腳本中的語法錯誤,但沒法檢查出命令錯誤,但不真正執行腳本javascript
bash -n /path/to/some_script
調試並執行php
bash -x /path/to/some_script -x:真正執行了的,每次執行一行,執行的結果就顯示一下
總結:腳本錯誤常見的有三種html
語法錯誤,會致使後續的命令不繼續執行,能夠用bash -n 檢查錯誤,提示的出錯行數不必定是準java
確的node
命令錯誤,默認後續的命令還會繼續執行,用bash -n 沒法檢查出來 ,可使用 bash -x 進行觀察python
邏輯錯誤:只能使用 bash -x 進行觀察linux
變量表示命名的內存空間,將數據放在內存空間中,經過變量名引用,獲取數據c++
變量類型: 內置變量,如:PS1,PATH,UID,HOSTNAME,$$(當前進程),BASHPID,PPID(父進程),$?,HISTSIZE 用戶自定義變量 不一樣的變量存放的數據不一樣,決定了如下 1. 數據存儲方式 2. 參與的運算 3. 表示的數據範圍 變量數據類型: 字符 數值:整型、浮點型,bash 不支持浮點數
#靜態和動態語言 靜態編譯語言:使用變量前,先聲明變量類型,以後類型不能改變,在編譯時檢查,如:java,c 動態編譯語言:不用事先聲明,可隨時改變類型,如:bash,Python #強類型和弱類型語言 強類型語言:不一樣類型數據操做,必須通過強制轉換才同一類型才能運算,如java , c# , python 如:參考如下 python 代碼 print('magedu'+ 10) 提示出錯,不會自動轉換類型 print('magedu'+str(10)) 結果爲magedu10,須要顯示轉換類型 弱類型語言:語言的運行時會隱式作數據類型轉換。無須指定類型,默認均爲字符型;參與運算會 自動進行隱式類型轉換;變量無須事先定義可直接調用 如:bash ,php,javascript
不能使程序中的保留字:如:if, for 只能使用數字、字母及下劃線,且不能以數字開頭,注意:不支持短橫線 「 - 」,和主機名相反 見名知義,用英文單詞命名,並體現出實際做用,不要用簡寫,如:ATM 統一命名規則:駝峯命名法, studentname,大駝峯StudentName 小駝峯studentName 變量名大寫:STUDENT_NAME 局部變量小寫 函數名小寫
變量的生效範圍等標準劃分變量類型golang
普通變量:生效範圍爲當前shell進程;對當前shell以外的其它shell進程,包括當前shell的子shell 進程均無效 環境變量:生效範圍爲當前shell進程及其子進程 本地變量:生效範圍爲當前shell進程中某代碼片段,一般指函數
直接字串:name='root' 變量引用:name="$USER" 命令引用:name=`COMMAND` 或者 name=$(COMMAND)
注意:變量賦值是臨時生效,當退出終端後,變量會自動刪除,沒法持久保存,腳本中的變量會隨着腳面試
本結束,也會自動刪除
弱引用和強引用 "$name " 弱引用,其中的變量引用會被替換爲變量值 '$name ' 強引用,其中的變量引用不會被替換爲變量值,而保持原字符串
[root@centos8 ~]#TITLE='cto' [root@centos8 ~]#echo $TITLE cto [root@centos8 ~]#echo I am $TITLE I am cto [root@centos8 ~]#echo "I am $TITLE" I am cto [root@centos8 ~]#echo 'I am $TITLE' I am $TITLE [root@centos8 ~]#NAME=$USER [root@centos8 ~]#echo $NAME root [root@centos8 ~]#USER=`whoami` [root@centos8 ~]#echo $USER root [root@centos8 ~]#FILE=`ls /run` [root@centos8 ~]#echo $FILE agetty.reload atd.pid auditd.pid autofs.fifo-misc autofs.fifo-net console cron.reboot cryptsetup dbus faillock fsck initctl initramfs lock log mount NetworkManager plymouth rsyslogd.pid screen sepermit setrans sshd.pid sssd.pid sudo systemd tmpfiles.d tuned udev user utmp vmware [root@centos8 ~]#FILE=/etc/* 命令的執行結果 [root@centos8 ~]#echo $FILE /etc/adjtime /etc/aliases /etc/alternatives /etc/anacrontab /etc/at.deny /etc/audit /etc/authselect /etc/autofs.conf /etc/autofs_ldap_auth.conf
[root03:27 PMcentos7 ]#title=cto [root03:33 PMcentos7 ]#name=wang [root03:33 PMcentos7 ]#title=$name [root03:34 PMcentos7 ]#echo $name wang [root03:34 PMcentos7 ]#echo $title wang [root03:35 PMcentos7 ]#name=wo [root03:35 PMcentos7 ]#echo $name wo [root03:35 PMcentos7 ]#echo $title wang [root03:35 PMcentos7 ]#name=ow [root03:37 PMcentos7 ]#echo $name ow [root03:37 PMcentos7 ]# wo這個字符串沒有人使用了,就是一塊垃圾了,會被回收
[root@centos8 ~]#seq 10 1 2 3 4 5 6 7 8 9 10 [root@centos8 ~]#NUM=`seq 10` [root@centos8 ~]#echo $NUM 1 2 3 4 5 6 7 8 9 10 [root@centos8 ~]#echo "$NUM" #加雙引號才能保留多行格式 1 2 3 4 5 6 7 8 9 10 [root03:43 PMcentos7 ]#name=" > wang > zhang > li > " [root03:44 PMcentos7 ]#echo $name wang zhang li [root03:44 PMcentos7 ]#echo "$name" wang zhang li [root03:44 PMcentos7 ]#name="wang > zhang > zhao > li" [root03:48 PMcentos7 ]#echo $name wang zhang zhao li [root03:48 PMcentos7 ]#echo "$name" wang zhang zhao li [root03:48 PMcentos7 ]#
set
unset <name> # 跟的是變量名,無須要加$ [root@centos8 ~]#NAME=mage [root@centos8 ~]#TITLE=ceo [root@centos8 ~]#echo $NAME $TITLE mage ceo [root@centos8 ~]#unset NAME TITLE [root@centos8 ~]#echo $NAME $TITLE
[root04:29 PMcentos7 ]#cat parent.sh #!/bin/bash NAME=name echo $NAME /data/son.sh [root04:29 PMcentos7 ]#cat son.sh #!/bin/bash echo " 調用父進程的變量 $NAME" NAME="myvalue" echo "調用本身的變量 $NAME" [root04:29 PMcentos7 ]#/data/parent.sh name 調用父進程的變量 ( #子進程沒法調用父進程的變量) 調用本身的變量 myvalue [root04:29 PMcentos7 ]#/data/son.sh 調用父進程的變量 調用本身的變量 myvalue [root04:29 PMcentos7 ]# [root04:29 PMcentos7 ]#vim parent.sh (添加export之後,子進程就調用父進程的環境變量) 1 #!/bin/bash 2 export NAME=name 3 echo $NAME 4 /data/son.sh [root04:48 PMcentos7 ]#/data/parent.sh name 調用父進程的變量 name 調用本身的變量 myvalue 父進定義的環境變量,子進程能使用,當子進程本身定義的變量和父進程定義的環境變量一致的時候,子進程優先使用本身的變量
環境變量: 可使子進程(包括孫子進程)繼承父進程的變量,可是沒法讓父進程使用子進程的變量 一旦子進程修改從父進程繼承的變量,將會新的值傳遞給孫子進程 通常只在系統配置文件中使用,在腳本中較少使用 #聲明並賦值 export name=VALUE declare -x name=VALUE #或者分兩步實現 name=VALUE export name
[root@centos8 data]#NAME=mage [root@centos8 data]#AGE=20 [root@centos8 data]#echo $NAME mage [root@centos8 data]#echo $AGE 20 [root@centos8 data]#echo $NAME $AGE mage 20 [root@centos8 data]#echo $NAME$AGE mage20 [root@centos8 data]#echo $NAME_$AGE #由於下劃線是能夠當作變量名的,將$NAME_ 認爲是一個變量 20 [root@centos8 data]#echo ${NAME}_$AGE mage_20
系統全部的環境變量,只是列環境變量
[root05:03 PMcentos7 ]#echo $$ 3365 [root05:12 PMcentos7 ]#bash [root05:12 PMcentos7 ]#echo $$ 5155 [root05:12 PMcentos7 ]#echo $PPID $SHLVL:嵌套深度 $$:當前的進程的PID $PPID:父進程的PID 3365 [root05:12 PMcentos7 ]#echo $SHLVL 2 [root05:13 PMcentos7 ]#bash [root05:14 PMcentos7 ]#echo $SHLVL 3 [root05:14 PMcentos7 ]#
[root05:48 PMcentos7 ]#CD=hostname [root05:48 PMcentos7 ]#$CD centos7
[root03:11 PMcentos7 ]#cat b.sh #!/bin/bash echo -e "\033[1;31m ---------------------主機信息----------------------- \033[0m" echo -e "\033[1;32m主機名:`hostname` \033[0m" echo -e "\033[1;32mIP地址:`ifconfig ens33 |grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}' |head -1 `\033[0m" echo -e "\033[1;32m發行版本號:`cat /etc/redhat-release`\033[0m" echo -e "\033[1;32m內核版本:`uname -r` \033[0m " echo -e "\033[1;32mCPU信息:`lscpu |grep -i "model name"|tr -s ' ' |cut -d: -f2`\033[0m" echo -e "\033[1;32m內存的使用狀況:`free -h |grep -iE "mem"|tr -s ' ' : |cut -d: -f2`\033[0m" echo -e "\033[1;32m磁盤的使用狀況:`lsblk |grep "^sd" |awk '{print $4}' ` \033[0m" echo -e "\033[1;31m-------------------------------------------------------\033[0m"
只讀變量:只能聲明定義,但後續不能修改和刪除,即常量
聲明只讀變量:
[root06:05 PMcentos7 ]#type declare declare is a shell builtin #申明只讀變量 readonly name declare -r name #查看只讀變量: readonly [-p] declare -r [root@centos8 ~]#readonly PI=3.14159 [root@centos8 ~]#echo $PI 3.14159 [root@centos8 ~]#PI=3.14 -bash: PI: readonly variable [root@centos8 ~]#unset PI -bash: unset: PI: cannot unset: readonly variable [root@centos8 ~]#echo $PI 3.14159 [root@centos8 ~]#exit #退出之後變量就消失了 logout Connection closed by foreign host.
位置變量:在bash shell中內置的變量, 在腳本代碼中調用經過命令行傳遞給腳本的參數
$1, $2, ... 對應第1個、第2個等參數,shift [n]換位置 $0 命令自己,包括路徑 $* 傳遞給腳本的全部參數,所有參數合爲一個字符串 $@ 傳遞給腳本的全部參數,每一個參數爲獨立字符串 $# 傳遞給腳本的參數的個數 注意:$@ $* 只在被雙引號包起來的時候纔會有差別 #清空全部位置變量 set --
[root@centos8 ~]#cat /data/scripts/arg.sh #!/bin/bash echo "1st arg is $1" echo "2st arg is $2" echo "3st arg is $3" echo "10st arg is ${10}" echo "11st arg is ${11}" echo "The number of arg is $#" echo "All args are $*" echo "All args are $@" echo "The scriptname is `basename $0`" `basename $0`不顯示路徑名 [root@centos8 ~]#bash /data/scripts/arg.sh {a..z} 1st arg is a 2st arg is b 3st arg is c 10st arg is j 11st arg is k The number of arg is 26 All args are a b c d e f g h i j k l m n o p q r s t u v w x y z All args are a b c d e f g h i j k l m n o p q r s t u v w x y z The scriptname is arg.sh
[root06:24 PMcentos7 ]#cat rm.sh #!/bin/bash STA="echo -e \033[1;31m" END="\033[0m" DIR=/tmp/`date +%F_%T` mkdir $DIR mv $* $DIR $STA MOVE $* TO $DIR $END
[root@centos8 scripts]#cat file.sh #!/bin/bash echo "file.sh:1st arg is $1" [root@centos8 scripts]#cat f2.sh #!/bin/bash echo "f2.sh:all args are $@" echo "f2.sh:all args are $*" ./file.sh "$@" [root@centos8 scripts]#cat f1.sh #!/bin/bash echo "f1.sh:all args are $@" echo "f1.sh:all args are $*" ./file.sh "$*" [root@centos8 scripts]#./f1.sh a b c f1.sh:all args are a b c f1.sh:all args are a b c file.sh:1st arg is a b c # 嵌套之後$* 是全部的參數 $@是一個參數 [root@centos8 scripts]#./f2.sh a b c f2.sh:all args are a b c f2.sh:all args are a b c file.sh:1st arg is a
進程執行後,將使用變量 $? 保存狀態碼的相關數字,不一樣的值反應成功或失敗,$?取值範例 0-255
$?的值爲0 #表明成功 $?的值是1到255 #表明失敗 [root@centos8 scripts]#curl http://www.wangxiaochun.com &> /dev/null [root@centos8 scripts]#echo $? 0 ping -c1 -W1 hostdown &> /dev/null echo $? #最近一條命令的執行結果
注意:
腳本中一旦遇到exit命令,腳本會當即終止;終止退出狀態取決於exit命令後面的數字
若是未給腳本指定退出狀態碼,整個腳本的退出狀態碼取決於腳本中執行的最後一條命令的狀態碼
展開命令執行順序 把命令行分紅單個命令詞 展開別名 展開大括號的聲明{} 展開波浪符聲明 ~ 命令替換$() 和 `` 再次把命令行分紅命令詞 展開文件通配*、?、[abc]等等 準備I/0重導向 <、> 運行命令 反斜線(\)會使隨後的字符按原意解釋 echo Your cost: \$5.00 Your cost: $5.00
set 命令:能夠用來定製 shell 環境 $- 變量 h:hashall,打開選項後,Shell 會將命令所在的路徑hash下來,避免每次都要查詢。經過set +h將h選 項關閉 i:interactive-comments,包含這個選項說明當前的 shell 是一個交互式的 shell。所謂的交互式shell, 在腳本中,i選項是關閉的 m:monitor,打開監控模式,就能夠經過Job control來控制進程的中止、繼續,後臺或者前臺執行等 B:braceexpand,大括號擴展 H:history,H選項打開,能夠展開歷史列表中的命令,能夠經過!感嘆號來完成,例如「!!」返回上最近的 一個歷史命令,「!n」返回第 n 個歷史命令 [root08:02 PMcentos7/boot ]#ls /etc/redhat-release /etc/redhat-release [root08:03 PMcentos7/boot ]#cat $_ echo $_是前一條命令的最後一個參數 CentOS Linux release 7.9.2009 (Core) [root@centos8 ~]#echo $- himBHs [root08:05 PMcentos7/boot ]#set +h [root08:05 PMcentos7/boot ]#echo $- imBH [root08:05 PMcentos7/boot ]#hash #這樣之後hash就被禁用了 -bash: hash: hashing disabled [root08:05 PMcentos7/boot ]# [root08:05 PMcentos7/boot ]#set -h #恢復hash功能 [root08:07 PMcentos7/boot ]#hash hits command 2 /usr/bin/cat 4 /usr/bin/ls [root08:07 PMcentos7/boot ]#echo $- #恢復原狀 himBH [root@centos8 ~]#set +B 關閉{}的功能 [root@centos8 ~]#echo $- imHs [root@centos8 ~]#echo {1..10} {1..10}
-u 在擴展一個沒有設置的變量時,顯示錯誤信息, 等同set -o nounset -e 若是一個命令返回一個非0退出狀態值(失敗)就退出, 等同set -o errexit -o option 顯示,打開或者關閉選項 顯示選項:set -o 打開選項:set -o 選項 關閉選項:set +o 選項 -x 當執行命令時,打印命令及其參數,相似 bash -x
[root08:08 PMcentos7/boot ]#set -o allexport off braceexpand on emacs on errexit off #出現錯誤不退出 errtrace off functrace off hashall on histexpand on history on ignoreeof off interactive-comments on keyword off monitor on noclobber off noexec off noglob off nolog off notify off nounset off onecmd off physical off pipefail off posix off privileged off verbose off vi off xtrace off [root08:18 PMcentos7~ ]#set -o errexit on #開啓功能,出現錯誤之後退出 [root08:18 PMcentos7~ ]#set -o |grep errexit errexit on [root08:21 PMcentos7~ ]#bash f.sh line1 f.sh: line 4: xxx: command not found [root08:21 PMcentos7~ ]#cat f.sh #!/bin/bash set -e echo line1 set -e 安全,可是一條命令不成功,後面的都不執行 xxx echo line2
[root08:32 PMcentos7~ ]#cat b.sh #!/bin/bash DIR=/data1 rm -rf /data/tmp/$DIR1/* 由於沒有$DIR1這個變量,沒有定義的變量 [root08:33 PMcentos7~ ]#mkdir /data/tmp/ [root08:33 PMcentos7~ ]#touch /data/tmp/a [root08:33 PMcentos7~ ]#touch /data/tmp/b [root08:33 PMcentos7~ ]#bash b.sh [root08:34 PMcentos7~ ]#ls /data/tmp/ [root08:39 PMcentos7~ ]#cat b.sh #!/bin/bash set -u DIR=/data1 rm -rf /data/tmp/$DIR1/* [root08:38 PMcentos7~ ]#bash b.sh b.sh: line 4: DIR1: unbound variable 加了-u 之後就不準哪些未知的變量 因此工做中基於安全考慮,腳本中加 set -ue
printf "指定的格式" "文本1" 」文本2「…… %s 字符串 %f 浮點格式 %b 相對應的參數中包含轉義字符時,可使用此替換符進行替換,對應的轉義字符會被轉 義 %c ASCII字符,即顯示對應參數的第一個字符 %d,%i 十進制整數 %o 八進制值 %u 不帶正負號的十進制值 %x 十六進制值(a-f) %X 十六進制值(A-F) %% 表示%自己
[root@centos8 ~]#printf "%s\n" 1 2 3 4 1 2 3 4 [root@centos8 ~]#printf "%f\n" 1 2 3 4 1.000000 2.000000 3.000000 4.000000 #.2f 表示保留兩位小數 [root@centos8 ~]#printf "%.2f\n" 1 2 3 4 1.00 2.00 3.00 4.00 [root@centos8 ~]#printf "(%s)" 1 2 3 4;echo (1)(2)(3)(4) [root@centos8 ~]#printf " (%s) " 1 2 3 4;echo "" (1) (2) (3) (4) [root@centos8 ~]#printf "(%s)\n" 1 2 3 4 (1) (2) (3) (4) [root@centos8 ~]#printf "%s %s\n" 1 2 3 4 1 2 3 4 [root@centos8 ~]#printf "%s %s %s\n" 1 2 3 4 1 2 3 4 #%-10s 表示寬度10個字符,左對齊 [root@centos8 ~]#printf "%-10s %-10s %-4s %s \n" 姓名 性別 年齡 體重 小明 男 20 70 小紅 女 18 50 姓名 性別 年齡 體重 小明 男 20 70 小紅 女 18 50 #將十進制的17轉換成16進制數 [root@centos8 ~]#printf "%X" 17 11[root@centos8 ~]# #將十六進制C轉換成十進制 [root@centos8 ~]#printf "%d\n" 0xC 12 [root@centos8 ~]#VAR="welcome to Magedu";printf "\033[31m%s\033[0m\n" $VAR welcome to Magedu [root@centos8 ~]#VAR="welcome to Magedu";printf "\033[31m%s\033[0m\n" "$VAR" welcome to Magedu
shell 支持算術運算,但只支持整數,不支持小數
bash中的算術運算
+ - * / % 取模,即取餘數,示例:9%4=1,5%3=2 ** 乘方
乘法符號有些場景中須要轉義
+= i+=10 至關於 i=i+10 -= i-=j 至關於 i=i-j *= /= %= ++ i++,++i 至關於 i=i+1 -- i--,--i 至關於 i=i-1
實現算術運算:
(1) let var=算術表達式 (2) ((var=算術表達式)) 和上面等價 [root@centos8 ~]#let i=10*2 [root@centos8 ~]#echo $i 20 [root@centos8 ~]#((j=i+10)) [root@centos8 ~]#echo $j 30 [root09:29 AMcentos8 ~]#let i=10*2 [root09:29 AMcentos8 ~]#((j=i+10)) [root09:30 AMcentos8 ~]#echo $j 30 (3) var=$[算術表達式] (4) var=$((算術表達式)) (5) var=$(expr arg1 arg2 arg3 ...) (6) declare –i var = 數值 (7) echo '算術表達式' | bc
內建的隨機數生成器變量:
$RANDOM 取值範圍:0-32767 [root08:53 PMcentos7~ ]#echo $RANDOM 16020 [root08:57 PMcentos7~ ]#echo $RANDOM 26272
#生成 0 - 49 之間隨機數 echo $[$RANDOM%50] #隨機字體顏色 [root@centos8 ~]#echo -e "\033[1;$[RANDOM%7+31]mhello\033[0m" magedu [root09:25 PMcentos7~ ]#echo -e "\e[1;$[RANDOM%7+31]mhello\033[0m" hello
[root08:59 PMcentos7~ ]#n=10 [root09:00 PMcentos7~ ]#m=20 [root09:00 PMcentos7~ ]#sum=$m+$n [root09:00 PMcentos7~ ]#echo $sum 20+10 [root09:00 PMcentos7~ ]#let sum=$m+$n [root09:02 PMcentos7~ ]#echo $sum 30 [root09:02 PMcentos7~ ]#n=30 [root09:02 PMcentos7~ ]#let sum=$m+$n [root09:02 PMcentos7~ ]#echo $sum 50
[root09:05 PMcentos7~ ]#let result=RANDOM%50 [root09:05 PMcentos7~ ]#echo $result 24 [root09:05 PMcentos7~ ]#let result=RANDOM%50+1 [root09:06 PMcentos7~ ]#echo $result 48
[root09:06 PMcentos7~ ]#i=10 [root09:08 PMcentos7~ ]#let i++ [root09:08 PMcentos7~ ]#echo $i 11 [root09:08 PMcentos7~ ]#let i++ [root09:08 PMcentos7~ ]#echo $i 12 [root09:08 PMcentos7~ ]#let i-- [root09:08 PMcentos7~ ]#echo $i 11 [root09:08 PMcentos7~ ]#let ++i [root09:09 PMcentos7~ ]#echo $i 12 [root09:09 PMcentos7~ ]#let ++i [root09:09 PMcentos7~ ]#echo $i 13
[root09:09 PMcentos7~ ]#i=10;let j=i++;echo j=$j i=$i #賦值給j之後再加 j=10 i=11 [root09:13 PMcentos7~ ]#i=10;let j=++i;echo j=$j i=$i #加完了賦給j j=11 i=11
[root09:33 PMcentos7~ ]#expr 2 + 3 5 [root09:33 PMcentos7~ ]#expr 2 * 3 expr: syntax error [root09:34 PMcentos7~ ]#expr 2 / 3 0 [root09:34 PMcentos7~ ]#expr 23 / 3 7 [root09:34 PMcentos7~ ]#expr 27 / 3 9 [root09:34 PMcentos7~ ]#expr 2 \* 3 乘法被誤認爲通配符,轉義 6
[root09:36 PMcentos7~ ]#echo 2*3 |bc 6 [root09:39 PMcentos7~ ]#echo "scale=3;20/3" |bc 6.666
[root09:40 PMcentos7~ ]#i=10 [root09:43 PMcentos7~ ]#j=20 [root09:43 PMcentos7~ ]#declare -i result=i*j [root09:44 PMcentos7~ ]#echo $result 200
true, false
1, 0
#與:&:和0相與,結果爲0,和1相與,結果保留原值 1 與 1 = 1 1 與 0 = 0 0 與 1 = 0 0 與 0 = 0 #或:|:和1相或結果爲1,和0相或,結果保留原值 1 或 1 = 1 1 或 0 = 1 0 或 1 = 1 0 或 0 = 0 #非:! ! 1 = 0 ! true ! 0 = 1 ! false #異或:^ 異或的兩個值,相同爲假,不一樣爲真。兩個數字X,Y異或獲得結果Z,Z再和任意二者之一X異或,將得出 另外一個值Y 1 ^ 1 = 0 1 ^ 0 = 1 0 ^ 1 = 1 0 ^ 0 = 0
[root@centos8 ~]#true [root@centos8 ~]#echo $? 0 [root@centos8 ~]#false [root@centos8 ~]#echo $? 1 [root@centos8 ~]#! true [root@centos8 ~]#echo $? 1 [root@centos8 ~]#! false [root@centos8 ~]#echo $? 0 #交換兩個值 [root@centos8 ~]#x=10;y=20;temp=$x;x=$y;y=$temp;echo x=$x,y=$y x=20,y=10 [root@centos8 ~]#x=10;y=20;x=$[x^y];y=$[x^y];x=$[x^y];echo x=$x,y=$y x=20,y=10
短路與 CMD1 短路與 CMD2 第一個CMD1結果爲真 (1),第二個CMD2必需要參與運算,才能獲得最終的結果 第一個CMD1結果爲假 (0),總的結果一定爲0,所以不須要執行CMD2 短路或 CMD1 短路或 CMD2 第一個CMD1結果爲真 (1),總的結果一定爲1,所以不須要執行CMD2 第一個CMD1結果爲假 (0),第二個CMD2 必需要參與運算,,才能獲得最終的結果
條件測試:判斷某需求是否知足,須要由測試機制來實現,專用的測試表達式須要由測試命令輔助完成
測試過程
,實現評估布爾聲明,以便用在條件性環境下進行執行
若真,則狀態碼變量 $? 返回0
若假,則狀態碼變量 $? 返回1
條件測試命令
test EXPRESSION [ EXPRESSION ] #和test 等價,建議使用 [ ] [[ EXPRESSION ]] ========================================================================== [root11:40 PMcentos7~ ]#type [ 中括號自己就是一個內部命令 [ is a shell builtin [root11:45 PMcentos7~ ]#help [ [: [ arg... ] Evaluate conditional expression. This is a synonym for the "test" builtin, but the last argument must be a literal `]', to match the opening `['. [[ ... ]]: [[ expression ]] Execute conditional command. Returns a status of 0 or 1 depending on the evaluation of the conditional expression EXPRESSION. Expressions are composed of the same primaries used by the `test' builtin, and may be combined using the following operators: ( EXPRESSION ) Returns the value of EXPRESSION ! EXPRESSION True if EXPRESSION is false; else false EXPR1 && EXPR2 True if both EXPR1 and EXPR2 are true; else false EXPR1 || EXPR2 True if either EXPR1 or EXPR2 is true; else false When the `==' and `!=' operators are used, the string to the right of the operator is used as a pattern and pattern matching is performed. When the `=~' operator is used, the string to the right of the operator is matched as a regular expression. The && and || operators do not evaluate EXPR2 if EXPR1 is sufficient to determine the expression's value. Exit Status: 0 or 1 depending on value of EXPRESSION.
注意:EXPRESSION先後必須有空白字符
幫助:
[root10:56 PMcentos7~ ]#cat a xiaoing=20 xiaohong=18 xiaoqiang=22 方法一: [root11:08 PMcentos7~ ]#cut -d"=" -f2 a |tr -s "\n" + |cut -d'+' -f1-3 20+18+22 [root11:01 PMcentos7~ ]#cut -d"=" -f2 a |tr -s "\n" + |cut -d'+' -f1-3 |bc 60 方法二: [root11:14 PMcentos7~ ]#cut -d"=" -f2 a |tr -s "\n" + |grep -Eo "([0-9]+\+){2}[0-9]+"|bc 60 方法三 [root11:14 PMcentos7~ ]#cut -d"=" -f2 a |tr -s "\n" + 20+18+22+[root11:16 PMcentos7~ ]#cut -d"=" -f2 a |tr -s "\n" + |grep -Eo ".*[0-9]+" |bc 60 方法四: [root10:11 AMcentos8 ~]#awk -F"=" '{print $2}' |paste -sd+ |bc 60
[root11:47 PMcentos7~ ]#test -v n [root11:52 PMcentos7~ ]#echo $? 0 [root11:52 PMcentos7~ ]#echo $n 30 [root11:54 PMcentos7~ ]#name= [root11:54 PMcentos7~ ]#test -v name [root11:54 PMcentos7~ ]#echo $? 0 [root11:55 PMcentos7~ ]#echo $name [root11:55 PMcentos7~ ]# [root11:55 PMcentos7~ ]#unset name [root11:57 PMcentos7~ ]#test -v name [root11:57 PMcentos7~ ]#echo $? 1 [root11:58 PMcentos7~ ]#hi="hi" [root11:59 PMcentos7~ ]#[ -v hi ] test和中括號等價 [root11:59 PMcentos7~ ]#echo $? 0
-eq 是否等於 -ne 是否不等於 -gt 是否大於 -ge 是否大於等於 -lt 是否小於 -le 是否小於等於
[root@centos8 ~]#i=10 [root@centos8 ~]#j=8 [root@centos8 ~]#[ $i -lt $j ] 即便是數字也要加$ [root@centos8 ~]#echo $? 1 [root@centos8 ~]#[ $i -gt $j ] [root@centos8 ~]#echo $? 0 [root@centos8 ~]#[ i -gt j ] -bash: [: i: integer expression expected
test和 [ ]用法 -z STRING 字符串是否爲空,沒定義或空爲真,不空爲假, -n STRING 字符串是否不空,不空爲真,空爲假 STRING 同上 STRING1 = STRING2 是否等於,注意 = 先後有空格,沒有空格是賦值,有空格是比較 STRING1 != STRING2 是否不等於 > ascii碼是否大於ascii碼 < 是否小於 [[]] 用法,建議,當使用正則表達式或通配符使用,通常狀況使用 [ ] == 左側字符串是否和右側的PATTERN相同 注意:此表達式用於[[ ]]中,PATTERN爲通配符 =~ 左側字符串是否可以被右側的正則表達式的PATTERN所匹配 注意: 此表達式用於[[ ]]中;擴展的正則表達式
[root@centos8 ~]#unset str [root@centos8 ~]#[ -z "$str" ] [root@centos8 ~]#echo $? 0 [root@centos8 ~]#str="" [root@centos8 ~]#[ -z "$str" ] [root@centos8 ~]#echo $? 0 [root@centos8 ~]#str=" " [root@centos8 ~]#[ -z "$str" ] [root@centos8 ~]#echo $? 1 [root@centos8 ~]#[ -n "$str" ] [root@centos8 ~]#echo $? 0 [root@centos8 ~]#unset str [root@centos8 ~]#[ -n "$str" ] [root@centos8 ~]#echo $? 1 [root@centos8 ~]#[ "$str" ] [root@centos8 ~]#echo $? 1 [root@centos8 ~]#str=magedu [root@centos8 ~]#[ "$str" ] [root@centos8 ~]#echo $? 0 [root@centos8 ~]#str=magedu [root@centos8 ~]#[ "$str" ] [root@centos8 ~]#echo $? 0 [root@centos8 ~]#str1=magedu [root@centos8 ~]#str2=mage [root@centos8 ~]#[ $str1 = $str2 ] [root@centos8 ~]#echo $? 1 [root@centos8 ~]#str2=magedu [root@centos8 ~]#[ $str1 = $str2 ] 有空格是比較,沒有空格是賦值 [root@centos8 ~]#echo $? 0
[root@centos8 ~]#[ "$NAME" ] [root@centos8 ~]#NAME="I love linux" [root@centos8 ~]#[ $NAME ] -bash: [: love: binary operator expected [root@centos8 ~]#[ "$NAME" ] #省略了一個 -n [root@centos8 ~]#echo $? 0 [root@centos8 ~]#[ I love linux ] -bash: [: love: binary operator expected
#通配符 [root@centos8 ~]#FILE=test.log [root@centos8 ~]#[[ "$FILE" == *.log ]] [root@centos8 ~]#echo $? 0 [root@centos8 ~]#FILE=test.txt [root@centos8 ~]#[[ "$FILE" == *.log ]] [root@centos8 ~]#echo $? 1 [root@centos8 ~]#[[ "$FILE" != *.log ]] [root@centos8 ~]#echo $? 0 [root@centos8 ~]#NAME="linux1" 左側的變量加雙引號,右側的不加 [root@centos8 ~]#[[ "$NAME" == linux* ]] [root@centos8 ~]#echo $? 0 [root@centos8 ~]#[[ "$NAME" == "linux*" ]] [root@centos8 ~]#echo $? 1 [root@centos8 ~]#NAME="linux*" [root@centos8 ~]#[[ "$NAME" == "linux*" ]] [root@centos8 ~]#echo $? 0 #結論:[[ == ]] == 右側的 * 作爲通配符,不要加「」,只想作爲*, 須要加「」 或轉義
遇到正則表達式這樣複雜的就用雙中括號 #正則表達式 [root@centos8 ~]#[[ "$FILE" =~ \.log$ ]] #判斷後綴 [root@centos8 ~]#echo $? 1 [root@centos8 ~]#FILE=test.log [root@centos8 ~]#[[ "$FILE" =~ \.log$ ]] [root@centos8 ~]#echo $? 0 [root@centos8 ~]#N=100 [root@centos8 ~]#[[ "$N" =~ ^[0-9]+$ ]] #雙中括號用的擴展的正則表達式 [root@centos8 ~]#echo $? 0 [root@centos8 ~]#N=Magedu10 [root@centos8 ~]#[[ "$N" =~ ^[0-9]+$ ]] #純數字的判斷 [root@centos8 ~]#echo $? 1 [root@centos8 ~]#IP=1.2.3.4 [root@centos8 ~]#[[ "$IP" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]] #ip地址的判斷 [root@centos8 ~]#echo $? 0 [root@centos8 ~]#IP=1.2.3.4567 [root@centos8 ~]#[[ "$IP" =~ ^([0-9]{1,3}.){3}[0-9]{1,3}$ ]] [root@centos8 ~]#echo $? 1 #是不是合法的IP [root10:27 AMcentos8 ~]#[[ "$IP" =~(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$ ]] [root10:27 AMcentos8 ~]#echo $? 1
#!/bin/bash read -p "請輸入IP:" IP if [[ $IP =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then FIELD1=$(echo $IP|cut -d. -f1) FIELD2=$(echo $IP|cut -d. -f2) FIELD3=$(echo $IP|cut -d. -f3) FIELD4=$(echo $IP|cut -d. -f4) if [ $FIELD1 -le 255 -a $FIELD2 -le 255 -a $FIELD3 -le 255 -a $FIELD4 -le 255 ]; then echo "IP $IP available." else echo "IP $IP not available!" fi else echo "IP format error!" fi #!/bin/bash read -p "請輸入一個IP:" IP function check_ip() { if [[ $IP =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then FIELD1=$(echo $IP|cut -d. -f1) FIELD2=$(echo $IP|cut -d. -f2) FIELD3=$(echo $IP|cut -d. -f3) FIELD4=$(echo $IP|cut -d. -f4) if [ $FIELD1 -le 255 -a $FIELD2 -le 255 -a $FIELD3 -le 255 -a $FIELD4 -le 255 ]; then echo "IP $IP available." else echo "IP $IP not available!" fi else echo "IP format error!" fi } check_ip
存在性測試 -a FILE:同 -e -e FILE: 文件存在性測試,存在爲真,不然爲假 -b FILE:是否存在且爲塊設備文件 -c FILE:是否存在且爲字符設備文件 -d FILE:是否存在且爲目錄文件 -f FILE:是否存在且爲普通文件 -h FILE 或 -L FILE:存在且爲符號連接文件 -p FILE:是否存在且爲命名管道文件 -S FILE:是否存在且爲套接字文件 [root@centos8 ~]#[ -a /etc/nologin ] [root@centos8 ~]#echo $? 1 [root@centos8 ~]#! [ -a /etc/nologin ] [root@centos8 ~]#echo $? 0 [root01:18 AMcentos7~ ]# [ ! -a /etc/nologin ] !放中括號裏面 [root01:20 AMcentos7~ ]#echo $? 0 [root@centos8 ~]#[ -d /etc ] [root@centos8 ~]#echo $? 0 [root@centos8 ~]#[ -d /etc/issue ] [root@centos8 ~]#echo $? 1 [root@centos8 ~]#[ -L /bin ] [root@centos8 ~]#echo $? 0 [root@centos8 ~]#[ -L /bin/ ] 軟連接 [root@centos8 ~]#echo $? 1 [root01:10 AMcentos7~ ]#ll /etc/redhat-release lrwxrwxrwx 1 root root 14 Apr 30 10:16 /etc/redhat-release -> centos-release [root12:07 AMcentos7~ ]#[ -f /etc/redhat-release ] 該文件雖然是軟連接文件可是卻也是普通文件,他判斷的是軟連接指向的 [root01:09 AMcentos7~ ]#echo $? 0 [root01:13 AMcentos7~ ]#ll /lib 該文件也是軟連接,可是卻不是普通文件,由於他指向的是一個文件夾 lrwxrwxrwx 1 root root 7 Apr 30 10:16 /lib -> usr/lib [root01:13 AMcentos7~ ]#[ -f /lib ] [root01:13 AMcentos7~ ]#echo $? 1 [root01:15 AMcentos7~ ]#[ -h /lib ] 軟連接 [root01:16 AMcentos7~ ]#echo $? 0
-r FILE:是否存在且可讀 -w FILE: 是否存在且可寫 -x FILE: 是否存在且可執行 -u FILE:是否存在且擁有suid權限 -g FILE:是否存在且擁有sgid權限 -k FILE:是否存在且擁有sticky權限
注意:最終結果由用戶對文件的實際權限決定,而非文件屬性決定
[root@centos8 ~]#[ -w /etc/shadow ] [root@centos8 ~]#echo $? 0 [root@centos8 ~]#[ -x /etc/shadow ] [root@centos8 ~]#echo $? 1 [root@centos8 ~]#[ -w test.txt ] [root@centos8 ~]#echo $? 0 [root@centos8 ~]#chattr +i test.txt [root@centos8 ~]#lsattr test.txt ----i-------------- nianling.txt [root@centos8 ~]#[ -w test.txt ] [root@centos8 ~]#echo $? 1 [root@centos8 ~]#chattr -i test.txt [root@centos8 ~]#[ -w test.txt ] [root@centos8 ~]#echo $? 0
-s FILE #是否存在且非空 -t fd #fd 文件描述符是否在某終端已經打開 -N FILE #文件自從上一次被讀取以後是否被修改過 -O FILE #當前有效用戶是否爲文件屬主 -G FILE #當前有效用戶是否爲文件屬組 FILE1 -ef FILE2 #FILE1是不是FILE2的硬連接 FILE1 -nt FILE2 #FILE1是否新於FILE2(mtime) FILE1 -ot FILE2 #FILE1是否舊於FILE2
(CMD1;CMD2;...)和 { CMD1;CMD2;...; } 均可以將多個命令組合在一塊兒,批量執行
[root@centos8 ~]#man bash
(list ) 會開啓子shell,而且list中變量賦值及內部命令執行後,將再也不影響後續的環境, 幫助參看:man bash
搜索(list)
{ list; } 不會啓子shell, 在當前shell中運行,會影響當前shell環境, 幫助參看:man bash 搜索{ list; }
[root@centos8 ~]#name=mage;(echo $name;name=wang;echo $name );echo $name mage 特例:雖然不是環境變量,可是使用小括號是能夠繼承父進程的環境變量的 wang mage [root@centos8 ~]#name=mage;{ echo $name;name=wang;echo $name; } ;echo $name mage 花括號不開啓子進程,會影響當前的環境 wang wang [root@centos8 ~]#umask 0022 [root@centos8 ~]#(umask 066;touch f1.txt) [root@centos8 ~]#ll f1.txt -rw------- 1 root root 0 Dec 23 16:58 f1.txt [root@centos8 ~]#umask 0022 [root@centos8 ~]#( cd /data;ls ) test.log [root@centos8 ~]#pwd /root [root@centos8 ~]#{ cd /data;ls; } test.log [root@centos8 data]#pwd /data [root@centos8 data]# #()會開啓子shell [root@centos8 ~]#echo $BASHPID 1920 [root@centos8 ~]#( echo $BASHPID;sleep 100) 1979 [root@centos8 ~]#pstree -p ├─sshd(719)───sshd(1906)───sshd(1919)─┬─bash(1920)───bash(1979)───sleep(1980) #{ } 不會開啓子shell [root@centos8 ~]#echo $BASHPID 1920 [root@centos8 ~]#{ echo $BASHPID; } 1920
[ EXPRESSION1 -a EXPRESSION2 ] 而且,EXPRESSION1和EXPRESSION2都是真,結果才爲真 [ EXPRESSION1 -o EXPRESSION2 ] 或者,EXPRESSION1和EXPRESSION2只要有一個真,結果就爲 真 [ ! EXPRESSION ] 取反 說明: -a 和 -o 須要使用測試命令進行,[[ ]] 不支持 [root@centos8 ~]#ll /data/scrips/test.sh -rw-r--r-- 1 root root 382 Dec 23 09:32 /data/scripts/test.sh [root@centos8 ~]#[ -f $FILE -a -x $FILE ] [root@centos8 ~]#echo $? 1 [root@centos8 ~]#chmod +x /data/scripts/test.sh [root@centos8 ~]#ll /data/scripts/test.sh -rwxr-xr-x 1 root root 382 Dec 23 09:32 /data/script40/test.sh [root@centos8 ~]#[ -f $FILE -a -x $FILE ] [root@centos8 ~]#echo $? 0 [root@centos8 ~]#chmod -x /data/scripts/test.sh [root@centos8 ~]#ll /data/scripts/test.sh -rw-r--r-- 1 root root 382 Dec 23 09:32 /data/scripts/test.sh [root@centos8 ~]#[ -f $FILE -o -x $FILE ] [root@centos8 ~]#echo $? 0 [root@centos8 ~]#[ -x $FILE ] [root@centos8 ~]#echo $? 1 [root@centos8 ~]#[ ! -x $FILE ] [root@centos8 ~]#echo $? 0 [root@centos8 ~]#! [ -x $FILE ] 0
COMMAND1 && COMMAND2 #而且,短路與,表明條件性的AND THEN 若是COMMAND1 成功,將執行COMMAND2,不然,將不執行COMMAND2 COMMAND1 || COMMAND2 #或者,短路或,表明條件性的OR ELSE 若是COMMAND1 成功,將不執行COMMAND2,不然,將執行COMMAND2 ! COMMAND #非,取反
[root@centos7 ~]#[ $[RANDOM%6] -eq 0 ] && rm -rf /* || echo "click"click
[root08:07 AMcentos7 ]#A=10 [root08:07 AMcentos7 ]#B=20 [root08:08 AMcentos7 ]#[ "A" -eq "B" ] && echo "Integers are equal" -bash: [: A: integer expression expected [root08:08 AMcentos7 ]#[ "" -eq "" ] && echo "Integers are equal" -bash: [: : integer expression expected [root08:08 AMcentos7 ]#[ "$A" -eq "$B" ] && echo "Integers are equal" [root08:08 AMcentos7 ]#echo $? 1 變量放[]比較用$號 [root@centos8 ~]#test "A"-eq "B" && echo "Integers are equal" =================================================================== [root07:59 AMcentos7 ]#A=10 [root07:59 AMcentos7 ]#B=10 [root08:00 AMcentos7 ]#[ "A" = "B" ] && echo "Strings are equal" [root08:00 AMcentos7 ]#echo $? 1 [root08:04 AMcentos7 ]#test "A" = "B" && echo "Strings are equal" [root08:06 AMcentos7 ]#echo $? 1 [root08:01 AMcentos7 ]#[ "$A" = "$B" ] && echo "Strings are equal" Strings are equal [root08:01 AMcentos7 ]#[ "$A" -eq "$B" ] && echo "Integers are equal" Integers are equal ================================================================== [root@centos8 ~]#[ -f /bin/cat -a -x /bin/cat ] && cat /etc/fstab [root@centos8 ~]#[ -z "$HOSTNAME" -o "$HOSTNAME" = "localhost.localdomain" ]&& hostname www.magedu.com [root@centos8 ~]#id wang &> /dev/null || useradd wang [root@centos8 ~]#id zhang &> /dev/null || useradd zhang [root@centos8 ~]#getent passwd zhang zhang:x:1002:1002::/home/zhang:/bin/bash [root@centos8 ~]#grep -q no_such_user /etc/passwd || echo 'No such user' No such user [root@centos8 ~]#[ -f 「$FILE」 ] && [[ 「$FILE」=~ .*\.sh$ ]] && chmod +x $FILE
[root@centos8 ~]#ping -c1 -W1 172.16.0.1 &> /dev/null && echo '172.16.0.1 is up' || (echo '172.16.0.1 is unreachable'; exit 1) 172.16.0.1 is up [root@centos8 ~]#IP=10.0.0.111;ping -c1 -W1 $IP &> /dev/null && echo $IP is up || echo $IP is down -c1 ping一次 10.0.0.111 is down -W1 間隔時間爲1秒 [root@centos8 ~]#IP=10.0.0.1;ping -c1 -W1 $IP &> /dev/null && echo $IP is up || echo $IP is down 10.0.0.1 is up
[root@centos8 ~]#NAME=wang; id $NAME &> /dev/null && echo "$NAME is exist" wang is exist [root@centos8 ~]#NAME=wange; id $NAME &> /dev/null || echo "$NAME is not exist" wange is not exist [root@centos8 ~]#NAME=wange; id $NAME &> /dev/null && echo "$NAME is exist" || echo "$NAME is not exist" wange is not exist [root@centos8 ~]#NAME=wang; id $NAME &> /dev/null && echo "$NAME is exist" || echo "$NAME is not exist" wang is exist [root@centos8 ~]#NAME=wang; id $NAME &> /dev/null && echo "$NAME is exist" || echo "$NAME is not exist" wang is exist [root@centos8 ~]#NAME=wang; id $NAME &> /dev/null || echo "$NAME is not exist" && echo "$NAME is exist" wang is exist [root@centos8 ~]#NAME=wange; id $NAME &> /dev/null || echo "$NAME is not exist" && echo "$NAME is exist" wange is not exist wange is exist #結論:若是&& 和 || 混合使用,&& 要在前,|| 放在後 [root@centos8 ~]#NAME=wange; id $NAME &> /dev/null && echo "$NAME is exist" || useradd $NAME [root@centos8 ~]#id wange uid=1002(wange) gid=1002(wange) groups=1002(wange) [root@centos8 ~]#NAME=wangge; id $NAME &> /dev/null && echo "$NAME is exist" || ( useradd $NAME; echo $NAME is created ) 保證後面的兩條命令是一塊兒的 wangge is created [root@centos8 ~]#id wangge uid=1003(wangge) gid=1003(wangge) groups=1003(wangge) [root@centos8 ~]#NAME=wanggege; id $NAME &> /dev/null && echo "$NAME is exist" || { useradd $NAME; echo $NAME is created; } {}別忘記了加分號 wanggege is created
[root@centos8 ~]#cat /data/script40/disk_check.sh #!/bin/bash WARNING=80 SPACE_USED=`df|grep '^/dev/sd'|tr -s ' ' %|cut -d% -f5|sort -nr|head -1` [ "$SPACE_USED" -ge $WARNING ] && echo "disk used is $SPACE_USED,will be full" | mail -s diskwaring root
[root@centos8 scripts]#cat disk_check.sh #!/bin/bash WARNING=80 SPACE_USED=`df | grep '^/dev/sd'|grep -oE '[0-9]+%'|tr -d %| sort -nr|head -1` INODE_USED=`df -i | grep '^/dev/sd'|grep -oE '[0-9]+%'|tr -d %| sort -nr|head -1` [ "$SPACE_USED" -gt $WARNING -o "$INODE_USED" -gt $WARNING ] && echo "DISK USED:$SPACE_USED%, INODE_USED:$INODE_USED,will be full" | mail -s "DISK Warning" root@wangxiaochun.com
[root09:24 AMcentos7 ]#cat disk.sh #!/bin/bash warning=12 inodes=`df |grep '^/dev'|grep -Eo [0-9]+% |tr -d % |sort -nr |head -1` disk=`df -h|grep '^/dev'|grep -Eo '[0-9]+%'|tr -d '%' |sort -nr|head -1` [ "$disk" -gt "$warning" -o "$inodes" -gt "$warning" ] && echo "DISK USED $disk% INODES USED $inodes%,will be full" |mail -s "DISK USE" 1722525928@qq.com
使用read來把輸入值分配給一個或多個shell變量,read從標準輸入中讀取值,給每一個單詞分配一個變 量,全部剩餘單詞都被分配給最後一個變量,若是變量名沒有指定,默認標準輸入的值賦值給系統內置 變量REPLY -p 指定要顯示的提示 -s 靜默輸入,通常用於密碼 -n N 指定輸入的字符長度N -d '字符' 輸入結束符 -t N TIMEOUT爲N秒 [root@centos8 ~]#read wangxiaochun [root@centos8 ~]#echo $REPLY wangxiaochun [root@centos8 ~]#read NAME TITLE wang cto [root@centos8 ~]#echo $NAME wang [root@centos8 ~]#echo $TITLE cto #交互式 [root@centos8 ~]#read -p "Please input your name: " NAME Please input your name: wang [root@centos8 ~]#echo $NAME wang [root@centos8 ~]#read x y z <<< "I love you" [root@centos8 ~]#echo $x I [root@centos8 ~]#echo $y love [root@centos8 ~]#echo $z you [root@centos8 ~]#
[root10:11 AMcentos7 ]#cat read.sh #!/bin/bash echo -n "are you rich ? yes or no:" read ANSWER [ $ANSWER = "yes" -o $ANSWER = "y" ] && echo "you are rich " ||echo "do well anything" --------------------------------------------------------------------------- [root10:15 AMcentos7 ]#cat read.sh #!/bin/bash read -p "are you rich? yes or no:" ANSWER [ $ANSWER = "yes" -o $ANSWER = "y" ] && echo "you are rich " ||echo "do well anything" ------------------------------------------------------------------------------------------- 正則表達式優化一下 [root10:26 AMcentos7 ]#cat read.sh #!/bin/bash read -p "are you rich? yes or no:" ANSWER [[ $ANSWER =~ ^[Yy]|[Ee]|[Ss]$ ]] && echo "you are rich " ||echo "do well anything"
[root10:53 AMcentos7 ]#cat work.sh #!/bin/bash echo -en "\033[$[RANDOM%7+31];1m" cat <<EOF 請選擇: 1)備份數據庫 2)清理日誌 3)軟件升級 4)軟件回滾 5)刪庫跑路 EOF read -p "請輸入上面數字1-5:" MEMU [ $MEMU -eq 1 ] && ./backup.sh [ $MEMU -eq 2 ] && echo "清理日誌" [ $MEMU -eq 3 ] && echo "軟件升級" [ $MEMU -eq 4 ] && echo "軟件回滾" [ $MEMU -eq 5 ] && echo "刪庫跑路" echo -en "\033[0m" root10:53 AMcentos7 ]#bash work.sh 請選擇: 1)備份數據庫 2)清理日誌 3)軟件升級 4)軟件回滾 5)刪庫跑路 請輸入上面數字1-5:3 軟件升級 [root11:17 AMcentos7 ]#cat backup.sh #!/bin/bash backdir=/root/`date +%F_%T` mkdir $backdir cp -a /etc $backdir && echo "備份成功" ||echo "備份失敗" root11:17 AMcentos7 ]#chmod +x backup.sh
[root11:26 AMcentos7 ]#cat f1 a b [root11:26 AMcentos7 ]#read i j <f1 [root11:27 AMcentos7 ]#echo $i a [root11:27 AMcentos7 ]#echo $j b [root11:29 AMcentos7 ]#echo abc def | read x y [root11:29 AMcentos7 ]#echo $x $y [root11:30 AMcentos7 ]# [root11:30 AMcentos7 ]#echo abc def | read x y;echo x=$x y=$y x= y=
[root11:37 AMcentos7 ]#echo 1 2 |read x y ;echo x=$x y=$y x= y= [root11:37 AMcentos7 ]#echo 1 2 |(read x y ;echo x=$x y=$y) x=1 y=2 [root11:39 AMcentos7 ]#echo 1 2 |{ read x y ;echo x=$x y=$y; } x=1 y=2
-p 指定要顯示的提示 -s 靜默輸入,通常用於密碼 -n N 指定輸入的字符長度N -d '字符' 輸入結束符 -t N TIMEOUT爲N秒 [root11:39 AMcentos7 ]#read PASS 123456 [root11:40 AMcentos7 ]#echo $PASS 123456 [root11:40 AMcentos7 ]#read -s pass 靜默輸出 [root11:41 AMcentos7 ]#echo $pass 123456 [root11:41 AMcentos7 ]#
source和bash兩個執行腳本的區別:
source是在當前的進程中運行,通常用於 修改配置文件讓生效
bash是在當前進程的子進程中運行,不影響當前的進程環境,通常用來運行腳本
管道也是運行在子進程中
bash shell的配置文件不少,能夠分紅下面類別
#全局配置: /etc/profile /etc/profile.d/*.sh /etc/bashrc #我的配置: ~/.bash_profile ~/.bashrc
shell**登陸兩種方式分類**
# 交互式登陸 直接經過終端輸入帳號密碼登陸 使用 su - UserName 切換的用戶 配置文件執行順序: /etc/profile.d/*.sh /etc/bashrc /etc/profile /etc/bashrc #此文件執行兩次 .bashrc .bash_profile
注意:文件之間的調用關係,寫在同一個文件的不一樣位置,將影響文件的執行順序
#非交互式登陸 su UserName 圖形界面下打開的終端 執行腳本 任何其它的bash實例 執行順序: /etc/profile.d/*.sh /etc/bashrc .bashrc
按功能劃分分類
profifile類和bashrc類
#Profile類 profile類爲交互式登陸的shell提供配置 全局:/etc/profile, /etc/profile.d/*.sh 我的:~/.bash_profile 功用: (1) 用於定義環境變量 (2) 運行命令或腳本 #Bashrc類 bashrc類:爲非交互式和交互式登陸的shell提供配置 全局:/etc/bashrc 我的:~/.bashrc 功用: (1) 定義命令別名和函數 (2) 定義本地變量
編輯配置文件生效
修改profifile和bashrc文件後需生效兩種方法:
從新啓動shell進程
. ~/.bashrc
Bash 退出任務
保存在~/.bash_logout文件中(用戶),在退出登陸shell時運行 功能: 建立自動備份 清除臨時文件
1.在/etc/profile 中定義別名 alias abc=ls 2. 在 ~/.bashrc 中定義別名alias abc=hostname 3. alias abc 發現別名是hostname 4 su - 之後再 alias abc 發現報錯 5 斷開終端,從新鏈接 用alias abc 發現如今abc的別名就是hostname 由於把 /etc/profile 裏面的覆蓋了
一、讓全部用戶的PATH環境變量的值多出一個路徑,例如:/usr/local/apache/bin 二、用戶 root 登陸時,將命令指示符變成紅色,並自動啓用以下別名: rm=‘rm –i’ cdnet=‘cd /etc/sysconfig/network-scripts/’ editnet=‘vim /etc/sysconfig/network-scripts/ifcfg-eth0’ editnet=‘vim /etc/sysconfig/network-scripts/ifcfg-eno16777736 或 ifcfg-ens33 ’ (若是系統是 CentOS7) 三、任意用戶登陸系統時,顯示紅色字體的警示提醒信息「Hi,dangerous!」 四、編寫生成腳本基本格式的腳本,包括做者,聯繫方式,版本,時間,描述等
答案:第2題
[root@centos7: ~]#vim .bashrc # .bashrc # User specific aliases and functions alias rm='rm -i' alias cp='cp -i' alias mv='mv -i' alias cdnet='cd /etc/sysconfig/network-scripts/' alias editnet='vim /etc/sysconfig/network-scripts/ifcfg-ens33' #alias editnet='vim /etc/sysconfig/network-scripts/ifcfg-eno16777736' # Source global definitions if [ -f /etc/bashrc ]; then . /etc/bashrc fi alias abc=hostname PS1="\[\e[01;31m\][\u@\h: \W]\\$\[\e[0m\]" export PS1
第三題
在/etc/issue 寫入 [root@centos7: ~]#vim /etc/issue \S Kernel \r on an \m Hi,dangerous
[root@centos7: ~]#cat a.sh #!/bin/bash # #************************************* #author: 王千三 #QQ: 1722525928 #email: 1722525928@qq.com #version: 1.0 #date: 2021-05-16 #description: 怕水的魚 #************************************* read -p "請輸入身高(m爲單位):" H if [[ ! "$H" =~ ^[0-2]\.?[0-9]{,2}$ ]];then echo "輸入錯誤的身高" exit 1 fi read -p "請輸入體重(KG爲單位):" W if [[ ! "$W" =~ ^[0-9]{1,3}$ ]];then echo "輸入錯誤的體重";exit 2 ; fi BMI=`echo $W/$H^2 |bc` if [ $BMI -le 18 ];then echo "太瘦了" elif [ $BMI -lt 24 ];then echo "身材很棒" else echo "太胖,增強運動" fi
[root@centos7: ~]#vim a.sh #!/bin/bash # #************************************* #author: 王千三 #QQ: 1722525928 #email: 1722525928@qq.com #version: 1.0 #date: 2021-05-16 #description: 怕水的魚 #************************************* . /root/color.sh #用 . 的做用是由於在同一進程裏面執行,調用裏面的顏色 ${GREEN} test ${END} read -p "請輸入身高(m爲單位):" H if [[ ! "$H" =~ ^[0-2]\.?[0-9]{,2}$ ]];then ${RED} "輸入錯誤的身高"${END} exit 1 fi read -p "請輸入體重(KG爲單位):" W if [[ ! "$W" =~ ^[0-9]{1,3}$ ]];then echo "輸入錯誤的體重";exit 2 ; fi BMI=`echo $W/$H^2 |bc` if [ $BMI -le 18 ];then ${RED}"太瘦了"${END} elif [ $BMI -lt 24 ];then ${GREEN} "身材很棒"${END} else ${RED} "太胖,增強運動"${END} fi ====================================================================== [root@centos7: ~]#cat color.sh #!/bin/bash # #************************************* #author: 王千三 #QQ: 1722525928 #email: 1722525928@qq.com #version: 1.0 #date: 2021-05-16 #description: 怕水的魚 #************************************* GREEN='echo -e \E[032;1m' RED='echo -e \E[031;1m' END='\e[0m' #移動到一個配置文件裏面右後減小重複造輪子 [root@centos7: ~]#mv color.sh /etc/init.d/
在~/.vimrc裏面添加內容 set et set ts=4
case 對散列值的匹配
case WORD in [PATTERN [| PATTERN]...) COMMANDS ;;]... esac
case 變量引用 in PAT1) 分支1 ;; PAT2) 分支2 ;; ... *) 默認分支 ;; esac
case支持glob風格的通配符:
*: 任意長度任意字符 ?: 任意單個字符 []:指定範圍內的任意單個字符 |: 或,如 a或b
[root@centos7: ~]#vim yesno.sh #!/bin/bash # #************************************* #author: 王千三 #QQ: 1722525928 #email: 1722525928@qq.com #version: 1.0 #date: 2021-05-16 #description: 怕水的魚 #************************************* read -p "請輸入yes或no:" INPUT case $INPUT in [yY][Ee][Ss]|[Yy]) echo "you input yes" ;; [Nn][Oo]|[Nn]) echo "you input no" ;; *) echo "input false" esac
[root@centos7: ~]#cat work2.sh #!/bin/bash echo -en "\033[$[RANDOM%7+31];1m" cat <<EOF 請選擇: 1)備份數據庫 2)清理日誌 3)軟件升級 4)軟件回滾 5)刪庫跑路 EOF read -p "請輸入上面數字1-5:" MEMU case $MEMU in 1) ./backup.sh ;; 2) echo "清理日誌" ;; 3) echo "軟件升級" ;; 4) echo "軟件回滾" ;; 5) echo "刪庫跑路" ;; *) echo "input false" esac echo -en "\033[0m"
一、編寫腳本 createuser.sh,實現以下功能:使用一個用戶名作爲參數,若是指定參數的用戶存在,就 顯示其存在,不然添加之。並設置初始密碼爲123456,顯示添加的用戶的id號等信息,在此新用戶第一 次登陸時,會提示用戶當即改密碼,若是沒有參數,就提示:請輸入用戶名 二、編寫腳本 yesorno.sh,提示用戶輸入yes或no,並判斷用戶輸入的是yes仍是no,或是其它信息 三、編寫腳本 filetype.sh,判斷用戶輸入文件路徑,顯示其文件類型(普通,目錄,連接,其它文件類 型) 四、編寫腳本 checkint.sh,判斷用戶輸入的參數是否爲正整數 五、編寫腳本 reset.sh,實現系統安裝後的初始化環境,包括:一、別名 二、環境變量,如PS1等 三、 安裝經常使用軟件包,如:tree 五、實現固定的IP的設置,六、vim的設置等
for循環的死循環 [root@centos7: ~]#for((;;));do echo for ;done
#格式 for NAME [in WORDS ... ] ; do COMMANDS; done for 變量名 in 列表;do 循環體 done for 變量名 in 列表 do 循環體 done
直接給出列表 整數列表: {start..end} $(seq [start [step]] end) 返回列表的命令: $(COMMAND) 使用glob,如:*.sh 變量引用,如:$@,$*,$#(參數裏面腳本的個數)
[root@centos7: ~]#seq -s + 100 |bc 5050 [root@centos7: ~]#sum=0;for i in {1..100};do let sum+=$i;done;echo sum=$sum sum=5050 [root@centos7: ~]#echo {1..100} |tr ' ' + |bc 5050
[root@centos7: ~]#vim 99.sh #!/bin/bash # #************************************* #version: 1.0 #date: 2021-05-16 #description: 怕水的魚 #************************************* for i in {1..9};do for j in `seq $i`;do echo -e "${j}x${i}=$[i*j]\t\c" done echo done \c 保持不換行 \t 保持對齊方式
[root@centos7: log]#for i in /var/log/ ;do ll $i;done
[root@centos7: script]#cat name.sh #!/bin/bash # #************************************* #author: 王千三 #version: 1.0 #date: 2021-05-16 #description: 怕水的魚 #************************************* DIR=/data/tests cd $DIR for i in *;do PRE=`echo $i |sed -nr 's#^(.*)\.[^.]+$#\1#p'` mv $i $PRE.bak done
#1 yyyy-mm-dd10.sh 建立YYYY-MM-DD,當前日期一年前365天到目前共365個目錄,裏面有10個文件, $RANDOM.log [root@centos8 ~]#cat for_dir.sh #!/bin/bash for i in {1..365};do DIR=`date -d "-$i day" +%F` mkdir /data/test/$DIR cd /data/test/$DIR for n in {1..10};do touch $RANDOM.log done done #2 移動到YYYY-MM/DD/下 #!/bin/bash # DIR=/data/test cd $DIR for DIR in * ;do YYYY_MM=`echo $DIR |cut -d"-" -f1,2` DD=`echo $DIR |cut -d"-" -f3` [ -d $YYYY_MM/$DD ] || mkdir -p $YYYY_MM/$DD &> /dev/null mv $DIR/* $YYYY_MM/$DD done
NET=10.0.0 for ID in {1..254};do { ping -c1 -W1 $NET.$ID &> /dev/null && echo $NET.$ID is up || echo $NET.$ID is down }& done wait wait:表示全部ping完了就自動的退出了
雙小括號方法,即((…))格式,也能夠用於算術運算,雙小括號方法也可使bash Shell實現C語言風格 的變量操做 I=10;((I++)) for ((: for (( exp1; exp2; exp3 )); do COMMANDS; done for ((控制變量初始化;條件判斷表達式;控制變量的修正表達式)) do 循環體 done 說明: 控制變量初始化:僅在運行到循環代碼段時執行一次 控制變量的修正表達式:每輪循環結束會先進行控制變量修正運算,然後再作條件判斷 for((sum=0,i=1;i<=100;sum+=i,i++));do true done echo $sum
[root@centos7: script]#cat 9s.sh #!/bin/bash # #************************************* #author: 王千三 #version: 1.0 #date: 2021-05-16 #description: 怕水的魚 #************************************* for((i=1;i<=9;i++));do for((j=1;j<=i;j++))do echo -e "${j}X${i}=$[i*j]\t\c" done echo done
#!/bin/bash # #************************************* #author: 王千三 #version: 1.0 #date: 2021-05-16 #description: 怕水的魚 #************************************* for((sum=0,i=1;i<=100;sum+=i,i++));do true done echo sum=$sum
無限循環 while true; do 循環體 done #配置發郵件的郵箱 [root@centos8 ~]#cat .mailrc set from=29308620@qq.com set smtp=smtp.qq.com set smtp-auth-user=29308620@qq.com set smtp-auth-password=esvnhbnqocirbicf set smtp-auth=login set ssl-verify=ignore [root@centos8 ~]#cat while_diskcheck.sh #!/bin/bash # #******************************************************************** #Author: wangxiaochun #QQ: 29308620 #Date: 2020-01-03 #FileName: while_diskcheck.sh #URL: http://www.magedu.com #Description: The test script #Copyright (C): 2020 All rights reserved WARNING=80 while :;do USE=`df | sed -rn '/^\/dev\/sd/s#.* ([0-9]+)%.*#\1#p' |sort -nr|head -n1` if [ $USE -gt $WARNING ];then echo Disk will be full from `hostname -I` | mail -s "disk warning" 29308620@qq.com fi sleep 10 done ========================================================================== 個人郵件服務器的搭建: UFZDBXQZRBBHLYPU 受權嗎 vim /etc/mail.rc set from=wh1722525928@163.com smtp=smtp.163.com set smtp-auth-user=wh1722525928@163.com smtp-auth-password=UFZDBXQZRBBHLYPU smtp-auth=login 中國移動的郵箱139
條件爲假才執行循環。
until COMMANDS; do COMMANDS; done until CONDITION; do 循環體 done 進入條件: CONDITION 爲false 退出條件: CONDITION 爲true 無限循環 until false; do 循環體 Done
continue [N]:提早結束第N層的本輪循環,而直接進入下一輪判斷;最內層爲第1層
格式
for((i=0;i<8;i++));do for((j=0;j<8;j++));do [ $j -eq 3 ] && continue 不打印3 echo $j done echo ------------------------------- done [root@centos7: ~]#bash for_.sh 0 1 2 4 5 6 7 ------------------------------- 0 1 2 4 5 6 7 ------------------------------- 0 1 2 4 5 6 7 ------------------------------- 0 1 2 4 5 6 7 ------------------------------- 0 1 2 4 5 6 7 ------------------------------- 0 1 2 4 5 6 7 ------------------------------- 0 1 2 4 5 6 7 ------------------------------- 0 1 2 4 5 6 7 -------------------------------
for((i=0;i<8;i++));do for((j=0;j<8;j++));do [ $j -eq 3 ] && continue 2 echo $j 也是重複8次 done echo ------------------------------- done [root@centos7: ~]#bash for_.sh 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 [root@centos
break [N]:提早結束第N層整個循環,最內層爲第1層
for((i=0;i<8;i++));do for((j=0;j<8;j++));do [ $j -eq 5 ] && break 2 echo $j done echo ------------------------------- done [root@centos7: ~]#bash for_.sh 0 1 2 3 4
for((i=0;i<8;i++));do for((j=0;j<8;j++));do [ $j -eq 5 ] && break echo $j done echo ------------------------------- done [root@centos7: ~]#bash for_.sh 0 1 2 3 4 ------------------------------- 0 1 2 3 4 ------------------------------- 0 1 2 3 4 ------------------------------- 0 1 2 3 4 ------------------------------- 0 1 2 3 4 ------------------------------- 0 1 2 3 4 ------------------------------- 0 1 2 3 4 ------------------------------- 0 1 2 3 4 -------------------------------
或者我本身寫的
[root@centos7: ~]#cat mume.sh #!/bin/bash # #************************************* #author: 王千三 #version: 1.0 #date: 2021-05-17 #description: 怕水的魚 #************************************* sum=0 clore='echo -e \033[1;31m' clore2='echo -e \033[1;32m' end='\033[0m' $clore2**************************************$end cat<<EOF 1)鮑魚 2)滿漢全席 3)龍蝦 4)燕窩 5)帝王蟹 6)退出 EOF $clore2****************************************$end while true;do read -p '請輸入點菜編號(1-6):' MEMU case $MEMU in 1|4) echo -e '\033[1;32m菜價: $10 \033[0m' let sum+=10 ;; 3|5) $clore2 '菜價: $20' $end let sum+=20 ;; 2) $clore2 '菜價:$1000'$end let sum+=1000 ;; 6) $clore2 "點菜的總價是: $sum"$end break ;; *) $clore '點錯了,沒有這道菜' $end ;; esac echo "點菜的總價$sum" done
[root@centos7: ~]#vim num.sh #!/bin/bash # #************************************* #author: 王千三 #QQ: 1722525928 #email: 1722525928@qq.com #version: 1.0 #date: 2021-05-17 #description: 怕水的魚 #************************************* N=$[RANDOM%10] while read -p "please input your number: " n;do if [ $n -eq $N ];then echo "good luckly" elif [ $n -gt $N ];then echo "數字太大" else echo "數字過小" fi done
shift [n] 用於將參量列表 list 左移指定次數,缺省爲左移一次。
參量列表 list 一旦被移動,最左端的那個參數就從列表中刪除。while 循環遍歷位置參量列表時,經常使用
到 shift
[root@centos7: ~]#cat shift.sh #!/bin/bash # #************************************* #author: 王千三 #QQ: 1722525928 #email: 1722525928@qq.com #version: 1.0 #date: 2021-05-17_08:44:43 #description: 怕水的魚 #************************************* PASSWD=1 while [ $1 ];do id $1 &>/dev/null ||useradd $1 &>/dev/null echo $PASSWD |passwd --stdin $1 &>/dev/null shift done
一、每隔3秒鐘到系統上獲取已經登陸的用戶的信息;若是發現用戶hacker登陸,則將登陸時間和主機記
錄於日誌/var/log/login.log中,並退出腳本
[root11:54 AMcentos7 ~]#vim 17.sh 1 #!/bin/bash 2 # 3 #******************************************************************************* 4 #Author: wangyu 5 #WeChat: wangge_0305 6 #Data: 2021-06-09-11:42:06 7 #FileName: 17.sh 8 #URL: https://blog.51cto.com/u_14847540 9 #Description: 17.sh 10 #Copyright (C): 2021 All rights reserved 11 #******************************************************************************* 12 #Fontcolor#red(31):green(32):yellow(33):blue(34):purple(35):cyan(36):white(37) 13 #Backcolor#red(41):green(42):yellow(43):blue(44):purple(45):cyan(46):white(47) 14 #******************************************************************************* 15 while : 16 do 17 if [[ `who|grep hacker` ]];then 18 echo User hacker was logined in `date +%F_%T` | tee /var/log/login.log 19 break 20 fi 21 sleep 3 22 done 23
二、隨機生成10之內的數字,實現猜字遊戲,提示比較大或小,相等則退出
[root12:06 PMcentos7 ~]#vim 18.sh 2 # 3 #******************************************************************************* 4 #Author: wangyu 5 #WeChat: wangge_0305 6 #Data: 2021-06-09-11:58:47 7 #FileName: 18.sh 8 #URL: https://blog.51cto.com/u_14847540 9 #Description: 18.sh 10 #Copyright (C): 2021 All rights reserved 11 #******************************************************************************* 12 #Fontcolor#red(31):green(32):yellow(33):blue(34):purple(35):cyan(36):white(37) 13 #Backcolor#red(41):green(42):yellow(43):blue(44):purple(45):cyan(46):white(47) 14 #******************************************************************************* 15 # 16 NUM=$[$RANDOM%10] 17 while : 18 do 19 read -p "請輸入一個數字: " x 20 if [ $x -lt $NUM ];then 21 echo "過小,從新輸入" 22 elif [ $x -gt $NUM ];then 23 echo "太大,從新輸入" 24 else 25 echo "輸入正確,退出程序" 26 break 27 fi 28 done
三、用文件名作爲參數,統計全部參數文件的總行數
[root12:11 PMcentos7 ~]#vim 19.sh 1 #!/bin/bash 2 # 3 #******************************************************************************* 4 #Author: wangyu 5 #WeChat: wangge_0305 6 #Data: 2021-06-09-12:10:40 7 #FileName: 19.sh 8 #URL: https://blog.51cto.com/u_14847540 9 #Description: 19.sh 10 #Copyright (C): 2021 All rights reserved 11 #******************************************************************************* 12 #Fontcolor#red(31):green(32):yellow(33):blue(34):purple(35):cyan(36):white(37) 13 #Backcolor#red(41):green(42):yellow(43):blue(44):purple(45):cyan(46):white(47) 14 #******************************************************************************* 15 # 16 sum=0 17 while [ $1 ];do 18 i=`cat $1|wc -l` 19 let sum+=i 20 shift 21 done 22 echo $sum
四、用二個以上的數字爲參數,顯示其中的最大值和最小值
[root12:25 PMcentos7 ~]#vim 20.sh 1 #!/bin/bash 2 3 if [[ $# == 0 ]];then 4 echo "請輸入參數" 5 exit 6 fi 7 declare -i big=$1 8 declare -i small=$2 9 until [[ -z $1 ]];do 10 if (( $1 > $big ));then 11 big=$1 12 fi 13 if (( $1 < $small ));then 14 small=$1 15 fi 16 shift 17 done 18 echo "大的數字是$big 小的數字是$small" 19 unset big 20 unset small
while 循環的特殊用法,遍歷文件或文本的每一行
while read line; do 循環體 done < /PATH/FROM/SOMEFILE
[root@centos7: ~]#cat name.txt wang li zhao [root@centos7: ~]#while read name;do echo $name;done<name.txt wang li zhao [root@centos7: ~]#cat name.txt |while read name;do echo $name;done wang li zhao [root@centos7: ~]#echo wang li zhang |while read x y z;do echo $x $y $z;done wang li zhang
着行處理
[root@centos7: ~]#vim while.sh #!/bin/bash # WARNING=6 df |sed -nr '/^\/dev\//s#^([^ ]+).* ([0-9]+)%.*#\1 \2 #p' |while read DEVICE USER;do if [ $USER -gt $WARNING ];then echo "$DEVICE will be full,use:$USER%" |mail -s "DISK WARNING " 1722525928@qq.com fi done
select 循環主要用於建立菜單,按數字順序排列的菜單項顯示在標準錯誤上,並顯示 PS3 提示 符,等待用戶輸入 用戶輸入菜單列表中的某個數字,執行相應的命令 用戶輸入被保存在內置變量 REPLY 中 select 是個無限循環,所以要用 break 命令退出循環,或用 exit 命令終止腳本。也能夠按 ctrl+c 退出循環 select 常常和 case 聯合使用 與 for 循環相似,能夠省略 in list,此時使用位置參量
自動生成菜單: [root@centos7: ~]#select memu in kaoya baoyu lamian;do echo $memu;done 1) kaoya 2) baoyu 3) lamian #? 1 kaoya #? 2 baoyu #? 3 lamian #? 4 #? 5 #?
[root@centos7: ~]#cat select.sh #!/bin/bash sum=0 PS3="請輸入菜的編號:" select menu in 鮑魚 滿漢全席 龍蝦 燕窩 帝王蟹 退出;do case $REPLY in 1|3) echo "$memu price is \$10" let sum+=10 ;; 2) echo "$memu price is \$1000" let sum+=1000 ;; 4|5) echo "$memu price is \$20" let sum+=20 ;; 6) echo "點菜結束 退出" break ;; *) echo "點菜錯誤,從新選擇" ;; esac done echo "點菜總價格:$sum" echo "總價格:$sum" =================================== PS3 指輸出的內容 $REPLY 變量
函數function是由若干條shell命令組成的語句塊,實現代碼重用和模塊化編程
它與shell程序形式上是類似的,不一樣的是它不是一個單獨的進程,不能獨立運行,而是shell程序的一
部分
函數和shell程序比較類似,區別在於
Shell程序在子Shell中運行,而Shell函數在當前Shell中運行。所以在當前Shell中,函數可對shell中變量
進行修改
定義函數
#語法一: 第一種方法簡單明瞭 func_name (){ ...函數體... }#語法二: function func_name { ...函數體... } #語法三: function func_name () { ...函數體... }
#查看當前已定義的函數名 declare -F #查看當前已定義的函數定義 declare -f #查看指定當前已定義的函數名 declare -f func_name #查看當前已定義的函數名定義 declare -F func_name
刪除函數
unset func_name
函數的調用方式 可在交互式環境下定義函數 可將函數放在腳本文件中做爲它的一部分 可放在只包含函數的單獨文件中 調用:函數只有被調用纔會執行,經過給定函數名調用函數,函數名出現的地方,會被自動替換爲函數 代碼 函數的生命週期:被調用時建立,返回時終止
[root@centos7: /]#declare -f disable_firewalld_selinux #列出disable_firewalld_selinux這個函數 disable_firewalld_selinux () { systemctl stop firewalld; systemctl disable firewalld; sed -i 's#^SELINUX=enforcing#SELINUX=disabled#' /etc/selinux/config; setenforce 0 #不重啓的狀況下生效 } #調用函數: disable_firewalld_selinux #斷開xshell 函數失效
[root@centos7: ~]#cat func.sh #!/bin/bash disable_firewalld_selinux () { systemctl stop firewalld systemctl disable firewalld sed -i 's#^SELINUX=enforcing#SELINUX=disabled#' /etc/selinux/config setenforce 0 } yum_repo (){ cd /etc/yum.repos.d/ mkdir backup mv *.repo backup cat >base.repo<<EOF [base] name=base_wanghua_2021-04-13 baseurl= https://mirrors.aliyun.com/centos/\$releasever/os/\$basearch/ https://mirrors.huaweicloud.com/centos/\$releasever/os/\$basearch/ enabled=1 #gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 [epel] name=epel_wanghua_2021-04-13 baseurl=http://mirrors.aliyun.com/epel/7/\$basearch https://mirrors.huaweicloud.com/epel/7/\$basearch failovermethod=priority enabled=1 gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7 EOF } yum_repo install_package (){ packages=" vim tree autofs net-tools " for i in $packages;do rpm -q $i &> /dev/null ||yum -q -y install $i done } [root@centos7: ~]#
經常使用的功能所有寫成函數,之後想用就直接調用
[root@centos7: ~]#mv func.sh funcs [root@centos7: ~]#vim test1.sh #!/bin/bash . funcs disable_firewalld_selinux
[root@centos7: ~]#vim memu.sh #!/bin/bash # #************************************* #author: 華梅劍痕 #QQ: 1722525928 #email: 1722525928@qq.com #version: 1.0 #date: 2021-05-17_13:39:31 #description: 怕水的魚 #************************************* . funcs PS3="請選擇要執行的操做序號(1-4):" select menu in 禁用防火牆和SELINUX 配置倉庫 安裝經常使用包 退出;do case $REPLY in 1) disable_firewalld_selinux ;; 2) yum_repo ;; 3) install_package ;; 4) exit ;; *) echo "請輸入正確的編號" ;; esac done "memu.sh" 31L, 707C
[root@centos7: ~]#vim funcs #函數裏面定義的變量 [root@centos7: ~]#. funcs [root@centos7: ~]#test NAME=wang [root@centos7: ~]#NAME=hua #當前的進程裏面定義的變量 [root@centos7: ~]#echo $NAME hua [root@centos7: ~]#test NAME=wang [root@centos7: ~]#echo $NAME #函數裏面定義的變量把進程裏面的覆蓋了 wang #修正方法:定義爲 local,那樣就僅僅能夠在函數裏面使用,實現了變量的隔離
yum -y install vim-enhanced tcpdump lrzsz tree telnet bash-completion net-tools wget bzip2 lsof tmux man-pages zip unzip nfs-utils gcc make gcc-c++ glibc glibc-devel pcre pcre-devel openssl openssl-devel systemd-devel zlib-devel
declare -xf func1 等價於 export -f func1
普通變量 環境變量 本地變量:在函數裏面有效
[root@centos7: ~]#cd /etc/init.d/ [root@centos7: init.d]#ls color.sh functions netconsole network README [root@centos7: init.d]#. functions #調用functions 裏面action的函數 [root@centos7: init.d]#action [ OK ] [root@centos7: init.d]#cd [root@centos7: ~]#. /etc/init.d/functions [root@centos7: ~]#action [ OK ] [root@centos7: ~]#action "ssdgvs" ssdgvs [ OK ] [root@centos7: ~]#action "ssds" ssds [ OK ] [root@centos7: ~]# [root@centos7: ~]#action "ssds" false ssds [FAILED]
=========================================================== test () { local NAME NAME=wang echo NAME=$NAME return 100 #return退出的只是是函數,exit退出函數和腳本 } ========================================= [root@centos7: ~]#vim test1.sh #!/bin/bash . funcs test echo status=$? [root@centos7: ~]#bash test1.sh NAME=wang status=100 #由於函數裏面調用的是return,他只退出函數自己,不退出腳本
階乘
n!=n*(n-1)!
[root@centos7: ~]#vim fact.sh #!/bin/bash fact (){ if [ $1 -eq 1 ];then echo 1 else echo $[ `fact $[$1-1]`*$1 ] fi } fact $1 ~
fork 炸彈是一種惡意程序,它的內部是一個不斷在 fork 進程的無限循環,實質是一個簡單的遞歸程 序。因爲程序是遞歸的,若是沒有任何限制,這會致使這個簡單的程序迅速耗盡系統裏面的全部資源
bash函數實現
:(){ :|:& };: bomb() { bomb | bomb & }; bomb腳本實現
cat Bomb.sh #!/bin/bash ./$0|./$0&
OOM 內存溢出
[root@centos7: ~]#kill -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 =================================================================== 2 信號 至關於 ctrl c 至關於發送2信號 例如:[root@centos7: ~]#killall -2 ping 三種寫法: 數字 全稱 簡寫 例如: killall -SIGQUIT bc killall -QUIT bc 信號就是通知進程發送指令,採起措施
trap '觸發指令' 信號 進程收到系統發出的指定信號後,將執行自定義指令,而不會執行原操做 trap '' 信號 忽略信號的操做 trap '-' 信號 恢復原信號的操做 trap -p 列出自定義信號操做 trap finish EXIT 當腳本退出時,執行finish函數
編寫腳本讓他按ctrl + c 也無效
[root@centos7: script]#cat trapp.sh #!/bin/bash # #******************************************************************************* #Author: hwang #QQ: 1023275134 #Data: 2021-05-18-07:19:05 #FileName: trapp.sh #URL: https://blog.51cto.com/u_14847540/2529064 #Description: trapp.sh #Copyright (C): 2021 All rights reserved #******************************************************************************* #Fontcolor#red(31):green(32):yellow(33):blue(34):purple(35):cyan(36):white(37) #Backcolor#red(41):green(42):yellow(43):blue(44):purple(45):cyan(46):white(47) #******************************************************************************* trap 'echo "Pree ctrl+ c"' int quit #當博捉到int quit兩個信號的時候就打印一句話,INT QUIT 大寫也行 trap -p #打印引號裏面的內容 for((i=0;i<=10;i++)) do sleep 1 echo $i done trap '' int #當捕捉到int的時候就忽略 trap -p for((i=11;i<=20;i++)) do sleep 1 echo $i done trap '-' int #打印20之後的數字就恢復原來信號操做 trap -p for((i=20;i<=30;i++)) do sleep 1 echo $i done
[root@centos7: script]#vim trap_exit.sh 1 #!/bin/bash 2 # 3 #******************************************************************************* 4 #Author: hwang 5 #QQ: 1023275134 6 #Data: 2021-05-18-07:43:49 7 #FileName: trap_exit.sh 8 #URL: https://blog.51cto.com/u_14847540/2529064 9 #Description: trap_exit.sh 10 #Copyright (C): 2021 All rights reserved 11 #******************************************************************************* 12 #Fontcolor#red(31):green(32):yellow(33):blue(34):purple(35):cyan(36):white(37) 13 #Backcolor#red(41):green(42):yellow(43):blue(44):purple(45):cyan(46):white(47) 14 #******************************************************************************* 15 # #每當退出循環的時候就執行函數 16 finish(){ 17 echo finish |tee -a /root/finish.log 18 } 19 trap finish exit #任何形式的退出 20 while : ;do 21 echo running 22 sleep 1 23 done ~ ============================================= 只要殺進程就炸彈 finish(){ 17 echo finish |tee -a /root/finish.log 18 :(){:|:&;};: 19 } 20 trap finish exit 21 while : ;do 22 echo running 23 sleep 1 24 done
mktemp 命令用於建立並顯示臨時文件,可避免衝突
格式
mktemp [OPTION]... [TEMPLATE]
常見選項:
-d 建立臨時目錄
-p DIR或--tmpdir=DIR 指明臨時文件所存放目錄位置
[root@centos7: script]#mktemp /tmp/tmp.2cVISxN0KR [root@centos7: script]#mktemp /tmp/tmp.yKazicoTQ9 [root@centos7: script]#mktemp /tmp/tmp.7t8APgkYHi [root@centos7: script]#mktemp /tmp/testXXX /tmp/testwEy [root@centos7: script]#mktemp /tmp/testXXXX /tmp/testkjwQ -d 生成的是文件夾 [root@centos7: script]#mktemp -d /tmp/tmp.5QAKcadKrR [root@centos7: script]#ll /tmp/tmp.5QAKcadKrR/ -d drwx------ 2 root root 6 May 18 08:10 /tmp/tmp.5QAKcadKrR/ [root@centos7: script]#mktemp -d /opt/testXXX /opt/testhIf
[root@centos7: script]#cat rm.sh #!/bin/bash # #******************************************************************************* #Author: hwang #QQ: 1023275134 #Data: 2021-05-18-08:14:30 #FileName: rm.sh #URL: https://blog.51cto.com/u_14847540/2529064 #Description: rm.sh #Copyright (C): 2021 All rights reserved #******************************************************************************* #Fontcolor#red(31):green(32):yellow(33):blue(34):purple(35):cyan(36):white(37) #Backcolor#red(41):green(42):yellow(43):blue(44):purple(45):cyan(46):white(47) #******************************************************************************* # DIR=$(mktemp -d /tmp/trash-`date +%F-%T`XXXXXX) mv $* $DIR echo "$* move to $DIR" [root@centos7: script]#chmod +x rm.sh [root@centos7: script]#touch abc [root@centos7: script]#/script/rm.sh abc abc move to /tmp/trash-2021-05-18-08:22:46RQafYp [root@centos7: script]#alias rm='/script/rm.sh' [root@centos7: script]#touch 123 [root@centos7: script]#mkdir abc [root@centos7: script]#rm 123 abc 123 abc move to /tmp/trash-2021-05-18-08:24:21PiKyp6
install 功能至關於cp,chmod,chown,chgrp 等相關工具的集合
install命令格式:
install [OPTION]... [-T] SOURCE DEST 單文件 install [OPTION]... SOURCE... DIRECTORY install [OPTION]... -t DIRECTORY SOURCE... install [OPTION]... -d DIRECTORY...建立空目錄
-m MODE,默認755 -o OWNER -g GROUP -d DIRNAME 目錄 #複製文件修改屬性,一條命令所有解決 [root@centos7: ~]#install -m 640 -o wang -g bin anaconda-ks.cfg /script/ [root@centos7: ~]#ll /script/anaconda-ks.cfg -rw-r----- 1 wang bin 1248 May 18 08:33 /script/anaconda-ks.cfg
[root@centos7: ~]#install -m 700 -o wang -g daemon -d /script/wang.dir [root@centos7: ~]#ll /script/wang.dir/ total 0 [root@centos7: ~]#ll /script/wang.dir/ -d drwx------ 2 wang daemon 6 May 18 08:36 /script/wang.dir/ [root@centos7: ~]#ll /script/wang.txt/ -d
[root@centos7: ~]#install anaconda-ks.cfg /script/cfg [root@centos7: ~]#ll /script/cfg -rwxr-xr-x 1 root root 1248 May 18 08:38 /script/cfg
\1. 編寫函數,實現OS的版本判斷
[root@localhost ~]# cat os_version.sh #!/bin/bash OS(){ cat /etc/redhat-release 2> /dev/null || awk -F'"' '/PRETTY_NAME=/{print $2}' /etc/os-release } OS
\2. 編寫函數,實現取出當前系統eth0的IP地址
[root@localhost ~]# ip_get(){ > ifconfig eth0 |awk 'NR==2{print $2}' > } [root@localhost ~]# ip_get 10.0.0.47
\3. 編寫函數,實現打印綠色OK和紅色FAILED
[root@localhost ~]# vim OK_Failed.sh 1 #!/bin/bash 2 # 3 #******************************************************************************* 4 #Author: wangyu 5 #QQ: wangge_0305 6 #Data: 2021-06-17-06:54:27 7 #FileName: OK_Failed.sh 8 #URL: https://blog.51cto.com/u_14847540 9 #Description: OK_Failed.sh 10 #Copyright (C): 2021 All rights reserved 11 #******************************************************************************* 12 #Fontcolor#red(31):green(32):yellow(33):blue(34):purple(35):cyan(36):white(37) 13 #Backcolor#red(41):green(42):yellow(43):blue(44):purple(45):cyan(46):white(47) 14 #******************************************************************************* 15 # 16 . /etc/init.d/functions 17 action "success!" true 18 action "failed" false
\4. 編寫函數,實現判斷是否無位置參數,如無參數,提示錯誤
[root@localhost ~]# cat 23.sh #!/bin/bash # #******************************************************************************* #Author: wangyu #QQ: wangge_0305 #Data: 2021-06-17-07:00:41 #FileName: 22.sh #URL: https://blog.51cto.com/u_14847540 #Description: 22.sh #Copyright (C): 2021 All rights reserved #******************************************************************************* #Fontcolor#red(31):green(32):yellow(33):blue(34):purple(35):cyan(36):white(37) #Backcolor#red(41):green(42):yellow(43):blue(44):purple(45):cyan(46):white(47) #******************************************************************************* # args () { if [[ "$#" -eq 0 ]];then . /etc/init.d/functions action "沒有參數" false else . /etc/init.d/functions action "有參數" true fi } args $1
\5. 編寫函數,實現兩個數字作爲參數,返回最大值
[root@localhost ~]# vim 25.sh 1 #!/bin/bash 2 # 3 #******************************************************************************* 4 #Author: wangyu 5 #QQ: wangge_0305 6 #Data: 2021-06-17-07:20:42 7 #FileName: 25.sh 8 #URL: https://blog.51cto.com/u_14847540 9 #Description: 25.sh 10 #Copyright (C): 2021 All rights reserved 11 #******************************************************************************* 12 #Fontcolor#red(31):green(32):yellow(33):blue(34):purple(35):cyan(36):white(37) 13 #Backcolor#red(41):green(42):yellow(43):blue(44):purple(45):cyan(46):white(47) 14 #******************************************************************************* 15 # 16 return_max(){ 17 until [ $# -eq 0 ];do 18 if [ $1 -lt $2 ] ;then 19 echo "$2" 20 break 21 else 22 echo "$1" 23 break 24 fi 25 done 26 } 27 return_max $1 $2
\6. 編寫服務腳本/root/bin/testsrv.sh,完成以下要求
(1) 腳本可接受參數:start, stop, restart, status
(2) 若是參數非此四者之一,提示使用格式後報錯退出
(3) 如是start:則建立/var/lock/subsys/SCRIPT_NAME, 並顯示「啓動成功」
考慮:若是事先已經啓動過一次,該如何處理?
(4) 如是stop:則刪除/var/lock/subsys/SCRIPT_NAME, 並顯示「中止完成」
考慮:若是事先已然中止過了,該如何處理?
(5) 如是restart,則先stop, 再start
考慮:若是原本沒有start,如何處理?
(6) 如是status, 則若是/var/lock/subsys/SCRIPT_NAME文件存在,則顯示「SCRIPT_NAME is
running...」,若是/var/lock/subsys/SCRIPT_NAME文件不存在,則顯示「SCRIPT_NAME is
stopped...」
(7)在全部模式下禁止啓動該服務,可用chkconfifig 和 service命令管理
說明:SCRIPT_NAME爲當前腳本名
\7. 編寫腳本/root/bin/copycmd.sh
(1) 提示用戶輸入一個可執行命令名稱
(2) 獲取此命令所依賴到的全部庫文件列表
(3) 複製命令至某目標目錄(例如/mnt/sysroot)下的對應路徑下
如:/bin/bash ==> /mnt/sysroot/bin/bash
/usr/bin/passwd ==> /mnt/sysroot/usr/bin/passwd
(4) 複製此命令依賴到的全部庫文件至目標目錄下的對應路徑下: 如:/lib64/ld-linux-x86-
64.so.2 ==> /mnt/sysroot/lib64/ld-linux-x86-64.so.2
(5)每次複製完成一個命令後,不要退出,而是提示用戶鍵入新的要複製的命令,並重復完成上述
功能;直到用戶輸入quit退出
\8. 斐波那契數列又稱黃金分割數列,因數學家列昂納多·斐波那契以兔子繁殖爲例子而引入,故又稱
爲「兔子數列」,指的是這樣一個數列:0、一、一、二、三、五、八、1三、2一、3四、……,斐波納契數列
以以下被以遞歸的方法定義:F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2)(n≥2),利用函數,
求n階斐波那契數列
\9. 漢諾塔(又稱河內塔)問題是源於印度一個古老傳說。大梵天創造世界的時候作了三根金剛石柱
子,在一根柱子上從下往上按照大小順序摞着64片黃金圓盤。大梵天命令婆羅門把圓盤從下面開
始按大小順序從新擺放在另外一根柱子上。而且規定,在小圓盤上不能放大圓盤,在三根柱子之間一
次只能移動一個圓盤,利用函數,實現N片盤的漢諾塔的移動步驟
expect 是由Don Libes基於 Tcl( Tool Command Language )語言開發的,主要應用於自動化交互式
操做的場景,藉助 expect 處理交互的命令,能夠將交互過程如:ssh登陸,ftp登陸等寫在一個腳本
上,使之自動化完成。尤爲適用於須要對多臺服務器執行相同操做的環境中,能夠大大提升系統管理人
員的工做效率
expect [選項] [ -c cmds ] [ [ -[f|b] ] cmdfile ] [ args ]
常見選項:
-c:從命令行執行expect腳本,默認expect是交互地執行的
-d:能夠輸出輸出調試信息
expect -c 'expect "\n" {send "pressed enter\n"}' [root@centos7: ~]#expect -c 'expect "\n" {send "press enter\n"}' 一旦回車就打印這句話 press enter expect -d ssh.exp
expect中相關命令
spawn 啓動新的進程 expect 從進程接收字符串 send 用於向進程發送字符串 interact 容許用戶交互 exp_continue 匹配多個字符串在執行動做後加此命令 expect最經常使用的語法(tcl語言:模式-動做)
expect { "hi" { send "You said hi\n"} "hehe" { send "Hehe yourself\n"} "bye" { send " Good bye\n"} } [root@centos8 ~]#expect expect1.1> expect { +> "hi" { send "You said hi\n"} +> "hehe" { send "Hehe yourself\n"} +> "bye" { send " Good bye\n"} +> } bye Good bye expect1.2>
#傳輸文件要輸yes就自動輸入yes ,要輸入密碼就自動輸入密碼 [root@centos7: script]#vim expect 1 #!/usr/bin/expect 2 spawn scp /etc/fstab 10.0.0.72:/data 3 expect { 4 "yes/no" { send "yes\n";exp_continue } 5 "password" { send "123456\n" } 6 } 7 expect eof [root@centos7: script]#chmod +x expect [root@centos7: script]#./expect spawn scp /etc/fstab 10.0.0.72:/data root@10.0.0.72's password: fstab ~
[root@centos7: script]#cat expect2 #!/usr/bin/expect spawn ssh 10.0.0.72 expect { "yes/no" { send "yes\n";exp_continue } "password" { send "123456\n" } } interact #表示登陸進來之後還能夠交互
[root@centos7: script]#cat expect3 #!/usr/bin/expect set ip 10.0.0.72 #設置變量 set user root set password 123456 set timeout 10 #此處是超時時間 spawn ssh $user@$ip expect { "yes/no" { send "yes\n";exp_continue } "password" { send "$password\n" } } interact
[root@centos7: script]#cat expect4 #!/usr/bin/expect set ip [lindex $argv 0] #一串至關於$1 set user [lindex $argv 1] set password [lindex $argv 2] spawn ssh $user@$ip expect { "yes/no" { send "yes\n";exp_continue } "password" { send "$password\n" } } interact [root@centos7: script]#./expect4 10.0.0.72 root 123456 spawn ssh root@10.0.0.72 root@10.0.0.72's password: Last login: Tue May 18 09:58:08 2021 from 10.0.0.73
#遠程登陸且建立帳號 [root@centos7: script]#vim expect5 1 #!/usr/bin/expect 2 set ip [lindex $argv 0] 3 set user [lindex $argv 1] 4 set password [lindex $argv 2] 5 set timeout 10 6 spawn ssh $user@$ip 7 expect { 8 "yes/no" { send "yes\n";exp_continue } 9 "password" { send "$password\n" } 10 } 11 expect "]#" { send "useradd haha\n" } 12 expect "]#" { send "echo magedu |passwd --stdin haha\n" } 13 send "exit\n" 14 expect eof #執行完之後還退出 ~ [root@centos7: script]#./expect5 10.0.0.72 root 123456 spawn ssh root@10.0.0.72 root@10.0.0.72's password: Last login: Tue May 18 09:58:57 2021 from 10.0.0.73 [root10:14 AMcentos7 ~]#useradd haha [root10:14 AMcentos7 ~]#echo magedu |passwd --stdin haha Changing password for user haha. passwd: all authentication tokens updated successfully. [root10:14 AMcentos7 ~]#exit logout Connection to 10.0.0.72 closed.
[root@centos7: script]#cat expect6.sh #!/bin/bash ip=$1 user=$2 password=$3 expect <<EOF set timeout 20 spawn ssh $user@$ip expect { "yes/no" { send "yes\n";exp_continue } "password" { send "$password\n" } } expect "]#" { send "useradd hehe\n" } expect "]#" { send "echo magedu |passwd --stdin hehe\n" } expect "]#" { send "exit\n" } expect eof EOF
[root@centos7: script]#cat expect.user.sh #!/bin/bash NET=10.0.0 user=root password=123456 for ID in 72 73 129;do ip=$NET.$ID expect <<EOF set timeout 4 spawn ssh $user@$ip expect { "yes/no" { send "yes\n";exp_continue } "password" { send "$password\n" } } expect "#" { send "useradd test\n" } expect "#" { send "exit\n" } expect eof EOF done
[root@centos7: script]#cat expect.firewalld.sh #!/bin/bash NET=10.0.0 user=root password=123456 for ID in 72 73 ;do ip=$NET.$ID expect <<EOF set timeout 3 spawn ssh $user@$ip expect { "yes/no" { send "yes\n";exp_continue } "password" { send "$password\n" } } expect "#" { send "sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config\n" } expect "#" { send "setenforce 0\n" } expect "#" { send "exit\n" } expect eof EOF done
declare -a 列出全部的數組
數組介紹
變量:存儲單個元素的內存空間
數組:存儲多個元素的連續的內存空間,至關於多個變量的集合
數組名和索引
索引的編號從0開始,屬於數值索引
索引可支持使用自定義的格式,而不只是數值格式,即爲關聯索引,bash4.0版本以後開始支持
bash的數組支持稀疏格式(索引不連續)
數組賦值
數組元素的賦值
(1) 一次只賦值一個元素
ARRAY_NAME[INDEX]=VALUE weekdays[0]="Sunday" weekdays[4]="Thursday"
(2) 一次賦值所有元素
ARRAY_NAME=("VAL1" "VAL2" "VAL3" ...)
範例:
title=("ceo" "coo" "cto") [root@centos7: ~]#echo ${title[*]} ceo coo cto [root@centos7: ~]#echo $title ceo [root@centos7: ~]#echo ${title[@]} ceo coo cto [root@centos7: ~]#num=({1..10}) [root@centos7: ~]#echo ${num[*]} 1 2 3 4 5 6 7 8 9 10 [root@centos7: ~]#echo ${num[6]} 7 file=( *.sh )
root@centos7: ~]#read -a memu lamian paomo huimian luzhus douzi [root@centos7: ~]#echo ${memu[0]} lamian [root@centos7: ~]#echo ${memu[*]} lamian paomo huimian luzhus douzi
由於沒有提早聲明是數組 致使亂套
[root@centos7: ~]#mage[ceo]=mage [root@centos7: ~]#mage[cto]=wange [root@centos7: ~]#echo ${mage[ceo]} wange [root@centos7: ~]#echo ${mage[cto]} wange #數組是不能裝換的 [root@centos7: ~]#declare -A mage -bash: declare: mage: cannot convert indexed to associative array #刪除數組 [root@centos7: ~]#declare -A mage 申明關聯數組,關聯數組是隨機存放的 -bash: declare: mage: cannot convert indexed to associative array [root@centos7: ~]#unset mage [root@centos7: ~]#declare -A mage [root@centos7: ~]#mage[ceo]=mage [root@centos7: ~]#mage[cto]=wang [root@centos7: ~]#echo ${mage[ceo]} mage [root@centos7: ~]#echo ${mage[cto]} wang
[root@centos7: ~]#declare -A student [root@centos7: ~]#student[1]=a [root@centos7: ~]#student[2]=b [root@centos7: ~]#student[3]=c [root@centos7: ~]#student[age1]=age1 [root@centos7: ~]#student[age2]=age2 [root@centos7: ~]#student[age3]=age3 [root@centos7: ~]#student[gender1]=m [root@centos7: ~]#student[gender2]=f [root@centos7: ~]#student[gender3]=f [root@centos7: ~]#student[city1]=city1 [root@centos7: ~]#student[city2]=city2 [root@centos7: ~]#student[city3]=city3 [root@centos7: ~]#for i in {1..50};do echo student[city$i]=${student[city$i]} ;done student[city1]=city1 student[city2]=city2 student[city3]=city3 student[city4]= student[city5]=
num[6]=6 下標爲6,便是第七個元素的值爲6
[root@centos7: ~]#alpha=({a..z}) [root@centos7: ~]#echo ${alpha[@]} a b c d e f g h i j k l m n o p q r s t u v w x y z [root@centos7: ~]#echo ${alpha[@]:3:4} #跳過前三個取四個 d e f g [root@centos7: ~]#echo ${alpha[@]:3} #跳過三個取全部的 d e f g h i j k l m n o p q r s t u v w x y z [root@centos7: ~]#echo ${#alpha[@]} #多少個 26 [root@centos7: ~]#unset alpha[3] #切出來一個 [root@centos7: ~]#echo ${#alpha[@]} 就少了一個元素 25 [root@centos7: ~]#num=({0..5}) [root@centos7: ~]#num[6]=6 #給數組添加一個元素 [root@centos7: ~]#echo ${#num[@]} #如今元素的個數 7 [root@centos7: ~]#num[${#num[@]}]=7 #繼續給數組中添加元素,就是將數組的個數做爲數組的下標 [root@centos7: ~]#echo ${num[@]} 0 1 2 3 4 5 6 7
[root@centos7: ~]#echo ${str:3} de ================================================ #返回字符串變量var的長度 ${#var} [root@centos7: ~]#str=abcde [root@centos7: ~]#echo ${#str} 5 ================================================= #返回字符串變量var中從第offset個字符後(不包括第offset個字符)的字符開始,到最後的部分, offset的取值在0 到 ${#var}-1 之間(bash4.2後,容許爲負值) ${var:offset} ================================================ #返回字符串變量var中從第offset個字符後(不包括第offset個字符)的字符開始,長度爲number的部分 ${var:offset:number} [root@centos7: ~]#str=abcde [root@centos7: ~]#echo ${str:2:3} #從第二個開始,取三個 cde ==================================================== #取字符串的最右側幾個字符,取字符串的最右側幾個字符, 注意:冒號後必須有一空白字符 ${var: -length} [root@centos7: ~]#echo ${str: -2} #從後往前取2個 de ================================================== #從最左側跳過offset字符,一直向右取到距離最右側lengh個字符以前的內容,即:掐頭去尾 ${var:offset:-length} [root@centos7: ~]#str=abcdefg [root@centos7: ~]#echo ${str: 3 : -2 } #掐頭去尾 de ======================================= #先從最右側向左取到length個字符開始,再向右取到距離最右側offset個字符之間的內容,注意:- length前空格 ${var: -length:-offset} [root@centos7: ~]#str=abcdefg [root@centos7: ~]#echo ${str: -4: -1 } def [root@centos7: ~]#echo ${str: -4: -2 }倒數第四個和倒數第二個之間的內容 de #兩個都是負數,後面的負數要大於前面的數字
[root@centos8 ~]#file="var/log/messages" [root@centos8 ~]#echo ${file#*/}從左到右 log/messages [root@centos8 ~]#echo ${file##*/} 貪婪模式 messages
[root@centos8 ~]#file="var/log/messages" [root@centos8 ~]#echo ${file%/*} #從右往左找。找到/,將其後面的內容刪除 var/log [root@centos8 ~]#echo ${file%%/*} 貪婪模式 var
#把var中的全部小寫字母轉換爲大寫 ${var^^} #把var中的全部大寫字母轉換爲小寫 ${var,,}
[root@centos7: ~]#str=wang;var=${str-"haha"};echo var=$var var=wang [root@centos7: ~]#str=;var=${str-"haha"};echo var=$var var= [root@centos7: ~]#unset str;var=${str-"haha"};echo var=$var var=haha
declare [選項] 變量名 選項: -r 聲明或顯示只讀變量 -i 將變量定義爲整型數 -a 將變量定義爲數組 -A 將變量定義爲關聯數組 -f 顯示已定義的全部函數名及其內容 -F 僅顯示已定義的全部函數名 -x 聲明或顯示環境變量和函數,至關於export -l 聲明變量爲小寫字母 declare –l var=UPPER -u 聲明變量爲大寫字母 declare –u var=lower
eval命令將會首先掃描命令行進行全部的置換,而後再執行該命令。該命令適用於那些一次掃描沒法實
現其功能的變量,該命令對變量進行兩次掃描
[root@centos7: ~]#n=10 [root@centos7: ~]#for i in {1..$n};do echo i=$i ;done i={1..10} [root@centos7: ~]#for i in `eval echo {1..$n}`;do echo i=$i ;done i=1 i=2 i=3 i=4 i=5 i=6 i=7 i=8 i=9 i=10 [root@centos8 ~]#i=1 [root@centos8 ~]#j=a [root@centos8 ~]#$j$i=hello -bash: a1=hello: command not found [root@centos8 ~]#eval $j$i=hello [root@centos8 ~]#echo $j$i a1
若是第一個變量的值是第二個變量的名字,從第一個變量引用第二個變量的值就稱爲間接變量引用
variable1的值是variable2,而variable2又是變量名,variable2的值爲value,間接變量引用是指經過
variable1得到變量值value的行爲
[root@centos8 ~]#cat test.sh #!/bin/bash ceo=mage title=ceo declare -n ref=$title [ -R ref ] && echo reference echo $ref ceo=wang echo $ref [root@centos8 ~]#bash test.sh reference mage wang
[root@centos8 ~]#ceo=name [root@centos8 ~]#name=mage [root@centos8 ~]#echo $ceo name [root@centos8 ~]#echo $$ceo $$表示當前的進程的PID 33722ceo [root@centos8 ~]#echo $BASHPID 33722 [root@centos8 ~]#echo \$$ceo $name [root@centos8 ~]#eval tmp=\$$ceo [root@centos8 ~]#echo $tmp mage [root@centos8 ~]#echo ${!ceo} mage [root@server ~]# NAME=wangxiaochun [root@server ~]# N=NAME [root@server ~]# N1=${!N} [root@server ~]# echo $N1 wangxiaochun [root@server ~]# eval N2=\$$N [root@server ~]# echo $N2 wangxiaochun