一些基礎腳本知識

編程基礎:
程序:指令+數據
程序編程風格:
過程式:以指令爲中心,數據服務於指令。 小軟件過程,大軟件對象。
對象式:以數據爲中心,指令服務於數據
shell程序:提供了編程能力,解釋執行
shell腳本基礎:
shell腳本:
包含一些命令或聲明,並符合必定格式的文本文件
格式要求:首行shebang機制
#!/bin/bash
#!/usr/bin/python
#!/usr/bin/perl

shell腳本的用途有:
自動化經常使用命令
執行系統化管理和故障排除
建立簡單的應用程序
處理文本或文件
建立shell腳本
第一步:使用文本編輯器來建立文本文件
第一行必須包括shell聲明序列:#!
 #!/bin/bash
 添加註釋
 註釋以#開頭
第二步:運行腳本
給予執行權限,在命令行上指定腳本的絕對或相對路徑
直接運行解釋器,將腳本做爲解釋器程序的參數運行

腳本規範:
腳本代碼開頭約定:
一、第一行通常爲調用使用的語言
二、程序名,避免更改文件名爲沒法找到正確的文件
三、版本號
四、更改後的時間
五、做者相關信息
六、該程序的做用,及注意事項
七、最後是各版本的更新簡要說明

腳本的基本結構:
腳本的基本結構
#!SHEBANG
CONFIGURATON_VARIABLES
FUNCTION_DEFINITIONS
MAIN_CODE

shell腳本示例
#!/bin/bash
# ------------------------------------------
# Filename: hello.sh
# Revision: 1.1
# Date: 2017/06/01
# Author: wang
# Email: wang@gmail.com
# Website: www.magedu.com
# Description: This is the first script
# ------------------------------------------
# Copyright: 2017 wang
# License: GPL
echo 「hello world」
腳本調試
檢測腳本中的語法錯誤
bash -n /path/to/some_script
調試執行
bash -x /path/to/some_script
bash -n 只能檢查語法錯誤
變量
變量:命名的內存空間
 數據存儲方式:
字符:
數值:×××,浮點型
變量:變量類型
    做用:
一、數據存儲格式
二、參與的運算 
三、表示的數據範圍
類型: 
字符
數值:×××、浮點型
加" "能夠改變格式 如: echo="name"
變量:
強類型:變量不通過強制轉換,它永遠是這個數據類型,不容許隱式的類型轉
換。通常定義變量時必須制動類型、參與運算必須符合類型要求;調用未聲明
變量會產生錯誤
如 java,c#
弱類型:語言的運行時回隱形作數據類型轉換。無須指定類型,默認均爲字符型;
參與運算會自動進行隱式類型轉換;變量無需事先定義可直接調用
如:bash不支持浮點數,php  能夠用數字可是不能放在前面
變量命名法則:
一、不能使程序中的保留字:列如if,for
二、只能使用數字、字母及下劃線,且不能以數字開頭
三、見名知義
四、統一命名法則:駱峯命名法:把多個首字母大寫,小駝峯:第一個首字母大寫,
bash中變量的種類:
根據變量的生效範圍等標準劃分下面變量類型:
局部變量:生效範圍爲當前shell進程;對當前shell以外的其餘shell進程,包括
當前shell的子shell進程均無效
環境變量:生效範圍爲當前shell進程及其子進程
本地變量:生效範圍爲當前shell進程中某代碼片斷,一般指函數
位置變量:$1,$2,...來表示,用於讓腳本在腳本代碼中調用經過命令行傳遞給它
的參數
特殊變量:$>,$0,$@,$#,$$
局部變量:
echo $$ 

echo $PPID:父子進程

局部變量只能在當前shell有效

在下級子進程變量不能往上傳別的進程

全局變量:使用要加關鍵字 export :把當前變量轉換環境變量
它容許往下傳   父進程能夠傳給子進程   
bash 後臺執行

declare -x 也能夠生成全部環境變量

env也能顯示環境變量

unset name 刪除當前環境變量

set :本劇變量 全局變量都有

常量:固定值

readonly -p:顯示常量

():用於一次性任務 執行一個小subsheell 不影響環境,
{}:和小括號有區別 

位置變量:能讓腳本寫死

$1 $2 $3
1 存的就是第一個字符串

10 個以上就得用{}
如:e'cho "ALL args are {$10}"

scp :能夠遠程複製

scp.sh 

shift:從右往左擠掉

ping -c:指定網絡拼一次
總結:
shell

變量:局部和環境    $1,$@ $*,$#,$0
set unset exprot declare -i -r -x env

環境變量:
變量聲明、賦值:
export name=VALUE
declare -x name=VALUE
變量引用:$name,${name}
顯示全部環境變量:
env
printenv
export
declare -x
刪除變量:
unset name
環境變量:
bash內建的環境變量:
PATH
SHELL
UID
USER
HOME
PWD
SHLVL
LANG
MAIL
HOSTNAME
HISTSIZE
—:下劃線

只讀和位置變量:
只讀變量:只能聲明,但不能修改和刪除
聲明只讀變量:
readonly name
declare -r name
查看只讀變量:
readonly -p
位置變量:在腳本代碼中調用命令行傳遞給腳本的參數
$1,$2,...:對應第1,第2等參數,shift [n]換位置
$0:命令自己
$*;傳遞給腳本的全部參數,所有參數合爲一個字符串
$@:傳遞給腳本的全部參數,每一個參數爲獨立字符串
$#:傳遞給腳本的參數的個數
$@$*只在被雙引號抱起來的時候纔會有差別
set -- 清空全部位置變量
退出狀態:
進程使用退出狀態來報告成功或失敗
0表明成功,1 - 255表明失敗
$?:變量保存最近的命令退出狀態
列如:
ping -c1 -w1 hostdown &>/dev/null
echo$?

退出狀態碼:
bash自定義退出狀態碼
exit[n]:自定義退出狀態碼
注意:腳本中一旦遇到exit命令,腳本會當即終止;終止退出狀態取決於exit命
令後面的數字
注意:若是未給腳本指定退出狀態碼,整個腳本的退出狀態碼取決於腳本中執行
的最後一條命令的狀態碼

算數運算:
bash中的算數運算:help let
+,-,*,%取模(取餘),**(乘方)
實現算數運算:
一、let var=算數表達式
二、var=$[算數表達式]
三、var=$((算數表達式))
四、var=$(expr arg1 arg2 arg3...)
五、declare -i var =數值
六、echo  '算數表達式'   | bc
乘法符號有些場景中須要轉義,如*
bash有內建的隨機數生成器:$RANDOM(0-32767)
echo $[$RANDOM%50】 :0-49之間隨機數
賦值:
加強型賦值:
+=,-=,*=,/=,%=
let varOPERvare
列如:let count+=3
自加3後減值
自增,自減:
let var+=1
let var++
let var-=1
let var--
邏輯運算;
true,false
1,0
與:
1與1=1          & 而且 and
1與0=0          | 或者 or
0與1=0           cmd1 && cmd2     若是cmd1爲假,cmd2不須要執行,反之cmd1爲真,須要cmd2執行
0與0=0           cmd1 || cmd2若是爲真,cmd2不須要執行,反之cmd1爲假,須要cmd2執行
或:                  XOR 異或
1或1=1         0^1=1
1或0=1         0^0=0
0或1=1         1^0=1
0或0=0         1^1=0

邏輯運算:
非:!
!1=0
!0=1
短路運算:
短路與
第一個爲0,結果一定爲0
第一個爲1,第二個必需要參與運算
短路或
第一個爲1,結果一定爲1
第一個爲0,第二個必需要參與運算
異或:^
異或的兩個值,相同爲假,沒必要爲真
條件測試;
判斷某需求是否知足,須要由測試機制來實現
專用的測試表達式須要由測試命令輔助完成測試過程
評估布爾聲明,以便用條件執行中
若真,澤返回0
若假,則返回1
測試命令:
testEXPRESSION
[ EXPRESSION]
[[ EXPRESSION]]
注意:EXPRESSUON先後必須有空白字符

條件性的執行操做符:
根據退出狀態而定,命令能夠有條件地運行
&&表明條件行的AN THEN
|| 表明條件行的OR ELSE
 例如:
grep -q no_such_user /etc/passwd \
|| echo 'No such user'
No such user
ping -c1 -W2 station1 &> /dev/null \
> && echo "station1 is up" \
> || (echo 'station1 is unreachable'; exit 1)
station1 is up

test命令
 長格式的例子:
test "$A" == "$B" && echo "Strings are equal"
test 「$A」 -eq 「$B」 && echo "Integers are equal"
 簡寫格式的例子:
[ "$A" == "$B" ] && echo "Strings are equal"
[ "$A" -eq "$B" ] && echo "Integers are equal"

bash的數值測試
-v VAR
變量VAR是否設置
數值測試:
-gt  是否大於
-ge  是否大於等於
-eq  是否等於
-ne  是否不等於
-lt  是否小於
-le  是否小於等於

bash的字符串測試
字符串測試:
==  是否等於
>  ascii碼是否大於ascii碼
<  是否小於
!=  是否不等於
=~  左側字符串是否可以被右側的PATTERN所匹配
注意: 此表達式通常用於[[ ]]中;擴展的正則表達式
-z "STRING「  字符串是否爲空,空爲真,不空爲假
-n "STRING「  字符串是否不空,不空爲真,空爲假
 注意:用於字符串比較時的用到的操做數都應該使用引號
Bash的文件測試
存在性測試
-a FILE:同-e
-e FILE: 文件存在性測試,存在爲真,不然爲假
存在性及類別測試
-b FILE:是否存在且爲塊設備文件
-c FILE:是否存在且爲字符設備文件
-d FILE:是否存在且爲目錄文件
-f FILE:是否存在且爲普通文件
-h FILE 或 -L FILE:存在且爲符號連接文件
-p FILE:是否存在且爲命名管道文件
-S FILE:是否存在且爲套接字文件

Bash的文件權限測試
文件權限測試:
-r FILE:是否存在且可讀
-w FILE: 是否存在且可寫
-x FILE: 是否存在且可執行
文件特殊權限測試:
-u FILE:是否存在且擁有suid權限
-g FILE:是否存在且擁有sgid權限
-k FILE:是否存在且擁有sticky權限

Bash的文件屬性測試
文件大小測試:
-s FILE: 是否存在且非空
文件是否打開:
-t fd: fd 文件描述符是否在某終端已經打開
-N FILE:文件自從上一次被讀取以後是否被修改過
-O FILE:當前有效用戶是否爲文件屬主
-G FILE:當前有效用戶是否爲文件屬組

Bash的文件屬性測試
雙目測試:
FILE1 -ef FILE2: FILE1是不是FILE2的硬連接
FILE1 -nt FILE2: FILE1是否新於FILE2(mtime)
FILE1 -ot FILE2: FILE1是否舊於FILE2

Bash的組合測試條件
第一種方式:
COMMAND1 && COMMAND2 而且
COMMAND1 || COMMAND2 或者
! COMMAND 非
如:[[ -r FILE ]] && [[ -w FILE ]]
第二種方式:
EXPRESSION1 -a EXPRESSION2 而且
EXPRESSION1 -o EXPRESSION2 或者
! EXPRESSION
必須使用測試命令進行
示例:
[ -z 「$HOSTNAME」 -o $HOSTNAME "==\
"localhost.localdomain" ] && hostname www.magedu.com
[ -f /bin/cat -a -x /bin/cat ] && cat /etc/fstab

使用read命令來接受輸入
使用read來把輸入值分配給一個或多個shell變量
-p 指定要顯示的提示
-s 靜默輸入,通常用於密碼
-n N 指定輸入的字符長度N
-d  ‘字符’ 輸入結束符
-t N TIMEOUT爲N秒
read 從標準輸入中讀取值,給每一個單詞分配一個變量
全部剩餘單詞都被分配給最後一個變量
read -p 「Enter a filename: 「 FILE

bash如何展開命令行
把命令行分紅單個命令詞
展開別名
展開大括號的聲明({})
展開波浪符聲明(~)
命令替換$() 和 ``)
再次把命令行分紅命令詞
展開文件通配(*、?、[abc]等等)
準備I/0重導向(<、>)
運行命令

防止擴展
反斜線(\)會使隨後的字符按原意解釋
$ echo Your cost: \$5.00
Your cost: $5.00
加引號來防止擴展
• 單引號(’)防止全部擴展
• 雙引號(」)也防止全部擴展,可是如下狀況例外:
$(美圓符號) - 變量擴展
`(反引號) - 命令替換
\(反斜線) - 禁止單個字符擴展
!(歎號) - 歷史命令替換

bash的配置文件
按生效範圍劃分,存在兩類:
全局配置:
/etc/profile
/etc/profile.d/*.sh
/etc/bashrc
我的配置:
~/.bash_profile
~/.bashrc
bashrc bash run command 
source 這種寫法在當前腳本中運行
通常配置文件用source
變量普通腳本是不能支持別名的
10:16

shell登陸兩種方式
交互式登陸:
(1)直接經過終端輸入帳號密碼登陸
(2)使用「su - UserName」 切換的用戶
執行順序:/etc/profile --> /etc/profile.d/*.sh --> ~/.bash_profile -->
~/.bashrc --> /etc/bashrc
非交互式登陸:
(1)su UserName
(2)圖形界面下打開的終端
(3)執行腳本
(4)任何其它的bash實例
執行順序: ~/.bashrc --> /etc/bashrc --> /etc/profile.d/*.sh

Profile類
按功能劃分,存在兩類:
profile類和bashrc類
profile類:爲交互式登陸的shell提供配置
全局:/etc/profile, /etc/profile.d/*.sh
我的:~/.bash_profile
功用:
(1) 用於定義環境變量
(2) 運行命令或腳本

Bashrc類
bashrc類:爲非交互式和交互式登陸的shell提供配置
全局:/etc/bashrc
我的:~/.bashrc
功用:
(1) 定義命令別名和函數
(2) 定義本地變量

編輯配置文件生效
修改profile和bashrc文件後需生效
兩種方法:
1從新啓動shell進程
2 . 或source
例:
. ~/.bashrc

Bash 退出任務
保存在~/.bash_logout文件中(用戶)
在退出登陸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 個歷史命令

read x y z  <<<  "i j k"
echo $.

9:42
   49
11:34

如何判斷命令是否存在?
which mkisofs >& /dev/null
if  [ "$?"  != 0 ] ;  then
     echo "mkisofs Not Found"
     echo "yum install mkisofs"
fi

判斷文件是否存在?
if  [ -f $2 ]; then
     echo "....."
     exit 1
fi

test(選項)
選項
-b<文件>:若是文件爲一個塊特殊文件,則爲真;
-c<文件>:若是文件爲一個字符特殊文件,則爲真;
-d<文件>:若是文件爲一個目錄,則爲真;
-e<文件>:若是文件存在,則爲真;
-f<文件>:若是文件爲一個普通文件,則爲真;
-g<文件>:若是設置了文件的SGID位,則爲真;
-G<文件>:若是文件存在且歸該組全部,則爲真;
-k<文件>:若是設置了文件的粘着位,則爲真;
-O<文件>:若是文件存在而且歸該用戶全部,則爲真;
-p<文件>:若是文件爲一個命名管道,則爲真;
-r<文件>:若是文件可讀,則爲真;
-s<文件>:若是文件的長度不爲零,則爲真;
-S<文件>:若是文件爲一個套接字特殊文件,則爲真;
-u<文件>:若是設置了文件的SUID位,則爲真;
-w<文件>:若是文件可寫,則爲真;
-x<文件>:若是文件可執行,則爲真。
實例
linux中shell編程中的test常見用法:

判斷表達式

if test     #表達式爲真
if test !   #表達式爲假
test 表達式1 –a 表達式2     #兩個表達式都爲真
test 表達式1 –o 表達式2     #兩個表達式有一個爲真
test 表達式1 ! 表達式2       #條件求反
判斷字符串

test –n 字符串    #字符串的長度非零
test –z 字符串    #字符串的長度是否爲零
test 字符串1=字符串2       #字符串是否相等,若相等返回true
test 字符串1!=字符串2      #字符串是否不等,若不等反悔false
判斷整數

test 整數1 -eq 整數2    #整數相等
test 整數1 -ge 整數2    #整數1大於等於整數2
test 整數1 -gt 整數2    #整數1大於整數2
test 整數1 -le 整數2    #整數1小於等於整數2
test 整數1 -lt 整數2    #整數1小於整數2
test 整數1 -ne 整數2    #整數1不等於整數2
判斷文件

test File1 –ef File2    兩個文件是否爲同一個文件,可用於硬鏈接。主要判斷兩個文件是否指向同一個inode。
test File1 –nt File2    判斷文件1是否比文件2新
test File1 –ot File2    判斷文件1比是否文件2舊
test –b file   #文件是否塊設備文件
test –c File   #文件而且是字符設備文件
test –d File   #文件而且是目錄
test –e File   #文件是否存在 (經常使用)
test –f File   #文件是否爲正規文件 (經常使用)
test –g File   #文件是不是設置了組id
test –G File   #文件屬於的有效組ID
test –h File   #文件是不是一個符號連接(同-L)
test –k File   #文件是否設置了Sticky bit位
test –b File   #文件存在而且是塊設備文件
test –L File   #文件是不是一個符號連接(同-h)
test –o File   #文件的屬於有效用戶ID
test –p File   #文件是一個命名管道
test –r File   #文件是否可讀
test –s File   #文件是不是非空白文件
test –t FD     #文件描述符是在一個終端打開的
test –u File   #文件存在而且設置了它的set-user-id位
test –w File   #文件是否存在並可寫
test –x File   #文件屬否存在並可執行

expr用法

  expr命令通常用於整數值,但也可用於字符串。通常格式爲:

  #expr argument operator argument

  expr也是一個手工命令行計數器。

  #$expr 10 + 10

  20

  #$expr 1500 + 900

  2500

  #$expr 30 / 3

  10

  #$expr 30 / 3 / 2
  5
  (注意運算符左右都有空格)
  使用乘號時,必須用反斜線屏蔽其特定含義。由於shell可能會誤解顯示星號的意義。
  #$expr 30 * 3
  90
  17.5.1 增量計數
  expr在循環中用於增量計算。首先,循環初始化爲0,而後循環值加1,反引號的用法意
  即替代命令。最基本的一種是從(expr)命令接受輸出並將之放入循環變量。
  $LOOP=0

  #$LOOP=`expr $LOOP + 1`

  17.5.2 數值測試
  能夠用expr測試一個數。若是試圖計算非整數,將返回錯誤。
  $rr=1.1
  #$expr $rr + 1
  #expr: non-numeric argument
  $rr=2
  $expr $rr + 1
  3
  (注意:這個例子與原文不一樣)
  這裏須要將一個值賦予變量(無論其內容如何),進行數值運算,並將輸出導入dev/null,
  而後測試最後命令狀態,若是爲0,證實這是一個數,其餘則代表爲非數值。
  $value=12
  #$expr $value + 10 > /dev/null 2>&1
  $echo $?
  0
  這是一個數。
  $value=hello
  #$expr $value + 10 > /dev/null 2>&1
  $echo $?
  2

  這是一個非數值字符。
  expr也能夠返回其自己的退出狀態,不幸的是返回值與系統最後退出命令恰好相反,成功返回1,任何其餘值爲無效或錯誤。下面的例子測試兩個字符串是否相等,這裏字符串爲「hello」和「hello」。
  $value=hello
  $expr $value = "hello"
  1
  $echo $?
  0
  expr返回1。不要混淆了,這代表成功。如今檢驗其最後退出狀態,返回0表示測試成功,
  「hello」確實等於「hello」。
  17.5.3 模式匹配

  expr也有模式匹配功能。可使用expr經過指定冒號選項計算字符串中字符數。.*意即任何字符重複0次或屢次。
  $value=accounts.doc
  $expr $value : '.*'
  12
  在expr中可使用字符串匹配操做,這裏使用模式. d o c抽取文件附屬名。
  $expr $value : '(.*).doc'
  accounts
相關文章
相關標籤/搜索