【shell基礎】0七、bash腳本編程入門及變量



1、shellhtml

一、shell是什麼java

     在計算機語言中,shell是指一種命令行解釋器,是爲用戶和操做系統之間通訊提供的一種接口。python

它接受來自用戶輸入的命令,並講其轉換爲一系列的系統調用送到內核執行,並將結果輸出給用戶。
linux


二、shell分爲兩大類redis

一類是圖形界面shell(Graphical User Interface):shell

                  Gnome,KDE,Xface(嵌入式輕量級桌面系統)編程

另外一類是命令行式shell(command Line Interface):vim

                 sh,bash,ksh,zsh,tcshwindows

查看系統使用的shell:數組

[root@Node3 ~]# cat /etc/shells   #系統默認安裝的shell
/bin/sh
/bin/bash
/sbin/nologin
/bin/dash
[root@Node3 ~]# echo $SHELL      #當前使用的shell
/bin/bash
[root@Node3 ~]# bash --version
GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

  事實上,shell不僅是一種解釋器(在用戶和系統間騎着橋樑的做用) ,仍是一種編程工具,稱爲腳本語言。腳本語言又被稱做解釋型語言   

   

三、shell的功能

       當一臺系統運行起來時,內核會被調入內存中運行,由內核執行全部底層的工做,它會將全部應用程序及用戶的操做翻譯成CPU的基本指令,並將其送至處理器。這些過程聽起來很是複雜,並且實際上也確實是很是底層的和技術化的。爲了對用戶屏蔽這些複雜的技術細節,同時也爲了保護內核不會由於用戶直接操做而受到損害,有必要在內核之上建立一個層,該層就是一個‘殼’,這就是shell的由來。


四、解釋和編譯

      計算機不能理解高級語言,只能理解機器語言,全部必須把高級語言翻譯爲機器碼。而這種翻譯的方式有2類:

編譯:

      編譯器:源程序(文本文件)-->預處理-->編譯-->彙編-->連接

      編譯型語言也被稱爲靜態語言:是指在編譯時變量的數據類型便可肯定的語言,多數靜態類型語言要求在使用變量以前必須聲明數據類型,如c,java

解釋:

       解釋器:解釋器可獨立運行,解釋器運行代碼

             詞法分析

             語法分析

             語義分析

      源程序(文本文件)-->解析器讀取並執行

      解釋器也被稱爲動態語言: 是在運行時肯定數據類型的語言。變量使用以前不須要類型聲明,一般變量的類型是被賦值的那個值的類型,如,python,bash,perl

編譯和解釋不一樣之處:

        翻譯的時間不一樣,編譯型語言是運行前翻譯,通常是使用編譯工具講程序源碼處理成機器認識的可執行文件(好比:windows上的exe文件,linux下的二進制執行文件),這種文件一旦產生,之後運行時,將不須要須要再次翻譯,全部編譯型語言效率較高;而解釋型語言是運行時翻譯,執行一條語句就當即翻譯一條,並且每次執行程序都須要進行解釋,相對來講效率較低。


五、過程式編程語言

順序執行

選擇執行:

       測試條件,當條件知足時,執行其中對應條件下的那部分代碼

循環執行:

       一段代碼被反覆執行屢次,循環語句須要退出條件


六、bash shell有兩種工做模式

互動模式:所謂互動模式就是輸入命令,等待期執行完畢後再執行嚇一跳命令

腳本模式:使用bash提供控制機制,將指望執行的命令羅列於文本文件中

                 bash沒有庫,整個程序幾乎都要依賴於命令


2、bash編程入門

一、shebang

linux可執行文件的格式是ELF

[root@Node3 tmp]# file /bin/ls    #ELF格式的文件能夠執行
/bin/ls: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped
[root@Node3 tmp]# file memory.txt 
memory.txt: ASCII text

#!/bin/bash            #指定解釋器的路徑,內核調用對應的解釋器來解釋腳本

腳本中常交待的信息:

#!/bin/bash  
#Description:
#Version:
#Author:
#License:
#Datetime:

腳本文件中以#開頭的行均爲註釋行,將會被解釋器忽略


二、運行腳本

      內核會啓動一個專門的shell進程(是當前shell的子進程)來運行程序文件,腳本運行結束,此shell進程也即終止

運行腳本的方式:

 1)給腳本執行權限,然後指定路徑來運行

          內核會經過讀取腳本文件第一行來判斷啓動什麼解釋器來運行此腳本

 2)指定給釋器來運行

[root@Node3 src]# vim first.sh
[root@Node3 src]# cat first.sh 
#!/bin/bash
echo "Hello world"
[root@Node3 src]# chmod +x first.sh 
[root@Node3 src]# first.sh
-bash: first.sh: command not found
[root@Node3 src]# ./first.sh 
Hello world
[root@Node3 src]# source first.sh   #此時能夠沒有執行權限
Hello world
[root@Node3 src]# /tmp/src/first.sh 
Hello world
[root@Node3 src]# bash first.sh    #此時能夠沒有執行權限
Hello world

bash命令經常使用的選項:

   -n   注意:檢查語法錯誤,但不會檢查命令錯誤

   -x   調試運行  顯示運行過程


三、腳本的執行結果狀態返回值

腳本最後一個命令的執行結果狀態返回值

自定義腳本的執行結果狀態返回值:

exit [N]

注意:腳本中不管哪一個位置遇到exit命令就中止運行,退出解釋器

[root@Node3 src]# cat first.sh 
#!/bin/bash
echo "Hello world"
[root@Node3 src]# bash first.sh 
Hello world
[root@Node3 src]# echo $?
0
[root@Node3 src]# echo "exit 111">>first.sh
[root@Node3 src]# bash first.sh 
Hello world
[root@Node3 src]# echo $?
111

四、shell腳本不一樣的執行方法的區別

  有兩種方法執行shell scripts,一種是新產生一個shell,而後執行相應的shell scripts一種是在當前shell下執行,再也不啓用其餘shell。
  新產生一個shell而後再執行scripts的方法是在scripts文件開頭加入語句:#!/bin/sh。通常的script文件(.sh)便是這種用法。這種方法先啓用新的sub-shell(新的子進程),而後在其下執行命令。
  另一種方法就是上面說過的source命令,再也不產生新的shell,而在當前shell下執行一切命令。source: source命令即點(.)命令。在 bash下輸入man source,找到source命令解釋處,能夠看到解釋"Read and execute commands from filename in the current shell environment and ..."。從中能夠知道,source命令是在當前進程中執行參數文件中的各個命令,而不是另起子進程(或sub-shell)。

  source 命令是 bash shell 的內置命令,從 C Shell 而來。source 命令的另外一種寫法是點符號,用法和 source 相同,從Bourne Shell而來。source 命令能夠強行讓一個腳本去當即影響當前的環境。source 命令會強制執行腳本中的所有命令,而忽略文件的權限。source 命令一般用於從新執行剛修改的初始化文件,如 .bash_profile 和 .profile 等等。source 命令能夠影響執行腳本的父shell的環境,而 export 則只能影響其子shell的環境。


在腳本中可使用source或.爲把文件當成當前腳本的配置文件(引入變量...)

[root@Note3 src]# echo $a

[root@Note3 src]# cat test1.conf 
a=111
[root@Note3 src]# source test1.conf   #在當前shell中引入變量,影響當前的shell環境
[root@Note3 src]# echo $a
111
[root@Note3 src]# cat test.sh 
#source test1.conf
echo "$a"
[root@Note3 src]# bash test.sh

[root@Note3 src]# vim test.sh
[root@Note3 src]# cat test.sh
source test1.conf                #把其它的文件當作當前腳本的配置文件
echo "$a"
[root@Note3 src]# bash test.sh
111


3、變量

一、變量是什麼

       顧名思義,變量就是其值能夠變化的量,從變量的本質來講變量是指向一片用於存儲數據的內存空間。

變量命名:

    一、不能使用程序中的關鍵字(保留字)如,if,case,for

    二、只能使用數字,字母和下劃線,且不能以數字開頭

    三、要見名知義

變量賦值:向變量指向的存儲空間保存數據    

        VAR_NAME=VALUE     #「=」號兩邊不能有空格

變量引用:引用其值

        ${VAR_NAME}              # {}通常可省略

撤銷變量: unset VAR_NAME 

[root@Node3 ~]# echo $name

[root@Node3 ~]# name=xj
[root@Node3 ~]# echo ${name}
xj
[root@Node3 ~]# echo $name
xj
[root@Node3 ~]# echo name
name
[root@Node3 ~]# name=3          #從新賦值
[root@Node3 ~]# echo $name
3
[root@Node3 ~]# bash            #子shell無效
[root@Node3 ~]# echo $name

[root@Node3 ~]# exit
exit
[root@Node3 ~]# unset name     #撤銷變量
[root@Node3 ~]# echo $name

[root@Node3 ~]# 
[root@Node3 src]# file=test0             #
[root@Node3 src]# rm file
rm: 沒法刪除"file": 沒有那個文件或目錄
[root@Node3 src]# rm $file
rm: 沒法刪除"test0": 沒有那個文件或目錄
[root@Node3 src]# file=test1
[root@Node3 src]# rm $file
rm:是否刪除普通空文件 "test1"?y

二、變量類別

本地變量:只對當前shell進程有效,對其它shell進程無效,包括當前shell的子進程     

環境變量:對當前shell及其子shell有效,對其餘shell無效

       定義:export VAR_NAME=VALUE

       導出:export VAR_NAME 

只讀變量: readonly VAR_NAME       #其值不能重複賦值

              用戶可自定義,bash有許多內置的環境變量

局部變量:對shell腳本中某代碼片斷有效,一般用於函數本地

        定義: local VAR_NAME=VALUE

位置參數變量:$0$1,$2,$三、、、${10}

特殊變量:$?,$!,$#,$@,$*

$0:腳本名稱自身

$?:上一條命令執行的狀態返回值,

      狀態用數字來表示0-255,0表示成功,非0表示失敗

$$:當前程序進程號

$!:運行於後臺的最後一個做業的PID

$#:腳本全部參數的個數

$@:全部的位置參數,每一個參數都是一個獨立的字符串

$*:全部的位置參數,被看成一個字符串        

$-:傳遞給腳本的標記,不知道怎麼使用

$_:上一條命令的最後一個參數

查看當前shell進程中的全部變量:set

查看當前shell進程中的全部環境變量:export,printenv,env

[root@Node3 src]# cat test.sh 
#!/bin/bash

cat << EOF
\$0 is $0
\$1 is $1
\$2 is $2
\$3 is $3
\$# is $#
\$@ is $@
\$* is $*
EOF
[root@Node3 src]# bash test.sh a b c
$0 is test.sh
$1 is a
$2 is b
$3 is c
$# is 3
$@ is a b c
$* is a b c
[root@Node3 src]# echo $?
0

三、bash數據(變量)類型

數據類型的做用?

數據存儲格式不一樣(文本,數值)

      例如:有var1=18,若是18是數字和是字符串,它們須要的存儲空間不一樣

 數字的存儲     18:00010010                      只需8位
 字符串的存儲   18:1:00000001 8:00001000         需16位

數據的有效存儲範圍不一樣

比較機制不一樣

參與的運算類型不一樣

bash數據類型分爲2類:

數值型:

      精確數值:整數

      近似數值:浮點型            #小數沒法精確轉換爲二進制數字

               單精度浮點

               雙精度浮點

字符型:(ASCII)

       char     單個字符

       string   字符串

布爾型:true(1),false(0)  #數值或字符


bash是動態弱類型語言,變量事先又不須要事先聲明,那麼一切變量的類型默認爲字符

類型轉換:顯示轉換(bash不支持),隱式轉換    

[root@Node3 src]# a=1
[root@Node3 src]# b=2
[root@Node3 src]# echo $a
1
[root@Node3 src]# echo $a $b
1 2
[root@Node3 src]# echo $a+$b
1+2
[root@Node3 src]# echo "$a $b"
1 2
[root@Node3 src]# echo '$a $b'
$a $b


四、變量的其它用法

 ${#var}      #返回該變量字符串的長度,

[root@Node3 src]# url="magedu"
[root@Node3 src]# echo url
url
[root@Node3 src]# echo $url
magedu
[root@Node3 src]# echo ${url}
magedu
[root@Node3 src]# echo ${#url}
6

給以變量默認值:

${var:-value}

       若是var不空,其返回值var的值,不然,則返回value

var=${var:-value}  就能夠實現給var默認值

[root@Node3 src]# echo $SB

[root@Node3 src]# SB=${SB:-xj}
[root@Node3 src]# echo $SB
xj
[root@Node3 src]# SB=xw
[root@Node3 src]# echo $SB
xw
[root@Node3 src]# SB=${SB:-xj}
[root@Node3 src]# echo $SB
xw

3、變量運算

bash中變量如何運算?

[root@xxj ~]# num1=4
[root@xxj ~]# num2=8
[root@xxj ~]# num=$num1+$num2
[root@xxj ~]# echo $num
4+8

爲何會這樣?

       由於bash中全部變量都默認是字符類型。

應該怎樣進行運算呢?

一、事先申明變量的類型爲數值型

運算符:+,-,*,/,%(取餘,去模)

加強型賦值:+=,-=,*=,/=,%=

declare

declare  VARNAME=算數表達式     

      -i:×××變量

      -x:環境變量,相似於export


let

let VARNAME=算數表達式       


expr

expr  $num1 + $num2      #注意,符號先後要有空格,可直接獲得結果,可以使用命令引用其結果


使用特殊格式$[ ],$(( ))

$[算術表達式]          

$((算術表達式))

注意:

      圓整:若是計算結果中存在小數,將會被圓整

      算術表達式中含有變量可不須要$應用,用$引用也能夠(建議仍是使用)

[root@Node3 ~]# num1=1
[root@Node3 ~]# num2=2
[root@Node3 ~]# sum=$num1+$num2
[root@Node3 ~]# echo $sum          #事先聲明連個加數沒用
1+2
[root@Node3 ~]# declare -i sum     #事先聲明值能夠
[root@Node3 ~]# sum=$int1+$int2
[root@Node3 ~]# echo $sum
3
[root@Node3 ~]# a=1
[root@Node3 ~]# b=2
[root@Node3 ~]# declare -i c=$a+$b 
[root@Node3 ~]# echo $c
3
[root@Node3 ~]# a=2
[root@Node3 ~]# b=4
[root@Node3 ~]# let c=a+b
[root@Node3 ~]# echo $c
6
[root@Node3 ~]# let c=$a+b
[root@Node3 ~]# echo $c
6
[root@Node3 ~]# let c=$a+$b
[root@Node3 ~]# echo $c
6
[root@Node3 ~]# let a+b
[root@Node3 ~]#
[root@Node3 ~]# x=1
[root@Node3 ~]# y=2
[root@Node3 ~]# declare -i z=y-x
[root@Node3 ~]# echo $z
1
[root@Node3 ~]# expr x + y
expr: 參數數目錯誤
[root@Node3 ~]# expr $x + $y
3 
[root@Node3 ~]# expr z=$x + $y       #不能直接這樣賦值,要使用命令替換
expr: 參數數目錯誤
[root@Node3 ~]# x=1
[root@Node3 ~]# y=2
[root@Node3 ~]# z=$[x+y]
[root@Node3 ~]# echo $z
3
[root@Node3 ~]# z=$[$x+$y]
[root@Node3 ~]# echo $z
3
[root@Node3 ~]# z=$(($x+$y))
[root@Node3 ~]# echo $z
3


4、經常使用的內置變量

  在bash中,內置變量通常是純大寫字母,函數名通常首字母大寫。

經常使用的內置變量:

  PATH,PS1,HOSTNAME,UID,HISTFILE,HISTSIZE,HISTFILESIZE,HISTCONTROL


$BASH:bash二進制程序文件的文件

$BASH_VERSION:bash的版本

$BASH_SUBSHELL:子shell的層次,這個不知道咋用

$SHLVL:shll級別,bash被嵌入的深度

$SECONDS:當前腳本已經運行的時長

 

$UID:當前用戶的UID號

$EUID:有效的用戶ID

$GROUPS:顯示當前用戶GID

$HOME:當前用戶的家目錄

$PWD:當前路徑

$OLDPWD:上一個路徑

$PPID:父進程


$IFS:輸入數據時字段分隔符,默認爲空白符(空格,製表符,換行符)

$PS1:主提示符

$PS2:第二提示符,補充徹底輸入時的提示符

$PS3:第三提示符,用於select(菜單生成器)命令中

$PS4:第四提示符,當使用-x選項調用腳本時,顯示的提示符,默認爲+號


$FUNCNAME:在函數中引用的,查看當前函數的名稱

$EDITOR:默認編輯器


$HISTTYPE:主機類型,用來識別系統硬件(x86,x86_64)

$MACHTYPE:機器類型

$OSTYPE:OS類型

[root@Node3 ~]# echo $HOSTTYPE
x86_64
[root@Node3 ~]# echo $MACHTYPE
x86_64-redhat-linux-gnu
[root@Node3 ~]# echo $OSTYPE
linux-gnu


聲明變量:

 declare

    -i:×××

    -a:數組

    -A:關聯數組

    -x:環境變量   

    -r:只讀變量,至關於readonly

    -f:聲明函數 

相關文章
相關標籤/搜索