1. 程式人生 > >shell及程式設計例項

shell及程式設計例項

1.shell簡介

 

1) 概念--命令直譯器

2) 常見shell

bash linux標準shell

sh 早期shell,較簡單

csh ksh tcsh unix  shell

vi  /etc/shells linux支援的shell

3) shell指令碼--和php一樣是指令碼語言 所見即所得 在執行過程中進行編譯

所有的命令在shell當中都可以直接執行 其他語言比不了

是用來進行系統管理的---寫不出漂亮的介面

 

#!/bin/bash  所有的shell語言都必須以這個開頭

# 意思不是註釋 而是所有的內容都要呼叫bash來解釋 不可省略 可嵌入其他語言

為了能夠讓bash知道我要解釋的是呢一段內容

例1:列印時間

#!/bin/bash

test=`date +%F` test=$(date +%F) 把目錄的結果賦給變數test

echo "today  is  $test"      shell是隻需要在呼叫的時候給變數加上$

[[email protected] sh]# vi hell.sh------------一般寫的時候以.sh結尾 系統會加上顏色

[[email protected] sh]#

指令碼執行方式:

[[email protected]

sh]# ll

總用量 4

-rw-r--r-- 1 root root 39 7月   6 07:07 hell.sh

[[email protected] sh]# chmod 755 hell.sh-----賦予執行許可權

[[email protected] sh]# ll

總用量 4

-rwxr-xr-x 1 root root 39 7月   6 07:07 hell.sh

[[email protected] sh]#

A 賦予執行許可權

路徑執行-相對路徑或者絕對路徑的方式來呼叫它----------

一般用此種方式

[[email protected] sh]# /home/sh/hell.sh 絕對路徑

2014-07-06

[[email protected] sh]# ./hell.sh    相對路徑

2014-07-06

[[email protected] sh]#

B bash  指令碼檔案 此種方式指令碼檔案可以不賦予執行許可權

[[email protected] sh]# /bin/bash hell.sh

2014-07-06

[[email protected] sh]#

4 bash常見功能 掌握

A)歷史命令

預設儲存1000條歷史命令 上下翻 預設儲存數可以改

環境變數配置檔案總共有四個 下面是第一個

vi  /etc/profile 修改環境變數配置檔案,要生效,必須登出

HISTSIZE=1000 修改預設歷史命令條數

每個使用者敲的命令都儲存在自己的家目錄當中

[[email protected] sh]# cd /

[[email protected] /]# cd

[[email protected] ~]# pwd

/root

[[email protected] ~]# ls -a           

.bash_history       儲存的是上次登入之前 歷史命令儲存檔案

[[email protected] ~]#

history 查詢系統歷史命令

歷史命令儲存檔案

~/.bash_history

history  -w 把記憶體中命令歷史,儲存入.bash_history 檔案

history  -c 清空所有的歷史命令

重複歷史命令

n(命令號) 重複第n條命令

!Str(命令) 重複最後一個以str開頭的命令

上箭頭 呼叫上面的命令

B)自動補全

tab 可以進行命令補全(按照PATH路徑),也可以進行目錄和檔名補全

C)別名

alias   檢視系統中生效的別名

alias  ls='ls  --color=never' 手工設定別名,臨時生效

vi  ~/.bashrc 寫入別名,永久生效(寫入環境變數配置檔案)

5) 輸入輸出重定向

標準輸入 /dev/stdin 0 鍵盤

標準輸出 /dev/stdout 1 顯示器

標準錯誤輸出 /dev/stderr 2 顯示器

#裝置檔名 #檔案描述符 #預設裝置

 

a)輸出重定向

把應該輸出到螢幕的輸出,重定向到檔案。

ls  >  aa 覆蓋到aa

ls  >>  aa 追加到aa

掌握

ls  >>  aa  2>&1 錯誤和正確都輸入到aa,可以追加

2>&1 把標準錯誤重定向到標準正確輸出

ls  >>  aa  2>>bb 正確資訊輸入aa,錯誤資訊輸入bb

注意:錯誤輸出的大於號,左右兩側不能有空格

b)輸入重定向 瞭解

[[email protected] ~]# wc

vds

vdsjd

vdsn

      3       3單詞      15字元

[[email protected] ~]#

Ctrl + d 儲存 單詞是按照空格分開的

wc  <  aa 輸入重定向,把檔案作為命令的輸入

wc  <<  test 後面跟識別符號,直到再碰到相同的標誌,兩個標誌之間內容作為命令輸入

......

test

[[email protected] ~]# wc < a

 17  19 201

[[email protected] ~]# wc a

 17  19 201 a

[[email protected] ~]# wc << bbb

> ds

> ds

> fsd

> bbb  這個不算 之間的

 3  3 10

[[email protected] ~]#

6 多命令順序執行

 

a)命令1  ;  命令2 ; 命令3 命令123順序執行。之間沒有任何關係

不管命令1正確與否 後面的命令2和3 都會執行

b)命令1  &&  命令2 命令1正確執行後,命令2才會執行

邏輯&與

c)命令1  ||  命令2 命令1執行不正確,命令2才會執行

ls aa && echo "cunzai" || echo "bu cunzai!" 執行ls  aa,判斷如果正確,輸出“存在”。如果不存在,輸出“不存在”

 

看一下 開始執行時間 和 執行結束時間 複製磁碟a到磁碟b

[[email protected] ~]# ls && echo yes   ls正確執行了輸出yes

a                chongge      httpd-2.2.9.gz  install.log.syslog  公共的  視訊  文件  音樂

anaconda-ks.cfg  httpd-2.2.9  install.log     stop                模板    圖片  下載  桌面

yes

[[email protected] ~]# ls ||  echo no   

a                chongge      httpd-2.2.9.gz  install.log.syslog  公共的  視訊  文件  音樂

anaconda-ks.cfg  httpd-2.2.9  install.log     stop                模板    圖片  下載  桌面

[[email protected] ~]# ls cd ||  echo no   ls不正確輸出了輸出no

ls: 無法訪問cd: 沒有那個檔案或目錄

no

[[email protected] ~]#

 

[[email protected] ~]# ls && echo yes || echo no   ls正確輸出了輸出yes

做一個簡單的判斷 取代但分支if

a                chongge      httpd-2.2.9.gz  install.log.syslog  公共的  視訊  文件  音樂

anaconda-ks.cfg  httpd-2.2.9  install.log     stop                模板    圖片  下載  桌面

yes

[[email protected] ~]# lscds && echo yes || echo no   ls和echo yes都不正確執行了輸出no

-bash: lscds: command not found

no

[[email protected] ~]#

 

[[email protected] ~]# lscds  || echo no && echo yes

邏輯關係是混亂的 不可以這樣寫

Lscds執行錯誤 echo no

Lscds 和 echo no 只要有一個正確執行 就echo yes 這裡echo no正確執行

-bash: lscds: command not found

no

yes

[[email protected] ~]#

7 管道符

命令1  |  命令2 命令1的執行結果,作為命令2的執行條件

Netstat -an

tcp        0      0 192.168.1.107:57050         117.104.138.26:80           ESTABLISHED -------正在連線我的ip

netstat -an | grep ESTABLISHED | wc -l 統計正在連線的網路連線數量

[[email protected] ~]# netstat -an | grep ESTABLISHED | wc -l 顯示有多少個人正在連線我

1

[[email protected] ~]#

more  檔名  |  grep  “字串” 提取含有字串的行

 

ls  |  more 分屏顯示ls內容

 

 

2. 變數 shel程式設計瞭解

 

1分類

本地變數(只在一個shell中生效

環境變數(所有的shell中生效---定義操作環境的

位置引數變數(預定義變數的一種)

預定義變數(系統事先設定好的)

Pstree---程序樹

Set-------檢視所有變數

 

2本地變數

a)宣告 變數名=變數值 注意:=號左右不能有空格

aa=123

b)呼叫

echo  $變數名

c)檢視變數

set 檢視所有變數,包括環境變數和本地變數

d)刪除

unset  變數名

3變數設定規則

a)變數以等號連線值,等號不能有空格

b)變數名由數字和字母和下劃線組成,不能以數字開頭 

c)變數值中有空格,用引號括起來

d)雙引號內,有特殊字元。如$

e)單引號中特殊字元無含義

f)在變數值中,可以使用\轉義符

g)變數值可以直接呼叫系統命令。 `命令`   變數名=$(命令)

如果命令放在等號右邊賦給一個變數 此命令需要加上括號或者``

如果命令直接放在shell指令碼中執行 不需要加上括號或者``

h)變數值可以累加 aa=123    aa="$aa"456   echo $aa  --->123456

[[email protected] ~]# aa=123

[[email protected] ~]# echo $aa

123

[[email protected] ~]# aa="$aa"456

[[email protected] ~]# echo $aa

123456

[[email protected] ~]#

i)環境變數一定設為大寫

 

 

4環境變數 ---------最重要的作用是修改系統的預設環境變數

a)宣告

export  變數名=變數值

export  aa  (如果手工不指定型別 變數預設都是字串型別)declare -x

[[email protected] ~]# echo $aa

123456

[[email protected] ~]# echo $bb

456

[[email protected] ~]# cc=$aa+$bb

[[email protected] ~]# echo $cc

123456+456  -----字串型別

[[email protected] ~]#

 

b)檢視

set 檢視所有變數

env export 只能檢視環境變數

declare    宣告變數型別的,如果不特別宣告,所有變數為字串型

-i   宣告為int

-x   宣告為環境變數

 

c)刪除

unset  變數名

d)常見環境變數

PATH=/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

系統查詢命令的路徑 

所有系統預定義的環境變數 例如ls 和 tab鍵補全 都是在這個路徑下去尋找

如果沒有就會提示沒有

 

[[email protected] home]# PATH="$PATH":/home/sh

[[email protected] home]# echo $PATH

/usr/lib/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/home/s h

[[email protected] home]# cd sh

[[email protected] sh]# ls

hell.sh

[[email protected] sh]# hell.sh ------改變環境變數中的路徑 就可以直接呼叫環境變數 hell.sh

2014-07-07

[[email protected] sh]#

 

PATH="$PATH":/root/shell 在系統預設路徑後,追加/root/shell目錄作為命令查詢路徑

 

PS1=‘[\[email protected]\h \W]\$’ 系統提示符

\u  登入使用者名稱 \h  主機名   \W  最後一個目錄   \w  完整所在目錄

\T  當前時間  12時    \t  24小時 \#  歷史命令條數 \$  提示符

 

e)環境變數配置檔案

/etc/rc.local 在登陸之前就讀取了

/etc/profile etc下的配置檔案對所有使用者生效 輸入使用者名稱密碼後生效

/etc/bashrc etc下的配置檔案對所有使用者生效 輸入使用者名稱密碼後生效

~/.bashrc 家目錄下的只對指定使用者生效    輸入使用者名稱密碼後生效

~/.bash_profile 家目錄下的只對指定使用者生效    輸入使用者名稱密碼後生效

 

再讀~/.bash_profile 中.的作用source  環境變數檔名 讓配置檔案不重啟就生效

完整登陸流程時,載入環境變數順序-----每次登陸的時候去讀取

先讀/etc/profile

再讀~/.bash_profile

再讀~/.bashrc

再讀/etc/bashrc

開始Bash介面

 

3. 位置引數變數

$0 命令自己

$1   第一個引數

$2 第二引數

$9 第九個引數

[[email protected] sh]# vi canshu.sh

[[email protected] sh]# chmod 755 canshu.sh

[[email protected] sh]# ls

canshu.sh

[[email protected] sh]# ll

總用量 4

-rwxr-xr-x 1 root root 74 7月   7 01:36 canshu.sh

[[email protected] sh]# ./canshu.sh(第一引數使用者自身) 11(第二引數) 22 33(第N個引數

 mingling is :./canshu.sh

canshu is 11

22

33

[[email protected] sh]#

例2:輸出位置引數變數,指令碼後要接引數

#!/bin/bash

echo "the  command  is  $0"

echo "canshu1  is  $1"

echo "canshu2 is $2"

 

 

4. 預定義變數

 

$? 上一個命令的返回值。 0  上一個命令正確執行 非0  上一個命令不 正確

[[email protected] sh]# echo $?

0

[[email protected] sh]# ls dsdad

ls: 無法訪問dsdad: 沒有那個檔案或目錄

[[email protected] sh]# echo $?

2

[[email protected] sh]#

 

$# 統計命令之後的引數個數

$* 返回所有引數

#!/bin/bash

echo " mingling is :$0"

echo "canshu is $1"

echo $2

echo $3

echo "引數的個數是 $#"

echo "所有引數為 $*"

[[email protected] sh]# vi canshu.sh

[[email protected] sh]# ./canshu.sh 11 22 33 44 55 66

 mingling is :./canshu.sh

canshu is 11

22

33

引數的個數是 6

所有引數為 11 22 33 44 55 66

[[email protected] sh]# 

$n 位置引數變數

例3:輸出預定義變數

#!/bin/bash

echo "canshu  zongshu  $#"

echo "canshu libiao: $*"

echo  $?

 

5. 鍵盤讀取命令

例2:輸出位置引數變數,指令碼後要接引數

#!/bin/bash

echo "the  command  is  $0"

echo "canshu1  is  $1"

echo "canshu2 is $2"

如果要向程式中傳值  推薦使用[[email protected] sh]# vi read.sh

[[email protected] sh]# vi read.sh

[[email protected] sh]# chmod 755 read.sh

[[email protected] sh]# ./read.sh

please input a filename:abcdef

abcdef

[[email protected] sh]#

read  -p “提示資訊” -t  等待時間   變數名

例子4:通過read讀入變數值

#!/bin/bash

read -p "please input num1:" -t 30  test1

read -p "input num2:" -t 30  test2

declare -i sum=$test1+$test2

echo “num1 +  num2 = $sum”

[[email protected] sh]# vi read1.sh

[[email protected] sh]# chmod 755 read1.sh

[[email protected] sh]# ./read1.sh

./read1.sh: line 1: !#/bin/bash: 沒有那個檔案或目錄

please input num1:11

input num2:22

sum is 33

[[email protected] sh]# vi read1.sh

[[email protected] sh]#

 

6. 數值運算

變數值預設都是字串型,要想進行數值運算。以下三種任選一種

1)declare

num1=123

num2=456

declare -i sum=$num1+$num2

2)sum=$(( $num1 + $num2 ))

3)sum=`expr $num1 + $num2` 注意+左右必須空格

4)運算子

+   -  \*  /  %取餘    ----乘號要加轉義符

[[email protected] ~]# declare -i cc=$aa+$bb  eclare -i cc把變數cc變為整型

[[email protected] ~]# echo $cc

123912

[[email protected] ~]#

 

[[email protected] ~]# dd=$(($aa+$cc))-----$(()) 也可以轉化為整型

此種方法常見!!!!!!!!!!!!!!!!!

[[email protected] ~]# echo $dd

247368

[[email protected] ~]#

 

[email protected] ~]# ee=`expr $bb+$cc`---------

空格必須有 ` expr 變1 + 變數2 `---------------也可以進行數值運算

[[email protected] ~]# echo $ee

456+123912

[[email protected] ~]# ee=`expr $bb + $cc`-------空格必須有

[[email protected] ~]# echo $ee

124368

[[email protected] ~]#

 

 

例5:資料備份

#!/bin/bash

DAY=`date +%Y%m%d`

#定義日期變數

[[email protected] sh]# DAY=`date +%Y%m%d`

[[email protected] sh]# echo $DAY

20140707

[[email protected] sh]#

SIZE=`du -sh /var/lib/mysql`

#定義mysql目錄大小的變數

[[email protected] sh]# SIZE=`du -sh /var/lib/mysql`

[[email protected] sh]# echo $SIZE

1.3M /var/lib/mysql

[[email protected] sh]#

echo "Date: $DAY" >> /tmp/dbinfo.txt

#把日期輸入資訊文件

[[email protected] sh]# echo "Date: $DAY" >> /tmp/dbinfo.txt

[[email protected] sh]# cat /tmp/dbinfo.txt

Date: 20140707

[[email protected] sh]#

echo "Data Size: $SIZE" >> /tmp/dbinfo.txt

#把大小輸入資訊文件

[[email protected] sh]# echo "Data Size: $SIZE" >> /tmp/dbinfo.txt

[[email protected] sh]# cat /tmp/dbinfo.txt

Date: 20140707

Data Size: 1.3M /var/lib/mysql

[[email protected] sh]#

cd /opt/dbbak

#切換目錄備份

tar zcvf mysqlbak-${DAY}.tar.gz /var/lib/mysql /tmp/dbinfo.txt 把資料庫和資訊文件同時打包

打包備份mysql目錄,同時打包資訊文件

[[email protected] sh]# tar zcvf mysqlbak-${DAY}.tar.gz /var/lib/mysql /tmp/dbinfo.txt

tar: 從成員名中刪除開頭的“/”

...............

[[email protected] mysql]# cat /tmp/dbinfo.txt

Date: 20140707

Data Size: 1.3M /var/lib/mysql

[[email protected] mysql]# cd /root/sh

[[email protected] sh]# ls

canshu.sh  mysqlbak-20140707.tar.gz  read1.sh  read.sh

[[email protected] sh]#

rm -f /tmp/dbinfo.txt刪除資訊文件(打包裡面已經有了)

[[email protected] sh]# rm -f /tmp/dbinfo.txt

[[email protected] sh]# cat /tmp/dbinfo.txt

cat: /tmp/dbinfo.txt: 沒有那個檔案或目錄

[[email protected] sh]#

 

 

注: cat  -A  檔名 顯示檔案隱,包括藏字