1、人類如何與計算機"溝通"?
翻譯官:編譯器、解釋器;
編程語言:機器語言、彙編語言、高級語言
靜態語言:編譯型語言
強類型語言:變量在使用之前,需要聲明定義,甚至需要初始化
事先轉換成可執行格式
C、C++、Java、C#
動態語言:解釋型語言
弱類型語言:變量在使用之前,不需要聲明定義
邊解釋、邊執行
PHP、JSP、Perl、shell編程、Python
面向過程:shell、C
面向對象:C++、JAVA、Python、Perl
變量:就是命名的內存空間;
內存:就是編址的存儲單元;
爲什麼會有變量:想象一下,如果沒有變量這個概念的話,讓計算機做一個1到10000的加法,這需要10000個內存空間去存放,但如果引入了變量這個概念,則需要兩個變量即可。
變量類型的作用及功能:事先確定變量的存儲格式及長度。
整型,8bit: 256
0-255, 溢出
字符變量
數值變量:
整型
浮點型:11.23,1.123*10,0.1123*10^2
eg:字符型:2014/9/30 64bit
數值型:99999 24bit
布爾型:真、假
字符:10:16bit
數值:10: 1010, 8bit
shell編程:shell弱類型的編程語言
什麼是強?什麼是弱?
強類型:變量在使用前,需要聲明定義,甚至初始化
弱類型:變量在使用時才聲明,甚至不區分類型
變量賦值:VER_NAME=VALUE
bash變量:
本地變量(局部變量)
環境變量
位置變量
特殊變量
本地變量:
set VARNAME=VALUE: 作用域爲整個bash進程;
局部變量:
local VARNAME=VALUE:作用域爲當前代碼段;
環境變量:
export VARNAME=VALUE;
VARNAME=VALUE
export VARNAME
“導出”
位置變量:
$1,$2......
特殊變量:
$?(返回上一個命令的執行狀態碼),$*(參數列表),$@
程序的執行可以返回兩類結果:
1、程序的執行結果;
2、程序的執行狀態碼:0-255
0:正確執行
1-255:錯誤代碼
輸出重定向:
>:覆蓋輸出重定向
>>:追加輸出重定向
2>:錯誤覆蓋輸出重定向
2>>:錯誤追加重定向
&>:標準輸出+錯誤輸出重定向
撤銷變量:
unset VERNAME
查看變量:(環境變量+本地變量)
set
查看環境變量:
printenv
env
export
腳本:命令的堆砌,按實際需要,結合控制流程機制實現的源程序
shebang:魔數
#!/bin/bash
#註釋,不執行
/dev/null:軟件設備 ; 位桶(bit bucket) 數據黑洞
腳本在執行時,會啓動一個子shell進程:
在命令行運行的腳本,會繼承當前shell環境變量
系統自動運行的腳本(非命令行啓動),則需要自我定義各個環境變量
練習:寫一個腳本,完成以下任務
1、添加5個用戶, user1,..., user5
2、每個用戶的密碼同用戶名,而且要求,添加密碼完成後不顯示passwd命令的執行結果信息;
3、每個用戶添加完成後,都要顯示用戶某某已經成功添加;
useradd user1
echo "user1" | passwd --stdin user1 &> /dev/null
echo "Add user1 successfully."
條件判斷:
如果用戶不存在
添加用戶,給密碼並顯示添加成功;
否則
顯示如果已經沒在,沒有添加;
bash 中如何實現條件判斷:
條件測試的類型:
整數測試
文件測試
字符測試
條件測試的表達式:
[ expression ]
` expression `
test expression
整數比較:
-gt:大於
-lt:小於
-ge:大於等於
-le:小於等於
-eq:等於
-ne:不等於
命令間的邏輯關係:
&&:與,一假全假,當左邊爲假時,則不需要執行右邊,整個邏輯表達式即爲假
||:或,一真全真,當左邊爲真時,則不需要執行右邊,整個邏輯表達式即爲真
如果用戶user6不存在,就添加用戶user6
!id user6 && useradd user6
id user6 || useradd user6
如果/etc/inittab文件的行數大於100,就顯示好大的文件;
[ wc -l /etc/inittab | cut -d " " -f 1 -gt 100 ] && echo "Large file"
變量命名規則:
1、只能包含字母,數字,下劃線,並且不能以數字開頭。
2、不能與系統中已有的環境變量重名
3、最好能夠做到見名知意
如果用戶存在,就顯示用戶已存在;否則,就添加此用戶;
id user && echo "user exists" || adduser user
!id user || echo "user exists" && adduser user
如果用戶不存在,就添加;否則,顯示其已經存在;
!id user && useradd user || echo "user exists"
id user || useradd user && echo "user exists"
如果用戶不存在,添加並且給密碼;否則,顯示其已經存在;
!id user && useradd user && echo "user" | passwd --stdin user || echo "user exists"
練習,寫一個腳本,完成以下要求:
1、添加3個用戶user1, user2, user3;但要先判斷用戶是否存在,不存在而後再添加;
2、添加完成後,顯示一共添加了幾個用戶;當然,不能包括因爲事先存在而沒有添加的;
3、最後顯示當前系統上共有多少個用戶;
USERNUM1=`wc -l /etc/passwd | cut -d ' ' -f1`#用戶爲添加之前的事先存在的用戶數
id user1 && echo "user1 exists" || adduser user1
id user2 && echo "user2 exists" || adduser user2
id user3 && echo "user3 exists" || adduser user3
USERNUM2=`wc -l /etc/passwd | cut -d ' ' -f1`
echo "USERADDNUM=$[ $USERNUM2-&USERNUM1 ]"
echo "USERNUM2"
練習,寫一個腳本,完成以下要求:
給定一個用戶:
1、如果其UID爲0,就顯示此爲管理員;
2、否則,就顯示其爲普通用戶;
如果 UID爲0;那麼
顯示爲管理員
否則
顯示爲普通用戶
NAME=user16
USERID=`id -u $NAME`
if [ $USERID -eq 0 ]; then
echo "Admin"
else
echo "common user."
fi
NAME=user16
if [ `id -u $NAME` -eq 0 ]; then
echo "Admin"
else
echo "common user."
fi
if id $NAME; then
練習:寫一個腳本
判斷當前系統上是否有用戶的默認shell爲bash;
如果有,就顯示有多少個這類用戶;否則,就顯示沒有這類用戶;
grep "bash$" /etc/passwd &> /dev/null
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
if grep "bash$" /etc/passwd &> /dev/null; then
提示:“引用”一個命令的執行結果,要使用命令引用;
比如: RESAULTS=`wc -l /etc/passwd | cut -d: -f1`;
使用一個命令的執行狀態結果,要直接執行此命令,一定不能引用;
比如: if id user1一句中的id命令就一定不能加引號;
如果想把一個命令的執行結果賦值給某變量,要使用命令引用,比如USERID=`id -u user1`;
如果想把一個命令的執行狀態結果保存下來,並作爲命令執行成功與否的判斷條件,則需要先執行此命令,而後引用其狀態結果,如
id -u user1
RETVAL=$?
此句絕對不可以寫爲RETVAL=`id -u user1`;
練習:寫一個腳本
判斷當前系統上是否有用戶的默認shell爲bash;
如果有,就顯示其中一個的用戶名;否則,就顯示沒有這類用戶;
練習:寫一個腳本
給定一個文件,比如/etc/inittab
判斷這個文件中是否有空白行;
如果有,則顯示其空白行數;否則,顯示沒有空白行。
#!/bin/bash
A=`grep '^$' /etc/inittab | wc -l`
if [ $A -gt 0 ]; then
echo "$A"
else
echo "meiyoukongbaihang"
fi
#!/bin/bash
FILE=/etc/inittab
if [ ! -e $FILE ]; then
echo "No $FILE."
exit 8
fi
if grep "^$" $FILE &> /dev/null; then
echo "Total blank lines: `grep "^$" $FILE | wc -l`."
else
echo "No blank line."
fi
練習:寫一個腳本
給定一個用戶,判斷其UID與GID是否一樣
如果一樣,就顯示此用戶爲“good guy”;否則,就顯示此用戶爲“bad guy”。
#!/bin/bash
USERNAME=user1
USERID=`id -u $USERNAME`
GROUPID=`id -g $USERNAME`
if [ $USERID -eq $GROUPID ]; then
echo "Good guy."
else
echo "Bad guy."
fi
進一步要求:不使用id命令獲得其id號;
#!/bin/bash
#
USERNAME=user1
if ! grep "^$USERNAME\>" /etc/passwd &> /dev/null; then
echo "No such user: $USERNAME."
exit 1
fi
USERID=`grep "^$USERNAME\>" /etc/passwd | cut -d: -f3`
GROUPID=`grep "^$USERNAME\>" /etc/passwd | cut -d: -f4`
if [ $USERID -eq $GROUPID ]; then
echo "Good guy."
else
echo "Bad guy."
fi
練習:寫一個腳本
給定一個用戶,獲取其密碼警告期限;
而後判斷用戶密碼使用期限是否已經小於警告期限;
提示:計算方法,最長使用期限減去已經使用的天數即爲剩餘使用期限;
如果小於,則顯示“Warning”;否則,就顯示“OK”。
圓整:丟棄小數點後的所有內容
#!/bin/bash
W=`grep "student" /etc/shadow | cut -d: -f6`
S=`date +%s`
T=`expr $S/86400`
L=`grep "^student" /etc/shadow | cut -d: -f5`
N=`grep "^student" /etc/shadow | cut -d: -f3`
SY=$[$L-$[$T-$N]]
if [ $SY -lt $W ]; then
echo 'Warning'
else
echo 'OK'
fi
練習:寫一個腳本
判定命令歷史中歷史命令的總條目是否大於1000;如果大於,則顯示“Some command will gone.”;否則顯示“OK”。
shell中如何進行算術運算:
A=3
B=6
1、let 算術運算表達式
let C=$A+$B
2、$[算術運算表達式]
C=$[$A+$B]
3、$((算術運算表達式))
C=$(($A+$B))
4、expr 算術運算表達式,表達式中各操作數及運算符之間要有空格,而且要使用命令引用
C=`expr $A + $B`
條件判斷,控制結構:
單分支if語句
if 判斷條件; then
statement1
statement2
...
fi
雙分支的if語句:
if 判斷條件; then
statement1
statement2
...
else
statement3
statement4
...
fi
多分支的if語句:
if 判斷條件1; then
statement1
...
elif 判斷條件2; then
statement2
...
elif 判斷條件3; then
statement3
...
else
statement4
...
fi
測試方法:
[ expression ]
` expression `
test expression
bash中常用的條件測試有三種:
整數測試:
-gt
-le
-ne
-eq
-ge
-lt
INT1=63
INT2=77
[ $INT1 -eq $INI2 ]
[[ $INT1 -eq $INT2 ]]
test $INT1 -eq $INT2
文件測試:
-e FILE:測試文件是否存在
-f FILE: 測試文件是否爲普通文件
-d FILE: 測試指定路徑是否爲目錄
-r FILE: 測試當前用戶對指定文件是否有讀取權限;
-w
-x
[ -e /etc/inittab ]
[ -x /etc/rc.d/rc.sysinit ]
練習:寫一個腳本
給定一個文件:
如果是一個普通文件,就顯示之;
如果是一個目錄,亦顯示之;
否則,此爲無法識別之文件;
定義腳本退出狀態碼
exit: 退出腳本
exit #
如果腳本沒有明確定義退出狀態碼,那麼,最後執行的一條命令的退出碼即爲腳本的退出狀態碼;
測試腳本是否有語法錯誤:
bash -n 腳本
bash -x 腳本:單步執行
bash變量的類型:
本地變量(局部變量)
環境變量
位置變量:
$1, $2, ...
shift
特殊變量:
$?
$#:參數的個數
$*: 參數列表
$@:參數列表
./filetest.sh /etc/fstab /etc/inittab
$1: /etc/fstab
$2: /etc/inittab
練習:寫一腳本
能接受一個參數(文件路徑)
判定:此參數如果是一個存在的文件,就顯示“OK.”;否則就顯示"No such file."
練習:寫一個腳本
給腳本傳遞兩個參數(整數);
顯示此兩者之和,之乘積;
#!/bin/bash
#
if [ $# -lt 2 ]; then
echo "Usage: cacl.sh ARG1 ARG2"
exit 8
fi
echo "The sum is: $[$1+$2]."
echo "The prod is: $[$1*$2]."
練習:寫一個腳本,完成以下任務
1、使用一個變量保存一個用戶名;
2、刪除此變量中的用戶,且一併刪除其家目錄;
3、顯示“用戶刪除完成”類的信息;
bash:
引用變量:${VARNAME}, 括號有時可省略。