shellb編程基礎第五篇
本章內容:數組
變量:存儲單個元素的內存空間
數組:存儲多個元素的連續的內存空間,相當於多個變量的集合。
索引:編號從0開始,屬於數值索引
注意:索引可支持使用自定義的格式,而不僅是數值格式,即爲關聯索引,bash4.0版本之後開始支持。
bash的數組支持稀疏格式(索引不連續)
數組名[索引]
${數組名[索引]}
定義數組:
聲明數組:declare -a NAME 聲明索引數組
declare -A NAME 聲明關聯數組
數組中元素賦值方式
一次只賦值一個元素:
一次賦值全部元素
只賦值特定元素
交互式數組值賦值 read -a 數組陳列
===================================================================
一次性元素賦值方式:
[root@xiaomag ~]# declare -a name 聲明索引數組名稱
[root@xiaomag ~]# name[0]=xiaobo 數組元素
[root@xiaomag ~]# name[1]=laozai 數組元素
[root@xiaomag ~]# echo ${name[*]} 調用全部元素
xiaobo laozai
[root@xiaomag ~]# echo ${name[0]} 調用0的元素
xiaobo
[root@xiaomag ~]# echo ${name[1]} 調用1的元素
laozai
===================================================================
一次賦值給全部元素:
[root@xiaomag ~]# name=("xiaobo" "laozai") 數組名稱=元素列表
[root@xiaomag ~]# echo ${name[0]} 輸出打印數組0的參數
xiaobo
[root@xiaomag ~]# echo ${name[1]} 輸出打印數組1的參數
laozai
[root@xiaomag ~]# echo ${name[*]} 輸出打印全部元素
xiaobo laozai
====================================================================
只給特定元素:
[root@xiaomag ~]# name=([0]="xiaobo" [2]="laozai") 數組名稱=特定給元素
[root@xiaomag ~]# echo ${name[0]}
xiaobo
[root@xiaomag ~]# echo ${name[2]}
laozai
[root@xiaomag ~]# echo ${name[*]}
xiaobo laozai
====================================================================
命令行舉例交互式數組賦值:
[root@Compro ~]# read -a name 讀取數組 名稱
xiaomag xiaobo laozai 寫入對應元素
[root@Compro ~]# echo ${name[0]} 0就是第一個元素
xiaomag
[root@Compro ~]# echo ${name[1]} 1就是第二個元素
xiaobo
[root@Compro ~]# echo ${name[2]} 2就是第三個元素
laozai 這叫做索引數組
======================================================================
[root@xiaomag ~]# name[laozai]=xiaobo
[root@xiaomag ~]# echo ${name[laozai]}
xiaobo
這種叫做關聯數組
=====================================================================
引用數組中的元素 $ {name[0]}
注意 :引用時只給數組名,表示引用下標爲0的元素
數組的長度,(數組中元素的個數)
${#name[*]}
${#name[@]} 就加上括號表示元素中的個數 ,不加表示第一個元素字符中的個數
=============================================================
練習
[root@Compro ~]# vim shuzusuiji.sh 編輯腳本名稱
#!/bin/bash
#
#uesr:Compro
#數組生成10個隨機數保存與數組中,並找出其最大值和最小值
declare -a name 聲明索引數組 name
declare -i max=0 聲明整數屬性
for i in {0..9};do 循環 變量i的值,0-9
name[$i]=$RANDOM 數組賦值上條命令的值=隨機
echo ${name[$i]} 打印數組的隨機值
[ ${name[$i]} -gt $max ] && max=${name[$i]} 條件判斷打印的值是否大於0. 如果大於0的話就執行 max=數組$i的元素
done
echo "Max:$max" 輸出打印上面的$max的值
===================================================
練習
[root@Compro shuzu]# vim oushuzhihe.sh
#!/bin/bash
#
#user:Compro
#寫一個腳本,定義一個數組,數組中的元素是/var/log目錄下所有以.log結尾的文件;
要統計其下標爲偶數的文件中的行數之和
declare -a files 聲明索引數組 files
files=( /var/log/*.log ) 數組元素= 路徑
declare -i lines=0 聲明整數屬性
for i in $(seq 0 $[${#files[*]}-1]);do 循環 變量i的值 ,追加數組元素
if [ $[$i%2] -eq 0 ];then 分支判斷變量值等於0
let lines+=$(wc -l ${files[$i]} | cut -d' ' -f1 ) 計算變量值 抽取以空白符爲分隔符的第1列的值
fi
done
echo "Lines: $lines." 輸出打印結果
==============================================================
引用數組中的元素
所有元素:${數組[@]},${數組[*]}
數組切片:${數組[@]}:offset:number
offset 要跳過的元素個數
number 要取出的元素個數
取偏移量之後的所有元素 ${數組[@]:offset}
向數組中最加元素:
數組名稱[${#數組元素[*]}]
刪除數組中的某元素:導致稀疏格式
unset 數組[索引]
關聯數組:
declare -A 數組名稱 必選先聲明,在調用
數組名稱=([元素1]='val1' [元素2] 'val2'...)
========================================================================
bash 的字符串處理工具
字符串切片:
${#var} 返回字符串變量var的長度
${var:offset} offset返回字符串的變量var中第offset個字符後(不包括第offset個字符)的字符開始,
到最後的部分offset的取值在0到 ${#var}-1 之間(bash4.2後,允許爲負值)
${var:offset:number} 返回字符串變量var中從第offset個字符 後(不包括第offset個字符)
的字符開始,長度爲number的部分
${var: -數字} 取字符串的最右側幾個字符
注意:冒號後面必須有一個空白字符
[root@xiaomag ~]# var=`echo {a..z}`
[root@xiaomag ~]# v=`echo $var |tr -d " "`
[root@xiaomag ~]# echo $v
abcdefghijklmnopqrstuvwxyz
[root@xiaomag ~]# echo ${#v}
26
[root@xiaomag ~]# echo ${v:3}
defghijklmnopqrstuvwxyz
[root@xiaomag ~]# echo ${v:3:5}
defgh
[root@xiaomag ~]# echo ${v: -3}
xyz
=====================================================================
基於模式取字符串:
${var#*word} 其中word可以是指定的任意字符
功能:自左而右,查找var變量所存儲的字符串中,第一次出現word,
刪除字符串開頭至第一次出現word字符之間的所有字符
~]# echo ${v#*m}
nopqrstuvwxyz
${var##*word} 同上,不同的是,刪除的是字符串開頭至
最後一次由word指定的字符之間的所有內容
~]# file="/var/log/messages"
~]# echo ${file##*/}
messages
${var%word*} 其中word可以是指定的任意字符
功能:自右而左,查找var變臉所存儲的字符串中,第一次出現的word,
刪除字符串最後一個字符向左至第一次出現word字符之間的所有字符
~]# file="/var/log/messages"
~]# echo ${file%/*}
/var/log
${var%%word*} 同上,只不過刪除字符串最右側的字符向左至
最後一次出現word字符之間的所有字符
url=aaaa:5556:222
~]# echo ${url##*:}
222 最右側的
~]# echo ${url%%:*}
aaaa 最左側的
[root@Compro ~]# var=hacker:x:1005:1005:hacker,,38763415:/home/hacker:/bin/bash
[root@Compro ~]# echo $var
hacker:x:1005:1005:hacker,,38763415:/home/hacker:/bin/bash
[root@Compro ~]# echo ${var#*x}
:1005:1005:hacker,,38763415:/home/hacker:/bin/bash
==============================================================================
查找替換:
${var/pattern/substi} : 查找var所表示的字符串,第一次被pattern所匹配到的字符串,以路徑替換之
${var//pattern/substi} : 查找var所表示的字符串,所有被pattern所匹配到的字符串,以路徑替換之
${var/#pattern/substi} : 查找var所表示的字符串,行首被pattern所匹配到的字符串,以路徑替換之
${var/%pattern/substi} : 查找var所表示的字符串,行尾被pattern所匹配到的字符串,以路徑替換之查找並刪除:
${var/pattern} 查找var所表示的字符串中,刪除第一次被pattern所匹配到的字符串
${var//pattern} 所有
${var/#pattern} 行首
${var/%pattern} 行尾
字符大小寫轉換:
${var^^} 把var中的所有小寫字母轉換爲大寫
${var,,} 把var中的所有大寫字母轉換爲小寫
變量賦值:
${var:-value} 如果var爲空或未設置,那麼返回value;否則,則返回var的值
${var:+value} 如果var不空,則返回value
${var:=value} 如果var爲空或未設置,那麼返回value,並將value 賦值給var;f否則,則返回var的值
${var:?error_info} 如果var爲空或未設置,那麼返回error_info;否則,
則返回var的值爲腳本程序使用配置文件,實現變量賦值
定義文本文件,每行定義“name=value”
在腳本中source此文件即可
高級變量用法-有類型變量:
shell變量一般是無類型的,但是bash shell提供了declare和
typeset兩個命令用於指定變量的類型,兩個命令是完全等價的
declare [選項] 變量名
-r name 將變量設置爲只讀屬性
-i name 將變量定義爲整型數
-a name 將變量定義爲數組
-f name 顯示此腳本前定義過的所有函數名及其內容
-F name 僅顯示此腳本前定義過的所有函數名
-x name 將變量聲明爲環境變量
-l name 將變量轉爲小寫字母
==============================================================
間接變量引用:
如果第一個變量的值是第二個變量的名字,
從第一個變量引用第二個變量的值就稱爲間接變量引用
var1=var2
var2=var3
var1的是是var2,而var2又是變量名,var2的值爲var3,間接變量引用是指通過var1獲得不變量值var3的行爲
[root@Compro ~]# echo ${!var1} 第一種間接引用格式
var3
bash shell提供了兩種格式實現間接變量引用
[root@Compro ~]# n=name
[root@Compro ~]# name=xiaomag
[root@Compro ~]# n1=${!n}
[root@Compro ~]# echo $n1
xiaomag
[root@Compro ~]# eval n3=\$$v1 第二種間接引用格式
[root@Compro ~]# echo $n3
xiaomag
===============================================================
eval命令
將會首先掃描命令行進行所有的置換,然後在執行該命令。
改名了適用於那些一次掃描無法實現其功能的變量,該命令對變量進行兩次掃描
示例:
[root@Compro ~]# cmd=whoami
[root@Compro ~]# echo $cmd
whoami
[root@Compro ~]# eval $cmd
root
=================================================================
創建臨時文件
mktemp命令 創建的臨時文件可避免衝突
mktemo 選項 格式filename.XXX X至少要出現三個
-d 創建臨時目錄
-p Dir 指明臨時文件所存放目錄位置
[root@Compro ~]# mktemp test.XXX XXX生成隨機字符
test.6Gk 執行結果
[root@Compro ~]# mktemp /tmp/test.XXX
/tmp/test.631
[root@Compro ~]# ll /tmp/test.631
-rw-------. 1 root root 0 8月 23 14:28 /tmp/test.631
================================================================
安裝複製文件
install命令:
install [選項] -t directory=目錄來源 將源文件所有參數複製到指定目錄
install [選項] -T 來源 directory 將目標文件視爲普通文件
install [選項] -d directory 創建空目錄
-m mode 默認755
-o owner
-g group
舉例:
[root@Compro ~]# install -m 700 -o hacker -g hacker file1 file2 將file複製到file2 並且帶有700的權限
rwx------. 1 hacker hacker 257 8月 23 20:50 file2 執行結果
[root@Compro ~]# install -m 700 -d /testdir/installdir 創建空目錄 給上700權限
[root@Compro ~]# ll /testdir
總用量 0
drwx------. 2 root root 6 8月 23 20:56 installdir 執行結果
=============================================================
bash如何展開命令行執行:
1 把命令行分成單個命令詞
2 展開別名
3 展開大括號中的聲明 ( {} )
4 展開波浪符聲明( ~ )
5 命令替換$() 和 ``
6 再次把命令行分成命令詞
7 展開文件通配(*、?、[abc]等等)
8 準備I/O重定向(< 、>)
9 運行命令
防止擴展:
單引號(')防止所有擴展
雙引號(")也防止所有擴展但是一下情況例外
$ (美元符號) 變量擴展
` (反引號) 命令替換
\ (反斜線) 禁止單個字符擴展
! (歎號) 歷史命令替換
反斜線(\)會使隨後的字符按願意解釋
bash的配置文件:按生效範圍劃分,存在兩類
全局配置:
/etc/profile
/etc/profile.d/*.sh
/etc/bashrc
個人配置:
~/.bash_profile
~/.bashrc
shell登錄兩種方式:
交互式登錄:
1 直接通過終端輸入帳號密碼登錄
2 使用 su - username 切換的用戶
執行順序:/etc/profile --> /etc/profile.d/*.sh --> ~/.bash_profile --> ~/.bashrc -->/etc/bashrc
非交互式登錄:
1 su username
2 圖形界面下打開的終端
3 執行腳本
執行順序:~/.bashrc --> /etc/bashrc --> /etc/profile.d/*.sh
profile爲交互式登錄的shell提供配置
全局:/etc/profile /etc/profile.d/*.sh
個人:~/.bash_profile
功能:用於定義環境變量 ; 運行命令或腳本
bashrc 爲非交互式和交互式登錄的shell提供配置
全局:/etc/bashrc
個人:~/.bashrc
功能:定義命令別名和函數 ; 定義本地變量
修改profile和bashrc文件後需要生效方法有兩種
重新啓動shell進程
. 或 source
bash 退出任務
保存在~/.bash_logout文件中(用戶)
在退出登錄shell時運行
可以用於:
創建自動備份
清楚臨時文件