Shell:GUI CLI
提供互動式接口:提高效率
指令行展開:~ ,{}
指令别名:alias
指令曆史:history
Globbing:*,?,[],[^]
指令補全:$PATH指定的目錄下
路徑補全:TAB鍵
管道:|
輸入輸出重定向:> >>
提供程式設計環境:
bash自動運作腳本機制
面向過程(以指令為中心組織資料)的程式設計模型
腳本程式設計
輸入指令解決問題
程式是語句和表達式組成的
運作時根據一定流程來執行:
順序執行
選擇執行
循環執行
程式是指令+資料的
面向對象(以資料為中心來組織指令)
架構組織程式中的各個指令
程式運作模型:
編譯運作:
源程式——>預處理——>編譯——>彙編——>連結——>運作
# file /bin/cat
/bin/cat: ELF 64-bit LSB executable, x86-64, version 1 (SYSV),
dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped
# ldd /bin/cat 連結到的庫
linux-vdso.so.1 => (0x00007fff5c3ff000)
libc.so.6 => /lib64/libc.so.6 (0x00000035d0e00000)
/lib64/ld-linux-x86-64.so.2 (0x00000035d0600000)
解釋運作:
向核心提出運作要求時是解釋器運作成程序
源程式——>無需編譯——>解釋器——>核心根據檔案的格式來判定可執行(腳本的第一行要寫入shebang,如#!/bin/bash)——>讓bash程式來執行
變量:命名的記憶體空間
變量名:存放在記憶體中,由解釋器和記憶體自行維護
變量值:存放在記憶體中,由使用者來維護
資料類型:127:01111111 7bit存儲空間
127:1,2,7,是字串,要24位來存儲
ASCII碼:0-9,a-z,A-Z,punction
0-127 ,128種變化,要7位就能存儲
0000 0000 - 0111 1111
1.定義了資料存儲格式
2.定義了資料表示範圍
3.定義資料可以參與的運算類型
強類型程式設計語言:嚴格區分類型
弱類型程式設計語言:不嚴格區分類型
bash:把所有值都預設當作字元存儲
類型:
數值型:
精确數值型:整數
近似數值型:float(單精度浮點),double(雙精度浮點)
計算機裡面有專門的浮點單元來進行
浮點數的存儲格式?
字元型:
單個字元,字元串string
布爾型:
true,false
邏輯運算:
與:1&&1=1
1&&0=0
0&&1=0
0&&0=0
或:
1 || 1 =1
1 || 0 =1
0 || 1 =1
0 || 0 =0
非:
!1 =0
!0 =1
異或:
1 異或 1 =0
1 異或 0 =1
bash的變量類型:
本地變量:隻對目前shell程序有效,對目前之外的其他shell等shell都無效。
環境變量:對目前shell程序及其子shell程序有效,對其他shell無效。
局部變量:僅對目前shell程序中的某段代碼空間内有效,通常用于函數本地程式。
位置變量:$1 , $2 ,。。。
特殊變量:$?,$0 ,$$ ,$# ,$* , $@
$# 傳遞到腳本的參數個數
$* 傳遞到腳本的參數,與位置變量不同,此選項參數可超過9個
$$ 腳本運作時目前程序的ID号,常用作臨時變量的字尾,如 haison.$$
$! 背景運作的(&)最後一個程序的ID号
$@ 與$#相同,使用時加引号,并在引号中傳回參數個數
$- 上一個指令的最後一個參數
$? 最後指令的退出狀态,0表示沒有錯誤,其他任何值表明有錯誤
本地變量:隻是在使用者目前shell生存期的腳本中使用
無需事先聲明可直接使用
變量指派:# VAR_NAME=
變量引用:#echo "${VAR_NAME}"
[root@localhostretry]# a=1
[root@localhostretry]# echo "a=$a"
a=1
[root@localhostretry]# b='2'
[root@localhostretry]# echo "b=$b"
b=2
[root@localhostretry]# c="3"
[root@localhostretry]# echo "c=${c}"
c=3
[root@localhostretry]# a=1-$a
[root@localhostretry]# echo "a=$a"
a=1-1
[root@localhostretry]# b='2-$a'
[root@localhostretry]# echo "b=$b"
b=2-$a
[root@localhostretry]# c="3-$a"
[root@localhostretry]# echo "c=${c}"
c=3-1-1
#echo $username
#username=jerry
#echo $username
jerry
# echo '$username' 強引用,其中變量會被替換,所見所得
$username
# echo "$username" 弱引用,其中變量不會被替換
jerry
#set 顯示本地變量
#unset VAR_NAME 撤銷變量
#username=slackware
#useradd $username
#echo $username |passwd --stdin $username
Changingpassword for user slackware.
passwd:all authentication tokens updated successfully.
注意習慣:
1.數字不加引号,其他預設加雙引号
2.把指令作為變量:反引号
CMD=`ls`
3.${WEEK}day 若變量和其他字元組成新的變量就必須給變量加上大括号。
4.養成将所有字元串變量用雙引号括起來的使用習慣,将會減少很多程式設計中遇到的錯誤。如 "$A" 或 "${A}"
特殊例子:awk調用shell變量引号例子
[root@localhostretry]# NUM=123
[root@localhostretry]# awk 'BEGIN {print '$NUM'}'
123
[root@localhostretry]# awk 'BEGIN {print "$NUM"}'
$NUM
環境變量:
環境變量用于定義shell的運作環境,保證shell指令的正确執行,shell通過環境變量确定登入使用者名,指令路徑,終端類型,登入目錄等,所有的環境變量都是系統全局變量,可用于所有子程序。
無需事先聲明
$USER
$HOME
$UID
$SHELL
$PATH
變量指派:
#export VAR_NAME=VALUE
#declare -x VAR_NAME=VALUE
變量引用:${VAR_NAME}
注意:bash内建了許多環境變量
顯示環境變量
#export
#printenv
#env
#export username 導出為環境變量
#unset VAR_NAME 撤銷變量臨時生效
變量隻讀:
readonly VAR_NAME
declare -r VAR_NAME
退出目前shell程序可撤銷
變量命名規則:
1.不能使用程式中的關鍵字
2.隻能使用數字,字母或者下劃線,而且不能以數字開頭
3.見名知意:username,userName,_
自定義環境變量生成環境JAVA環境配置執行個體:tomcat,resin,csvn,hadoop
export JAVA_HOME=/application/jdk
export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH:$HOME/bin
export RESIN_HOME=/application/resin
常見放在: /etc/profile 或者 /etc/
位置變量:
#scirpt1.sharg1 arg2…
$0,$1…${10}
算術運算:
letVAR=expression
$[epression]
$((epression))
'expr arg1 arg2 arg3'
計算整數之和
#vi test.sh
#!/bin/bash
#author:test
declare -i sum=0
sum=$[$1+$2]
echo "the sum of $1 and $2:$[$1+$2]
echo "the minus of $1 and $2:$[$1-$2]
參數變量的輪替:
shift [n]
#vi test2.sh
#!/bin/bash
#author:test
#echo $1
shift
#echo $1
shift
#echo $1
shift
特殊變量:
$0:擷取目前執行的shell腳本的檔案名,包括路徑
#cat 14.sh
dirname $0
basename $0
#sh /root/14.sh
/root
14.sh
$n:擷取目前執行的shell腳本的第n個參數值,n=1..9,當n為0時表示腳本的檔案名,如果n大于9後,用大括号括起來${10}
#seq 7 |sed 's#[0-9]#$&#g'
#cat 13.sh
#!/bin/bash
echo$1 $2 $3 $4 $5 $6 $7 $8 $9 $10
#sh 13.sh 1 2 3
12 3 10
$#:擷取目前shell指令行參數的總個數
#cat 13.sh
#!/bin/bash
echo$1 $2 $3 $4 $5 $6 $7 $8 $9 $10
echo$#
#sh 13.sh 1 2 3 4 5
12 3 4 5 10
5
#sh 13.sh "1 2 3 45"
12 3 4 5 1 2 3 4 50
1
$@:這個程式的所有參數"$1" "$2" "$3" … ,這是将參數傳遞給其他程式的最佳方式,因為它會保留所有内嵌在每個參數裡面的任何空白。
$*:擷取目前shell的所有參數,将所有的指令行參數視為單個字元串,相當于"$!$2$3"…
echo 'total $#'
echo -e '$@\n'
echo -e '$*\n'
程序狀态變量:
$$:擷取目前shell的程序号PID
#!/bin/bash
echo$$ >/root/pid.log
whiletrue ; do
uptime &>/dev/null
sleep 2
done
#sh 15.sh &
[1]3158
#cat pid.log
3158
$!:擷取上一個指令的PID
$?:擷取執行的上一個指令的狀态碼(0為成功,非0失敗)
例如:編譯安裝程式時,make後查詢成功與否
make
echo $?
打包時也可以使用
$?傳回值參考:
0:表示運作成功
2:權限拒絕
1-125:表示運作識别,腳本指令,系統指令錯誤或參數傳遞錯誤
126:找到指令,但無法執行
127:未找到要運作的指令
>128:指令被系統強制結束
$_ :在此之前執行的指令或腳本的最後一個參數
練習:寫一個腳本,能接受一個參數,此參數用于使用者名
1.建立此使用者
2.給使用者添加密碼,密碼同使用者名
#!/bin/bash
#author:test
useradd$1
echo$1 |passwd --stdin $1
練習:寫一個腳本,能接受一個參數,此參數為系統上某文本檔案路徑
1.顯示此檔案的總行數
2.統計此檔案中的空白行數
#!/bin/bash
wc-l $1 |cut -d' ' -f1
grep'^[[:space:]]$' $1 |wc -l
$*和$@的差別:
$*:将所有指令行所有參數視為單個字元,等同于"$1$2$3"
$@:将指令行每個參數視為單獨的字元串,等同于"$!" "$2" $3" ,這是将參數傳遞給其他程式的最佳方式,因為它會保留所有内嵌在每個參數裡的任何空白。
[root@localhost ~]# set -- "how old " are you. 傳入3個參數
[root@localhost ~]# echo $# 現在有三個參數
3
[root@localhost ~]# for i in $* ; do echo $i ; done循環列印參數,用$*,
how
old
are
you.
[root@localhost ~]# for i in $@ ; do echo $i ; done沒有雙引号情況
how
old
are
you.
[root@localhost ~]# for i; do echo $i ; done 去掉in變量清單,相當于in"$@"
howold
are
you.
[root@localhost ~]# for i in "$@" ; doecho $i ; done 在有雙引号的情況下,參數裡引号内容當作一個參數輸出,這才真正符合我們傳入的參數需求。
howold
are
you.
.
擷取系統運作級别:
# runlevel=$(set -- $(runlevel);eval "echo \$$#" )
# echo $runlevel
3
1. eval command-line
其中command-line是在終端上鍵入的一條普通指令行。然而當在它前面放上eval時,其結果是shell在執行指令行之前掃描它兩次。如:
pipe="|"
evalls $pipe wc -l
shell第1次掃描指令行時,它替換出pipe的值|,接着eval使它再次掃描指令行,這時shell把|作為管道符号了。
如果變量中包含任何需要shell直接在指令行中看到的字元(不是替換的結果),就可以使用eval。指令行結束符(;| &),I/o重定向符(< >)和引号就屬于對shell具有特殊意義的符号,必須直接出現在指令行中。
2. eval echo \$$# 取得最後一個參數
如:cat last
evalecho \$$#
./lastone two three four
four
第一遍掃描後,shell把反斜杠去掉了。當shell再次掃描該行時,它替換了$4的值,并執行echo指令
3.以下示意如何用eval指令建立指向變量的“指針”:
x=100
ptrx=x
eval echo \$$ptrx 指向ptrx,用這裡的方法可以了解b中的例子
100 列印100
eval $ptrx=50 将50存到ptrx指向的變量中。