配置變量與語句

bash——CLI(命令行接口)的一種

bash同樣屬於完整的應用程序,也有這四類文件:


bash的配置文件:

三類:

profile類:

爲交互式登錄的shell進程實現功能初始化的配置文件;

bashrc類:

爲非交互式登錄的shell進程實現功能啓動配置的配置文件;

logout類:

爲交互式登錄的shell進程提供終止及清理類功能的配置文件;


shell的類型:

交互式登錄的shell:

1.直接通過某個終端輸入賬號和密碼後登錄打開的shell進程;

2.使用su - USERNAME或su -l USERNAME執行切換登錄打開的shell進程;


非交互式登錄的shell:

1.在圖形界面下,通過菜單或右鍵菜單打開的終端的shell進程;

2.使用su USERNAME執行切換登錄打開的shell進程;


bash的配置文件:

profile類:

全局:對所有用戶都生效的配置文件;

/etc/profile

/etc/profile.d/*.sh


注意:在RHEL或CentOS系列的操作系統中,通常情況下,如果一個配置文件內容很多,格式複雜,我們會將其切割成多個片段,將切割出來的片段統一的存放在"程序名稱.d"目錄中;在這樣目錄中所保存的片段文件,大多以統一的文件後綴名來命名;


用戶個人:僅僅只是針對某個用戶有效的配置文件;

~/.bash_profile


profile類配置的文件的作用:

1.用於定義用戶的環境變量;

2.用於運行腳本或執行命令;


bashrc類:

全局:

/etc/bashrc

用戶個人:

~/.bashrc


bashrc類配置的文件的作用:

1.用於定義本地變量;

2.用於定義命令的別名;

3.定義umask;


注意:只有超級用戶root可以修改全局類的配置文件;普通用戶只能修改其家目錄中的個人配置文件;


交互式登錄的shell進程,會按照順序加載下列配置文件:

/etc/profile --> /etc/profile.d/*.sh --> ~/.bash_profile --> ~/.bashrc --> /etc/bashrc


非交互式登錄的shell進程,會按照順序加載下列配置文件:

~/.bashrc --> /etc/bashrc  --> /etc/profile.d/*.sh


所有在命令行中執行的命令的操作,只要沒涉及到文件的修改的,一般都只是針對當前的shell生命週期有效;只要shell進程結束,所有的設置均失效;


配置文件的作用:使得我們賴以生存的配置信息可以長期有效,只要不修改配置文件中的內容, 每一次打開shell都會使曾經的配置生效;


讓配置文件中新定義的配置能夠立即生效的方式:

1.source命令:

source /PATH/TO/SOME_CONF_FILES

. /PATH/TO/SOME_CONF_FILES


2.exec命令:

exec /PATH/TO/SOME_CONF_FILES


bash中變量中存放的字符串處理方式:

弱變量:

1.無需事先定義即可使用;

2.沒有變量數據類型的硬性要求,默認是字符型;


1.字符串切片:

${#VAR}:返回字符串類型的變量VAR的長度;

${VAR:offset}:返回字符串變量VAR中第offset個字符後面的內容,不包括第offset個字符;offset的取值範圍爲:0 ~ $[${#VAR}-1]

${VAR:offset:number}:返回字符串變量VAR中從第offset個字符後開始,長度爲number的字符部分;

${VAR: -length}:取字符串最右側的length個字符;


2.基於模式取字串:

${VAR#*PATTERN}:自左而右,查找VAR變量所存儲的字符串中,第一次被PATTERN匹配的字符,刪除從字符串開始到PATTERN匹配的字符之間的所有字符;

${VAR##*PATTERN}:自左而右,查找VAR變量所存儲的字符串中,所有被PATTERN匹配的字符,刪除從字符串開始到最好一個PATTERN匹配的字符之間的所有字符;

${VAR%PATTERN*}:自右而左,查找VAR變量所存儲的字符串中,第一次被PATTERN匹配的字符,刪除從字符串結尾到PATTERN匹配的字符之間的所有字符;

${VAR%%PATTERN*}:自右而左,查找VAR變量所存儲的字符串中,所有被PATTERN匹配的字符,刪除從字符串結尾到最好一個PATTERN匹配的字符之間的所有字符;


3.查找替換:

${VAR/PATTERN/SUBSTRING}:在VAR變量中查找匹配PATTERN的內容,將其第一個匹配到的結果更換成SUBSTRING;

${VAR//PATTERN/SUBSTRING}:在VAR變量中查找匹配PATTERN的內容,將其所有匹配到的結果都更換成SUBSTRING;


${VAR/#PATTERN/SUBSTRING}:在VAR變量中查找行首匹配PATTERN的內容,將匹配的結果更換成SUBSTRING;

${VAR/%PATTERN/SUBSTRING}:在VAR變量中查找行尾匹配PATTERN的內容,將匹配的結果更換成SUBSTRING;


4.查找刪除:

${VAR/PATTERN}:在VAR變量中查找匹配PATTERN的內容,將其第一個匹配到的結果刪除;

${VAR//PATTERN}:在VAR變量中查找匹配PATTERN的內容,將其第一個匹配到的結果刪除;


${VAR/#PATTERN}:在VAR變量中查找匹配PATTERN的內容,將其行首匹配到的結果刪除;

${VAR/%PATTERN}:在VAR變量中查找匹配PATTERN的內容,將其行尾匹配到的結果刪除;


5.字符的大小寫轉換:

${VAR^^}:將VAR變量中的所有小寫字母轉換爲大寫字母;

${VAR,,}:將VAR變量中的所有大寫字母轉換爲小寫字母;


6.變量賦值:

${VAR:-value}:如果變量VAR爲空或未被設置,那麼直接返回value的值;否則返回變量VAR的值;

${VAR:+value}:如果變量VAR不爲空,則返回value;

${VAR:=value}:如果變量VAR爲空或未被設置,那麼直接返回value的值,並且將value的值賦值給變量VAR;否則返回變量VAR的值;


7.變量的間接引用:

如果第一個變量的值恰好是第二個變量的變量名,從第一個變量引用第二個變量的值的方法,就稱爲變量的間接引用,也稱爲間接變量引用;

VAR1=VAR2

VAR2=value

bash提供了兩種格式的間接變量引用方式:

eval MYVAR=\$$VAR1

MYVAR=$(!VAR1)


1.有大文本文件file1,查詢file1裏面空行的所在行號;

2.編寫shell腳本查詢file1以abc結尾的行,並打印出前3行。


回顧:

顏色代碼:

\033[


echo -e ""


bash的配置文件:

交互式登錄shell進程

非交互式登陸shell進程


profile

bashrc

logout


變量中的字符串處理:


數組

變量:內存的存儲空間;

變量的特點:每個變量中只能存放一個數據,變量只能進行一次性的賦值;


存放本班每個人的名字於變量:

1.一次性賦值:

NAME="name1 name2 name3 ..."

2.使用多個變量,分別賦值:

NAME1=xu

NAME2=shen

3.數組變量:


數組:存放一個或多個元素的連續的內存空間;相當於多個變量的集合;

數組元素:數組中任何一個存放數據的存儲單元;

數組的索引:

1.數字:索引數組(Index ARRAY)

0,1,2,...

2.名稱(字符串):關聯數組(Related ARRAY)

bash4.0以上的版本才支持;


稠密數組和稀疏數組:

稠密數組:索引編號必須連續

稀疏數組:索引編號可以不連續,bash數組屬於此類;


聲明數組:

1.declare命令

declare -i NAME:將NAME聲明爲整型變量;

declare -x NAME:將NAME聲明爲環境變量;


declare -a NAME:將NAME聲明爲索引數組(如果支持);

declare -A NAME:將NAME聲明爲關聯數組(如果支持);


declare -a NAME=("value1" "value2" "value3" ...)

declare -a NAME=([0]="value1" [1]="value2" [5]="value3" ...)


2.直接聲明數組:

直接爲數組賦值:

ARRAY_NAME=("value1" "value2" "value3" ...) 聲明稠密數組;

ARRAY_NAME=([0]="value1" [1]="value2" [5]="value3" ...) 聲明稀疏數組;


3.定義數組的元素而創建數組:

ARRAY_NAME[0]=value1

ARRAY_NAME[1]=value2

...


引用數組中元素:

引用變量的方法:${NAME}

引用數組元素的方法:${ARRAY_NAME[INDEX]}

注意:如果不給出INDEX,則表示引用數組的第一個元素,即INDEX=0的元素;

引用整個數組的所有元素:${ARRAY_ANME[*]}或者${ARRAY_ANME[@]}

引用數組的索引:${!ARRAY_ANME[*]}或者${!ARRAY_ANME[@]}


查看數組的長度(數組中有效元素的個數)

${#ARRAY_NAME[*]} 或者 ${#ARRAY_NAME[@]} 


數組切片:

${ARRAY_NAME:offset}:顯示包括offset數字所表示的索引位置及以後的所有元素;

${ARRAY_NAME:6}:跳過0-5,從6開始顯示

${ARRAY_NAME:offset:number}:顯示包括offset數字所表示的索引位置及以後的number個元素;${ARRAY_NAME:6:3}:跳過0-5,從6開始顯示3個元素;


想數組中追加元素:

1.稠密數組:

ARRAY_NAME[${#ARRAY_NAME[*]}]=valueN

0 1 2 3 4 5 6 7

2.稀疏數組:

ARRAY_ANME[INDEX]=valueN

注意:INDEX必須爲未被使用的數組元素索引編號;


撤銷數組:

usnet ARRAY_NAME


刪除數組中的元素:

unset ARRAY_NAME[INDEX]


RANDOM變量:0-32767 

熵池

/dev/random

/dev/urandom


bash腳本編程:

寫一個腳本:

創建一個用戶alice,如果該用戶已經存在,就提示用戶已經存在的信息;否則將創建用戶;


shell腳本編程的特點:

過程式編程語言

腳本類語言

解釋型語言


過程式編程語言:

順序執行結構:

以從左到右,從上到下順序執行所有的語句(命令)

shell腳本的主體結構;


選擇執行結構:

依照給定條件的邏輯判斷結果或者依照可選的取值範圍,進而選擇某個分支中的語句來執行;

if:分支選擇標準:邏輯判斷的結果;

case:分支選擇標準:根據可選的取值;


循環執行結構:

對於某特定語句,重複執行0次,1次或多次;

for:遍歷指定的列表;

while:根據邏輯判斷的結果;

until:根據邏輯判斷的結果;

select:死循環,利用循環機制提供選擇列表;


選擇執行結構:

if語句:

if 命令; then 命令; [ elif 命令; then 命令; ]... [ else 命令; ] fi


if語句單分支結構:如果條件爲真,則執行then後的命令,否則,不做任何操作;

if CONDITION

then STATEMENT

fi


if CONDITION ; then

STATEMENT1

STATEMENT2

...

fi


注意:想要執行then後面的STATEMENTS,前提條件是CONDITION部分爲真;


if語句的雙分支結構:如果條件爲真,就執行then後面的命令;否則就執行else後面的命令;

if CONDITION ; then

STATEMENT

...

else

STATEMENT

...

fi


if語句的多分支結構:首先判斷CONDITION1是否爲真,如果爲真,則執行第一個then後面的語句;否則就判斷CONDITION2是否爲真,如果爲真,就執行第二個then後面的語句;否則就判斷CONDITION3是否爲真,如果爲真,就執行第三個then後面的語句...;如果所有的CONDITION都爲假,就執行else後面的語句;

if CONDITION1 ; then

STATEMENT

...

elif CONDITION2 ; then

STATEMENT

...

elif CONDITION3 ; then

 STATEMENT

 ...

...

else

STATEMENT

...

fi


建議:if多分支結構,能不用就不用;


練習:

1.寫一個腳本,列出系統中默認shell爲bash用戶;


bash腳本編程之用戶交互:

位置參數變量:$1, $2, $3, ...

特殊變量:

$#:所有的位置參數的總數;

$*:給出的所有位置參數的列表;當使用雙引號引用時,整個參數列表被當做一個字符串;

$@:給出的所有位置參數的列表;當時有雙引號引用時,每個參數作爲單獨的字符串存在;

$0:所執行的腳本文件自身的路徑;


2.寫一個腳本,給腳本傳遞用戶名參數,判斷參數數量是否合格;並且判斷用戶是否存在,如果存在,就顯示相應信息;否則就創建之併爲其設置密碼;

#!/bin/bash

#

if [ $# -ne 1 ] ; then

  echo "Only ONE USERNAME can be specified."

  exit 5

fi


if id $1 &> /dev/null ; then

  echo "$1 exists already."

else

  useradd $1

  echo $1 | passwd --stdin $1 &> /dev/null

  echo "Create $1 successfully."

fi


read命令:

read [-a 數組] [-p 提示符] [-t 超時] [名稱 ...]

名稱一般爲變量名或數組名:如果不寫名稱,則系統會將read讀到的信息保存在REPLY變量中;


LInux哲學思想:儘量不與用戶交互;


注意:在使用read命令的時候,通常會使用-t選項來規定超時時間;一旦使用-t選項定義了超時時間,我們必須在後面判斷給定的變量是否爲空,如果爲空需要爲變量提供默認值;


寫一個腳本:

能夠添加或刪除用戶賬戶,可以使用-a選項完成添加,使用-d選項完成刪除用戶;

#!/bin/bash

#

if [ $# -ne 2 ] ; then

  echo "Usage: $(basename $0) -a Username | -d Username."

  exit 5

fi


if [ $1 == '-a' ] ; then

  if id $2 &> /dev/null ; then

    echo "$2 exists already."

  else

    useradd $2

    echo $2 | passwd --stdin $2 &> /dev/null

    echo "Create $2 successfully."

  fi

fi


if [ $1 == '-d' ] ; then

  if id $2 &> /dev/null ; then

    userdel -r $2

    echo "Delte $2 finished."

  else

    echo "User $2 does not exist."

  fi

fi


寫腳本解決問題:

1.判斷給出的文件大小是否大於100KB,如果大於100KB,就顯示這是個大文件;否則就顯示這是個小文件;

#!/bin/bash

#

FILESIZE=$(wc -c < $1)

if [ $FILESIZE -le 102400 ] ; then

echo "Big file."

else

echo "Small file."

fi


2.判斷給出的一個字符串是否爲整數

#!/bin/bash

#

if echo $1 | grep "^\<[[:digit:]]\+\>$" &> /dev/null ; then

echo "$1 is integer."

else

echo "$1 is not integer."

fi

  



週一:7:00  8:00 12:00 1:30 6:00 12:00   100分鐘學習linux


回顧:

數組變量:一維數組

與bash交互的方式:

位置參數變量

read命令

if 單分支 雙分支


位置參數變量:

$1, $2, $3, ...


shift [n]

移位位置參數。



編寫簡易計算器:


繪製流程圖


如果 用戶存在 那麼

  提示用戶存在

否則

創建用戶

果如


if id ; then

echo

else

useradd

fi


如果 第一個參數是-a 那麼

如果 第二個參數是用戶名並存在 那麼

顯示存在

否則

創建

果如

果如


if語句多分支結構:

if CONDITION1 ; then

STATEMENT

...

elif CONDITION2 ; then

STATEMENT

...

elif CONDITION3 ; then

STATEMENT

...

...

else

STATEMENT

...

fi

循環執行結構:

將一段代碼重複的執行0次、1次或多次;

一個好的循環結構,必須要包括兩個最重要的環節:

進入循環的條件:

開始循環時所滿足的條件;

退出循環的條件:

循環結束所滿足的條件;


bash腳本:

for

while

until

select


for循環:

1.遍歷列表

for VAR_NAME in LIST ; do 循環體; done


for VAR_NAME in LIST ; do

循環體

done


VAR_NAME:任意指定的變量名稱,變量的值是從LIST中取值並賦值的;

循環體:一般來說是能夠用到VAR_NAME的命令或命令的組合;如果循環體中沒有包括VAR_NAME,則可能出現死循環;

LIST的生成方式:

1) 直接給出

2) 純整數列表

seq:輸出一個整數列表

seq [FIRST [INCREMENT]] LAST

3) 花括號展開

{FIRST..LAST}

4) 命令的執行結果的返回值

5) GLOBBING

6) 某些變量的引用:$@, $*


寫一個腳本:

能夠添加或刪除用戶賬戶,可以使用-a選項完成添加一個或多個用戶,使用-d選項完成刪除一個或多個用戶;

示例:

#!/bin/bash

#

if [ $# -lt 2 ] ; then

  echo "Usage: $(basename $0) -a User1 User2 ... | -d User1 User2 ..."

  exit 5

fi


if [ $1 == '-a' ] ; then

  shift

  for I in $* ; do

    if id $I &> /dev/null ; then

      echo "$I exists already."

    else

      useradd $I

      echo $I | passwd --stdin $I &> /dev/null

      echo "Create $I successfully."

    fi

  done

fi


if [ $1 == '-d' ] ; then

  shift

  for J in $* ; do

    if id $J &> /dev/null ; then

      userdel -r $J

      echo "Delte $J finished."

    else

      echo "User $J does not exist."

    fi

  done

fi


for循環:

進入循環的條件:LIST中有元素可以取用;

退出循環的條件:LIST中以被取空,再無元素可用;


for循環的特點:

1.幾乎不會出現死循環;

2.在執行循環的過程中,需要將這個LIST載入內存;因此對於大列表來說可能會過多的消耗內存和CPU資源;


示例:計算100以內所有整數的和;


#!/bin/bash

#

read -t 5 -p "Please input a integer[0]: " INTEGER


if [ -z $INTEGER ] ; then

  INTEGER=0

fi


if ! echo $INTEGER | grep -q "^\<[[:digit:]]\+\>$" ; then

  echo "You must input an integer."

  exit 5

fi


for I in $(seq $INTEGER) ; do

# let SUM+=$I

# let SUM=$SUM+$I

  SUM=$[SUM+I]

done

echo $SUM



2*[5-(5-1)]-1 = 9



*********   1  0  9   行-1個空格 以及 2*(總行數-行)+1 個星星 

 ******* 2  1  7

  ***** 3  2  5

   *** 4  3  3

    * 5  4  1


寫一個腳本,打印由*組成的倒置的等腰三角形;

#!/bin/bash

#

LINENUM=$1

for I in $(seq $LINENUM) ; do

  for J in $(seq $[I-1]) ; do

    echo -n " "

  done

  for K in $(seq $[2*(LINENUM-I)+1]) ; do

    echo -n "*"

  done

  echo

done


打印九九乘法表

#!/bin/bash

#

for I in {1..9} ; do

  for J in $(seq $I) ; do

    echo -ne "$I*$J=$[I*J]\t"

  done

  echo

done


1X1=1 1X2=2 1X3=3 ... 1X9=9

2X2=4 2X3=6 ... 2X9=18

...

9X9=81


注意:使用for循環嵌套的時候,外層for循環,控制行數的輸出;內層for循環,控制列數的輸出;


2.控制變量

for (( 表達式1; 表達式2; 表達式3 )); do 命令; done


for (( 表達式1; 表達式2; 表達式3 )) ; do

循環體

done


表達式1:爲變量賦初始值;

表達式2:循環的退出條件;

表達式3:變量值的變化規律;


#!/bin/bash

for (( I=1; I<=100; I++ )); do

let SUM+=$I

done

echo $SUM


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章