1. 程式人生 > 其它 >(一)shell程式設計

(一)shell程式設計

程式設計邏輯處理方式

順序執行:程式按從上到下順序執行
選擇執行:程式執行過程中,根據條件的不同,進行選擇不同分支繼續執行
迴圈執行:程式執行過程中需要重複執行多次某段語句

shell 指令碼基本結構

shell指令碼程式設計:是基於過程式、解釋執行的語言

程式語言的基本結構:

各種系統命令的組合

資料儲存:變數、陣列

表示式:a + b

控制語句:if

shell指令碼:包含一些命令或宣告,並符合一定格式的文字檔案

格式要求:首行shebang機制

#!/bin/bash
#!/usr/bin/python
#!/usr/bin/perl

shell指令碼建立過程

第一步:使用文字編輯器來建立文字檔案

第一行必須包括shell宣告序列:#!

示例:

#!/bin/bash

添加註釋,註釋以#開頭

第二步:加執行許可權

給予執行許可權,在命令列上指定指令碼的絕對或相對路徑

第三步:執行指令碼

直接執行直譯器,將指令碼作為直譯器程式的引數執行

shell 指令碼註釋規範

1、第一行一般為呼叫使用的語言
2、程式名,避免更改檔名為無法找到正確的檔案
3、版本號
4、更改後的時間
5、作者相關資訊
6、該程式的作用,及注意事項
7、最後是各版本的更新簡要說明

第一個 shell 指令碼

#!SHEBANG
CONFIGURATION_VARIABLES
FUNCTION_DEFINITIONS
MAIN_CODE
#執行方法1
[root@centos8 ~]# bash /data/hello.sh
#執行方法2
[root@centos8 ~]# cat /data/hello.sh | bash
#執行方法3
[root@centos8 ~]# bash < /data/hello.sh
#執行方法4
[root@centos8 ~]# chmod +x /data/hello.sh
#絕對路徑
[root@centos8 ~]#/data/hello.sh
#相法路徑
[root@centos8 ~]# cd /data/
[root@centos8 ~]#./hello.sh
#執行方法5,本方法可以實現執行遠端主機的shell指令碼
[root@centos8 ~]# yum -y install httpd
[root@centos8 ~]# systemctl start httpd
[root@centos8 ~]# mv /data/hello.sh /var/www/html/
[root@centos8 ~]# curl http://10.0.0.8/hello.sh

範例:執行遠端主機的指令碼

[root@centos8 ~]# curl http://10.0.0.8/hello.sh 2>/dev/null |bash
hello, world
Hello, world!
[root@centos8 ~]# curl http://10.0.0.8/hello.sh >/dev/null |bash
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 388 100 388 0 0 378k 0 --:--:-- --:--:-- --:--:-- 378k
[root@centos8 ~]# wget -qO - http://www.wangxiaochun.com/testdir/hello.sh | bash
hello, world
Hello, world!

備份指令碼

#!/bin/bash
# 
#********************************************************************
#Author:        xuanlv
#QQ:            xxxxxxxxxx
#Date:          2021-04-18
#FileName:     backup.sh
#URL:           https://www.cnblogs.com/xuanlv-0413/
#Description:      The test script
#Copyright (C):     2021 All rights reserved
#********************************************************************
echo -e "\033[1;32mStarting backup...\033[0m"
sleep 2
cp -av /etc/ /data/etc`date +%F`/
echo -e "\033[1;32mBackup is finished\033[0m"

shell 指令碼除錯

只檢測指令碼中的語法錯誤,但無法檢查出命令錯誤,但不真正執行指令碼

bash -n /path/to/some_script

除錯並執行

bash -x /path/to/some_script

範例:

root@long:~# cat -A test.sh 
#!/bin/bash$
#$
#********************************************************************$
#Author:^I^Ixuanlv$
#QQ: ^I^I^I3xxxxxx$
#Date: ^I^I^I2021-04-18$
#FileNameM-oM-<M-^Z^I^Itest.sh$
#URL: ^I^I^Ihttps://www.cnblogs.com/xuanlv-0413/$
#DescriptionM-oM-<M-^Z^I^IThe test script$
#Copyright (C): ^I2021 All rights reserved$
#********************************************************************$
echo line$
hostname$
cat > test.txt <<EOF $
aaa$
fadf$
ccc$
ddd$
EOF $
$
echo line233$
root@long:~# bash -n test.sh 
test.sh: line 21: warning: here-document at line 14 delimited by end-of-file (wanted `EOF')

總結:指令碼錯誤常見的有三種

語法錯誤,會導致後續的命令不繼續執行,可以用bash -n 檢查錯誤,提示的出錯行數不一定是準確的

命令錯誤,預設後續的命令還會繼續執行,用bash -n 無法檢查出來 ,可以使用 bash -x 進行觀察

邏輯錯誤:只能使用 bash -x 進行觀察

變數

變量表示命名的記憶體空間,將資料放在記憶體空間中,通過變數名引用,獲取資料

變數型別

內建變數,如:PS1,PATH,UID,HOSTNAME,$$,BASHPID,PPID,$?,HISTSIZE

使用者自定義變數
不同的變數存放的資料不同,決定了以下
資料儲存方式
參與的運算
表示的資料範圍
變數資料型別:
字元
數值:整型、浮點型,bash 不支援浮點數

程式語言分類

靜態和動態語言
靜態編譯語言:使用變數前,先宣告變數型別,之後型別不能改變,在編譯時檢查,如:java,c
動態編譯語言:不用事先宣告,可隨時改變型別,如:bash,Python
強型別和弱型別語言
強型別語言:不同型別資料操作,必須經過強制轉換才同一型別才能運算,如java , c# ,
python
如:參考以下 python 程式碼
print('magedu'+ 10) 提示出錯,不會自動轉換型別
print('magedu'+str(10)) 結果為magedu10,需要顯示轉換型別
弱型別語言:語言的執行時會隱式做資料型別轉換。無須指定型別,預設均為字元型;參與運算會
自動進行隱式型別轉換;變數無須事先定義可直接呼叫
如:bash ,php,javascript

Shell中變數命名法則

命名要求
區分大小寫
不能使程式中的保留字和內建變數:如:if, for
只能使用數字、字母及下劃線,且不能以數字開頭,注意:不支援短橫線 “ - ”,和主機名相反

命名習慣
見名知義,用英文單詞命名,並體現出實際作用,不要用簡寫,如:ATM
變數名大寫
區域性變數小寫
函式名小寫
大駝峰StudentFirstName
小駝峰studentFirstName
下劃線: student_name

變數定義和引用
變數的生效範圍等標準劃分變數型別
普通變數:生效範圍為當前shell程序;對當前shell之外的其它shell程序,包括當前shell的子shell程序均無效
環境變數:生效範圍為當前shell程序及其子程序
本地變數:生效範圍為當前shell程序中某程式碼片斷,通常指函式

變數賦值:

name='value'

value 可以是以下多種形式

直接字串:name='root'
變數引用:name="$USER"
命令引用:name=`COMMAND` 或者 name=$(COMMAND)

注意:變數賦值是臨時生效,當退出終端後,變數會自動刪除,無法持久儲存,指令碼中的變數會隨著指令碼結束,也會自動刪除

變數引用

$name
${name}

弱引用和強引用

"$name " 弱引用,其中的變數引用會被替換為變數值
'$name ' 強引用,其中的變數引用不會被替換為變數值,而保持原字串

範例:變數的各種賦值方式和引用

root@long:~# TITLE='cto'
root@long:~# echo $TITLE 
cto
root@long:~# echo I am $TITLE 
I am cto
root@long:~# echo "I am $TITLE"
I am cto
root@long:~# echo 'I am $TITLE'
I am $TITLE
root@long:~# 
root@long:~# NAME=$USER
root@long:~# echo $NAME 
root
root@long:~# USER=`whoami`
root@long:~# echo $USER 
root
root@long:~# FILE=`ls /home`
root@long:~# echo $FILE 
long
root@long:~# 
root@long:~# FILE=/etc/*
root@long:~# echo $FILE 
/etc/acpi /etc/adduser.conf /etc/alternatives /etc/apm /etc/apparmor /etc/apparmor.d /etc/apport /etc/apt /etc/at.deny /etc/bash.bashrc /etc/bash_completion /etc/bash_completion.d /etc/bindresvport.blacklist /etc/binfmt.d /etc/byobu /etc/ca-certificates

root@long:~# seq 10
1
2
3
4
5
6
7
8
9
10
root@long:~# NUM=`seq 10`
root@long:~# echo $NUM 
1 2 3 4 5 6 7 8 9 1
root@long:~# echo "$NUM"
1
2
3
4
5
6
7
8
9
10
root@long:~# NAMES="long
> wang
> zhi
> shi"
root@long:~# echo $NAMES
long wang zhi shi
root@long:~# echo "$NAMES"
long
wang
zhi
shi

範例:變數引用

root@long:~# NAME=long
root@long:~# AGE=20
root@long:~# echo $NAME
long
root@long:~# echo $AGE 
20
root@long:~# echo $NAME $AGE 
long 20
root@long:~# echo $NAME$AGE 
long20
root@long:~# echo $NAME_$AGE 
20
root@long:~# echo ${NAME}_$AGE 
long_20

範例:變數的間接賦值和引用

root@long:~# TITLE=cto
root@long:~# NAME=long
root@long:~# TITLE=$NAME
root@long:~# echo $NAME
long
root@long:~# echo $TITLE 
long
root@long:~# NAME=wang
root@long:~# echo $NAME
wang
root@long:~# echo $TITLE 
long

範例:變數追加值

root@long:~# TITLE=cto
root@long:~# TITLE+=:long
root@long:~# echo $TITLE 
cto:long

範例:利用變數實現動態命令

root@BJ-long:~# CMD=hostname
root@BJ-long:~# $CMD
BJ-long.longUbuntu.local

顯示已定義的所有變數:

set

刪除變數:

unset <name>

範例:

root@BJ-long:~# vim backup2.sh 

#!/bin/bash
# 
#********************************************************************
#Author:        xuanlv
#QQ:            xxxxxxx
#Date:          2021-04-18
#FileName:     backup2.sh
#URL:           https://www.cnblogs.com/xuanlv-0413/
#Description:      The test script
#Copyright (C):     2021 All rights reserved
#********************************************************************
COLOR='echo -e \E[1;35'
END='\E[0m'
BACKUP=/backup
SRC=/etc
DATE=`data +%F`

${COLOR}Starting backup...$END
sleep 2
cp -av $SRC ${BACKUP}${SRC}_$DATE
${COLOR}Backup is finished$END