1. 程式人生 > >1、shell編程(shell腳本)_理解編程和變量

1、shell編程(shell腳本)_理解編程和變量

Shell 編程 變量

在study(Shell)專欄中,會深刻學習到shell編程

而作為一個運維人,最基本的能力,也是要學會shell腳本編程
為我們的工作中提高效率!
shell編程:
編譯器:也叫解釋器
shell給我們提供另外一個功能:方便我們的工作!

編程語言:將人類的語言轉變成機器可以理解的語言
機器語言(01代碼)
匯編語言(依然很低層,成長周期比較長,學習起來也比較困難)
高級語言(盡管如此,它也不是人類的語言,但是最接近人類的語言)
靜態和動態語言

1、靜態語言:編譯型語言
(有程序開發環境,不需要借助額外的二進制程序,直接寫代碼,寫完之後需要一個編譯器,將代碼放到編譯器就可以交給硬件形成一個獨立運行的程序,我們就把他叫做靜態語言)

事先轉換成可執行的格式;比如說java,c++
靜態語言所需要的重要的一個特征:強類型(變量)
關鍵字:
執行之前就要完全轉換,事先轉換成可以執行的格式程序。
比如java的剛開始是一個.java文件(也就是源代碼),編譯成可執行文件即為.class文件(就是編譯後的文件,就不是源碼了)

2、動態語言:解釋型語言on the fly
(一個代碼我們程序員寫完以後,他不需要轉換成二進制格式,而是有一個解釋器,解釋一條,執行一條,也就是在執行以後在進行轉換)
(通常)弱類型:邊解釋邊執行
像PHP,SHELL,Python(非常流行的,面向對象的,很多遊戲腳本都是用python),perl(早前流行的:讀音:po(破))

像C,C++,JAVA,C#(不需要任何解釋器,自我就能運行)

bash:最易學,最容易上手的就是SHELL
如果能學好python就是如虎添翼,添加了很多翼。
perl面向過程的,雖然perl6加上了對象,但是現在由於各種原因也流行不起來
事實上很多腳本是python研發的,在學習學了多年的計算機,都沒有學過python,所以學校學的是脫節的

面向過程:相對開發小型的應用程序:shell,c
把編程著眼點主要在於問題解決的過程本身
面向對象:相對開發大型的應用程序:JAVA(純面向對象語言),Python(純面向對象語言),perl,c++
面向對象的含義:把整個我們要實現的項目抽象一個個對象,並定義對象之間的動作,就是可發出的操作來完成的,所以這個更適合開發大型程序

不過任何工具都是雙刃劍(菜刀可以殺人也可以切菜)

要想理解編程,必須要理解變量
變量(不斷變化的量):是內存空間,命名的內容空間(就是不斷變化的量,存儲在某一個內存的存儲空間,根據地址就可以找到這個)
內存是存址的存儲單元
我們通過變量和內存地址相對應,所以我們看到的是變量,比如a,其實它對應的是一個內存的地址空間。

實例:
10:字符存儲的話,需要16位bit
10:存儲為數值的話,就是1010,就只需要4位就足夠了,當然計算機最小的存儲是字節,所以這裏也是需要8位的。
通過上述就知道,我們的變量需要有類型的

1、字符類型
2、數值類型,而數值類型又分:
1、整型
2、浮點型:11.23(存儲舉例:小數點之前存一個地方,小數點後面存在一個地方,小數點存在一個位置),就可能存儲到這種格式1.12310^1,0.112310^2(可能只存1123和2)
如果我們要存儲年份的話,比如:2013/10/10和99999,存儲的格式和大小都不一樣的
所以我們確定變量的類型:就是事先確定數據的存儲格式和長度
內存:編址的存儲單元

什麽是溢出?
如下實例
·整型,8bit:256
·0-255,滿了,流出去了,溢出
如果溢出的數據占據別人進程的空間了,就把其他的覆蓋掉了,而如果這種精心設計的緩沖區溢出,一些攻擊就是利用這種溢出的。
簡單防止溢出的:看給的數據和我的程序變量類型是否合適,不合適就返回錯誤,不讓其寫入。因此說變量是需要類型的。
所以好的代碼還會去檢查變量,檢查異常(舉例:印度的外包業要比中國的要強很多就是這個原因)

布爾類型:真假
邏輯: 1+1>2
邏輯運算:與、或、非、異或(操作數相同為假,操作數不同為真)
!真=假
!假=真
其實我們計算機的電邏輯就是這樣的
其實我們整個數字電路的電路就是這種運算,我們還可以自己設計加法器
在這種基礎上不斷的加,變成一個復雜的功能。
對於與來講,只要有一個為假,結果一定為假
對於或來講,只要有一個為真,結果一定為真

下圖是一個電磁感應的原理(這就是計算機專業名稱說的:非門)
技術分享圖片

整個計算機就是一大堆的這種門來運算的

強類型編程:
變量在使用前,必須事先聲明,甚至還需要初始化值的:
NULL:
弱類型編程:
變量用時才聲明(拿來直接用就行了),甚至不區分類型(如果不區分類型,默認為字符串):
我們的shell編程是弱類型的編程語言

變量賦值VAR_NAME=VALUE(把這個值保存在變量空間裏面去了)如:ShenGao=175

編程能力:
bash腳本編程
bash變量類型:
環境變量
本地變量(局部變量(局部變量不一定都是本地變量))
位置變量
特殊變量(bash內置的,用來保存bash特殊數據的,也有人把他稱作系統變量)

本地變量:(變量一定是進程的變量)
[root@www ~]# NAME=jerry
[root@www ~]# echo $NAME
jerry
我們引用變量用:${VARNAME} (通常{}可以省略),如上
但是有時候會引起變量混淆的,我們就要加上花括號,如下
[root@www ~]# echo $NAME
jerry
[root@www ~]# echo "my name is $NAME"
my name is jerry
[root@www ~]# echo "my name is $NAMEs"
my name is
[root@www ~]# echo "my name is ${NAME}s"
my name is jerrys
[root@www ~]# echo "my name is ${NAME}:s+w"
my name is tom:s+w 可以看出有一些字符是不會被識別的,比如:,+...
子bash:在一個shell中再打開一個shell

變量的學習以及變量的類型
本地變量:
VARNAME=VALUE:作用域為整個bash進程:
局部變量:
local VARNAME=VALUE:作用域為當前代碼段
export定義一個環境變量,環境的作用域如下(export意為:“導出”)
技術分享圖片

VARNAME=VALUE
export VARNAME
技術分享圖片

技術分享圖片

當然,環境變量如果重新打開一個shell,就會沒有作用;但是子shell是有作用的

位置變量(是用來引用腳本的參數的):
$1,$2,...
比如下面的例子
#!/bin/bash
let sum=$[$1+$2]
echo -e "the sum is $sum"
然後輸出結果就可以這樣
[root@zabbix ~]# ./myshell.sh 15 96
the sum is 111
[root@zabbix ~]# ./myshell.sh 5 9
the sum is 14

特殊變量:
$?:上一個命令的執行狀態的返回值,我們看到的輸出是執行結果,那問如果是正確還是錯誤的話,就是狀態結果,也叫做狀態返回值
程序執行,可能有兩類返回值,一種是正確的,一種是錯誤的
$?:上一個命令的執行狀態返回值:如果不是0(執行狀態返回代碼),就是執行狀態是錯誤的,如果是1-255就是錯誤的,不是正確的執行狀態。
1-255中系統預留的有三個1,2,127,其他的可以自己定義的
[root@www ~]# ifconfig &> /dev/null
[root@www ~]# echo $?
0
&>錯誤還是正確都輸出到/dev/null(軟件模擬的設備,也叫做bit bucket(數據黑洞)放什麽進去都會消失)下去,而/dev/null就是垃圾站一樣,什麽都可以接收,我們用上面的命令,就是為了查證上一個命令是否正確輸出,echo $?,這樣放進去null就不用顯示屏幕了。
技術分享圖片

變量用完以後,就沒用了,我們就還可以撤銷變量
本來我們定義變量是有一個set的,但是其實它默認就有了,所以我們沒有用set,而撤銷的話就是用unset VARNAME
技術分享圖片

set
查看shell中的所有變量就直接用set就可以了,,這裏包括了所有變量(包括環境變量)
如果只查看環境變量用printenv或者env或者export
用:在環境變量基礎上可以再加東西(是不會識別成變量名的,所以不需要{})

技術分享圖片

技術分享圖片

跟window差不多,用:隔開去添加一個新的變量
記住:這個符號——變量默認不能做算術運算的

什麽是腳本?

如何去寫腳本:其實就是命令的堆砌,是按照實際需要,結合命令流程控制機制實現的源程序的腳本。
Linux只能識別ELF格式去執行的(也就是腳本的第一行必須是#!/bin/bash,bash是解釋器,/bin/bash 是解釋器路徑),這樣才能然一個ASCII格式的文本可以被執行
我們的文件幾乎都是是ACISS格式的
所以我們想運行腳本文件,必須是在文件的第一行用
#!/bin/bash (而後再出現的#就是註釋的#(也就是當做有效的組成部分))
所以一執行這個文件,就會讀到第一行,就會用bash的編輯器去運行
並且要知道shell腳本的文件要用.sh後綴,就像是本地倉庫要用.repo一樣
如下的一個shell腳本,用來進入網絡配置文件
[root@www tmp]# vim 1.sh
#!/bin/bash
cd /etc/sysconfig/network-scripts/
vim ifcfg-eno16777736
[root@www tmp]# ./1.sh ./表示運行當前目錄腳本
如果沒有x執行權限,而是作為別人的參數來進行的,就不用執行權限
可以直接 bash 1.sh(而且這一種方式,開頭也不需要#!/bin/bash去調用編譯器,因為已經是通過bash這個程序去執行了

練習
技術分享圖片

useradd user001
useradd user002
echo "112233" | passwd --stdin user001 &> /dev/null
echo "112233" | passwd --stdin user002 &> /dev/null
echo user001 passwd shezhi successful
echo user002 passwd shezhi successful

Chinaname=user001 (不能在腳本中用set Chinaname=user001,測試發現不成功)
userdel -r $Chinaname
echo "the user already delete"

1、shell編程(shell腳本)_理解編程和變量