shell腳本基礎
執行腳本的幾種方式 :
假如已經寫好一個腳本hello.sh
1.在編寫好的腳本目錄下執行./hello.sh
2.直接執行bash hello.sh,可以不用添加執行權限
3.把腳本放入環境變量$PATH的路徑中去
4.執行cat hello.sh |bash
5.以絕對路徑方式去運行
遠程主機的腳本在本機執行
遠程主機:
1.啟動httpd服務
2.cp hello.sh /var/www/html/
3.主機地址172.20.109.152
本地機:
[root@centos7 ~]#curl http://172.20.109.152/hello.sh | bash
% Total??? % Received % Xferd? Average Speed?? Time??? Time???? Time? Current
Dload? Upload?? Total?? Spent??? Left? Speed
100?? 356? 100?? 356??? 0???? 0? 58437????? 0 –:–:– –:–:– –:–:–? 115k
hello world!
shell腳本錯誤檢查
1.bash -n /path/to/hello.sh
這個只能檢查語法錯誤,但不能檢查命令錯誤
2.bash -x /path/to/hello.sh 調試執行,能查看腳本執行的過程
變量
定義變量:
1.如name=”wang zhe”,變量中含有空格,需要加“”號,否則,它會被當作一個命令去執行
例:
[root@centos7 data]#name=wang zhe
bash: zhe: command not found.
2.變量調用命令,name=`hostname`? name=`cat /etc/issue `里面定義的是整篇文件內容。
查看該變量echo “$name”,此時該變量需要加上“”號,這樣能保留文件的換行格式,否則會變成一行顯示。
例:定義name1=a,name3=$name1? 查看name3變量echo $name3,然后重新定義name1=b,再查看變量name3的結果
[root@centos7 data]#name1=a
[root@centos7 data]#name3=$name1
[root@centos7 data]#echo $name3
a
[root@centos7 data]#name1=b
[root@centos7 data]#echo $name3
a
結果,name3的結果并未隨著name1變量的改變而改變,其原理是,開始name1和name3同樣指向同一個變量a,name1重新指向了b,而name3還是指向a。
“`
bash變量的種類
局部變量:生效范圍只在當前shell進程;對當前shell之外的其它shell進程,包括當前shell下的子shell均無效.
環境(全局)變量:生效范圍為當前shell進程及其子進程
系統登陸時,系統運行了bash進程,在當前bash下再運行bash,他們的關系為父子進程
查看當前bash進程執行echo $$ ,查看父進程執行echo $ppid,查看父子進程執行pstree -p
[root@centos7 data]#echo $$
8192
[root@centos7 data]#bash
[root@centos7 data]#echo $$
8846
[root@centos7 data]#echo $PPID
8192
[root@centos7 data]#pstree -p
├─sshd(1041)─┬─sshd(1960)───bash(1972)
│??????????? ├─sshd(4019)───bash(4023)───man(6373)───less(6386)
│??????????? └─sshd(8188)───bash(8192)───bash(8846)───pstree(8905)
在局部變量下,父進程和子進程定義的變量,只能對各自當前shell有效。
例:在父進程定義一個變量name=a,然后進入子進程,執行echo $name
[root@centos7 data]#name=a
[root@centos7 data]#echo $name
a
[root@centos7 data]#bash
[root@centos7 data]#echo $name
說明父進程變量不能繼承給子進程。同理,子進程定義的變量也不能繼承給父進程,
而在全局變量,首先定義全局變量,export name=a 或者declare -x name=a ,全局變量父進程能把變量一直繼承給子進程,子子進程,定義的全局變量也能傳遞給腳本,腳本也是一個子進程,一直繼承下去。而子進程則不能繼承變量給父進程。
例:
[root@centos7 data]#export name=a
[root@centos7 data]#echo $name
a
[root@centos7 data]#bash
[root@centos7 data]#echo $name
a
查看全局變量:export或者declare -x 或者env或者printenv
刪除變量:unset=name
“`
$SHELVL和$_和$-變量
$SHELVL代表子進程嵌入的深度
例:
[root@centos7 data]#echo $SHLVL
1
[root@centos7 data]#bash
[root@centos7 data]#echo $SHLVL
2
$_代表引用最后一個參數
例:
[root@centos7 data]#echo a b c
a b c
[root@centos7 data]#echo $_
c
$-變量
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 個歷史命令
“`
只讀變量(常量)
只讀變量只能聲明,不能修改和刪除
設置:readonly name=a 或者declare -r name=a
[root@centos7 data]#set |grep name?? 查看自定義變量
_=name
name=a
要想刪除常量,需要退出當前進程。
顯示系統自帶的常量:declare -r或者readonly -p
“`
()的意義
()不影響當前shell環境,相當于開啟了一個臨時子進程,而子進程對父進程不產生影響
[root@centos7 data]#(umask 666;touch /data/f1)
[root@centos7 data]#ll /data/f1
———-. 1 root root 0 Apr 10 05:55 /data/f1
[root@centos7 data]#umask
0022
()對于變量
[root@centos7 data]#(name=wang;echo $name)
wang
[root@centos7 data]#echo $name
在子shell能看到變量,而在當前shell下變量為空
{}則對當前環境變量有影響,它和()的相同點是都是以一個整體去運行
[root@centos7 data]#{ name=wang;echo $name; }
wang
[root@centos7 data]#echo $name
wang
“`
“`
例:
[root@centos7 data]#x=1;echo “pid=$$”;(echo “subpid=$$”;echo “subx=$x”;x=2;echo “subx2=$x”);echo x=$x
pid=1972
subpid=1972
subx=1
subx2=2
x=
上述實驗說明()里的subx還是繼承了外面的x=1.說明括號生成的子shell和之前執行bash生成的子shell有點區別。
“`
位置參數
$1調取命令中的第一個參數
${10}第10個參數,不能寫成$10,它會被識別成$1和0
$* 傳遞給腳本的所有參數,全部參數合為一個字符串
$@ 傳遞給腳本的所有參數,每個參數為獨立字符串
$# 參數的個數
$0顯示命令本身
set –清空位置的所有參數
shift 逐個處理參數,shift 2 同時處理兩個參數
例:編輯腳本scp.sh
#!/bin/bash
#
#********************************************************************
#Author:??? ????????????wqf
#QQ:??????????????????? 88888888
#Date:????????????????? 2018-04-10
#FileName:???????????? scp.sh
#URL:?????????????????? http://www.magedu.com
#Description:????????? The test script
#Copyright (C):???????? 2018 All rights reserved
#********************************************************************
echo -e “\e[1;32mstart copy…\e[0m”
scp $* root@192.168.67.129:
echo -e “\e[1;32mcopy ended..\e[0m”
[root@centos6 data]#./scp.sh scp.sh
start copy…
root@192.168.67.129’s password:
scp.sh?????????????????????????????????????????????????????????????????? 100%? 434???? 0.4KB/s?? 00:00
copy ended..
“`
$*和$@的區別
[root@centos6 data]#vim file1.sh
#!/bin/bash
#
#********************************************************************
#Author:??????????????? wqf
#QQ:??????????????????? 88888888
#Date:????????????????? 2018-04-10
#FileName:???????????? file.sh
#URL:?????????????????? http://www.magedu.com
#Description:????????? The test script
#Copyright (C):???????? 2018 All rights reserved
#********************************************************************
echo “all arg are $*”
file2.sh “$*”
[root@centos6 data]#vim file2.sh
#!/bin/bash
#
#********************************************************************
#Author:??????????????? wqf
#QQ:??????????????????? 88888888
#Date:????????????????? 2018-04-10
#FileName:???????????? file2.sh
#URL:?????????????????? http://www.magedu.com
#Description:????????? The test script
#Copyright (C):???????? 2018 All rights reserved
#********************************************************************
echo “file2.sh:the first arg is $1”
[root@centos6 data]#./file.sh a b c
all arg are a b c
file2.sh:the first arg is a b c
結果$* 把a,b,c單個單獨的字符串當作一個整體,傳遞個腳本二
假若把腳本中的$*換成$@
#!/bin/bash
#
#********************************************************************
#Author:??????????????? wqf
#QQ:??????????????????? 88888888
#Date:????????????????? 2018-04-10
#FileName:???????????? file.sh
#URL:?????????????????? http://www.magedu.com
#Description:????????? The test script
#Copyright (C):???????? 2018 All rights reserved
#********************************************************************
echo “all arg are $*”
./file2.sh “$@”
[root@centos6 data]#./file.sh a b c
all arg are a b c
file2.sh:the first arg is a
$@則把a ,b,c當作一個單獨字符串,注意$@要加上“”號,
“`
$0 顯示命令本身
給腳本創建不同的軟鏈接,
#!/bin/bash
#
#********************************************************************
#Author:????????? ??????wqf
#QQ:??????????????????? 88888888
#Date:????????????????? 2018-04-10
#FileName:???????????? file.sh
#URL:?????????????????? http://www.magedu.com
#Description:????????? The test script
#Copyright (C):???????? 2018 All rights reserved
#********************************************************************
echo “the scripts name is $0”
[root@centos6 data]#./file.sh
the scripts name is ./file.sh
[root@centos6 data]#ln -s /data/file.sh link2.sh
[root@centos6 data]#ln -s /data/file.sh link1.sh
[root@centos6 data]#ll
total 52
lrwxrwxrwx. 1 root root??? 13 Apr 10 09:39 link1.sh -> /data/file.sh
lrwxrwxrwx. 1 root root??? 13 Apr 10 09:39 link2.sh -> /data/file.sh
[root@centos6 data]#./link1.sh
the scripts name is ./link1.sh
[root@centos6 data]#./link2.sh
the scripts name is ./link2.sh
以后可以根據軟鏈接的不同實現不同功能
“`
進程使退出狀態來報告成功或者失敗
- 0代表成功,1-255表示失敗
- $?變量保存最近的命令退出狀態,
例:
[root@centos6 data]#grep -q root /etc/passwd
[root@centos6 data]#echo $?
0
例:
[root@centos6 data]#ping -c2 192.168.67.129 &>/dev/null
[root@centos6 data]#echo $?
0
選項-c表示ping的次數
“`
退出狀態碼
bash自定義退出狀態碼
exit n :自定義退出狀態碼
注意:腳本中一旦遇到exit命令,腳本會立即終止;終止退出狀態取決于exit命令后面的數字
注意:如果未給腳本指定退出狀態碼,整個腳本的退出狀態碼取決于腳本中執行的最后一條命令的狀態碼
bash中的算術運算
let var=算術表達式
var=$[算術表達式]
var=$((算術表達式))
var=$(expr arg1 arg2 arg3)
declare -i 算術表達式
例:三種表達式
[root@centos6 data]#a=1
[root@centos6 data]#b=1
[root@centos6 data]#let c=a+b
[root@centos6 data]#echo $c
2
[root@centos6 data]#x=2
[root@centos6 data]#let x++
[root@centos6 data]#echo $x
3
[root@centos6 data]#let result=100%3
[root@centos6 data]#echo $result
1
[root@centos6 data]#c=$[a+b]
[root@centos6 data]#echo $c
2
[root@centos6 data]#c=$((a+b))
[root@centos6 data]#echo $c
2
“`
expr
[root@centos6 data]#expr 1 + 2
3
[root@centos6 data]#expr 1 \* 3
3
let 命令:
XOR 異或
0^1=1
1^0=1
0^0=0
1^1=0?????????? ###即相同為假,不同為真
例:
[root@centos6 data]#a=2
[root@centos6 data]#b=3
[root@centos6 data]#let c=a^b
[root@centos6 data]#echo $c
1
分別把a和b轉換成二進制
a:10
b:11?? 對位異或結果為01
c: 01
變量值互換
[root@centos6 data]#a=4
[root@centos6 data]#b=5
[root@centos6 data]#echo $a $b
4 5
[root@centos6 data]#a=$[a^b];b=$[a^b];a=$[a^b];echo $a $b
5 4
a異或b得到一個中間值a,中間值a異或b得到的是a賦值給b,中間值a異或被a賦值的b得到b,并且賦值給a,從而實現了對換
方法二
[root@centos6 data]#a=4
[root@centos6 data]#b=5
[root@centos6 data]#echo $a $b
4 5
[root@centos6 data]#tmp=$a
[root@centos6 data]#a=$b
[root@centos6 data]#b=$tmp
[root@centos6 data]#echo $a $b
5 4
“`
給字體生成隨機顏色
“`
COLOR=$[RANDOM%7+31]
[root@centos6 data]#COLOR=$[RANDOM%7+31];echo -e “\e[1;${COLOR}mhello\e[0m”
hello
[root@centos6 data]#COLOR=$[RANDOM%7+31];echo -e “\e[1;${COLOR}mhello\e[0m”
hello
“`
練習:
1、編寫腳本/root/bin/sumid.sh,計算/etc/passwd文件中的第10個用戶和第20用戶的ID之和
2、編寫腳本/root/bin/sumspace.sh,傳遞兩個文件路徑作為參數給腳本,計算這兩個文件中所有空白行之和
3、編寫腳本/root/bin/sumfile.sh,統計/etc, /var, /usr目錄中共有多少個一級子目錄和文件
腳本1:
#!/bin/bash
#
#********************************************************************
#Author:??????????????? wqf
#QQ:??????????????????? 88888888
#Date:????????????????? 2018-04-10
#FileName:???????????? sumid.sh
#URL:?????????????????? http://www.magedu.com
#Description:????????? The test script
#Copyright (C):???????? 2018 All rights reserved
#********************************************************************
uid1=`cat /etc/passwd |head -n$1 |tail -n1 |cut -d: -f3`
uid2=`cat /etc/passwd |head -n$2 |tail -n1 |cut -d: -f3`
sumid=$[uid1+uid2]
echo “$sumid”
腳本2
#!/bin/bash
#
#********************************************************************
#Author:??????????????? wqf
#QQ:??????????????????? 88888888
#Date:????????????????? 2018-04-10
#FileName:???????????? sumfile.sh
#URL:?????????????????? http://www.magedu.com
#Description:????????? The test script
#Copyright (C):???????? 2018 All rights reserved
#**************************************************
file1=`grep -c “^$” $1`
file2=`grep -c “^$” $2`
sumspace=$[file1+file2]
echo “the sumspace is $sumspace”
腳本3
filenum1=`ls -1 $1 | wc -l`
filenum2=`ls -1 $2 | wc -l`
filenum3=`ls -1 $3 | wc -l`
sumfile=$[filenum1+filenum2+filenum3]
echo “the sumfile is $sumfile”
[root@centos6 data]#./sumfile2.sh /etc /var /usr
the sumfile is 282
“`
條件測試
test
字符串比較? [ str1 = str2 ]
root@centos6 data]#str1=a
[root@centos6 data]#str2=b
[root@centos6 data]#test $str1 = $str2
[root@centos6 data]#echo $?
1
[root@centos6 data]#str1=b
[root@centos6 data]#test $str1 = $str2
[root@centos6 data]#echo $?
0
等價的寫法:#[ $str1 = $str2 ]
-n STRING
the length of STRING is nonzero
例:-n
[root@centos6 data]#var=b
[root@centos6 data]#[ $var ]
[root@centos6 data]#echo $?
0
-n 可以省略
[root@centos6 data]#[ “aa” ]
[root@centos6 data]#echo $?
0
[root@centos6 data]#[ “” ]
[root@centos6 data]#echo $?
1
注:判斷字符串是否為空還可以寫成[ x”$var” = “x” ]
數字大小比較eq、ne、 ge、 gt、 le、 lt
“`
“`
例:分區利用率報警
#!/bin/bash
#
#********************************************************************
#Author:??????????????? wqf
#QQ:??????????????????? 88888888
#Date:????????????????? 2018-04-10
#FileName:???????????? diskcheck.sh
#URL:?????????????????? http://www.magedu.com
#Description:????????? The test script
#Copyright (C):???????? 2018 All rights reserved
#********************************************************************
sd=`df |grep sd | tr -s ” ” % |cut -d% -f5 |sort -nr |head -n1`
[ “$sd” -ge 80 ] && echo “the disk will full” || echo “the disk is not full”
“`
判斷用戶輸入參數的個數
[ “$#” -ne 2 ] && echo “please input 2 arg” && exit
判斷用戶輸入的是否是數字
[[ ! “$1” =~ ^[0-9]+$ ]] && echo “$1 is not digit,please input digit” && exit
擴展正則表達式必須用[[ ]]
例:
#!/bin/bash
[ “$#” -ne 2 ] && echo “please input 2 arg” && exit
[[ ! “$1” =~ ^[0-9]+$ ]] && echo “$1 is not digit,please input digit” && exit
[[ ! “$2” =~ ^[0-9]+$ ]] && echo “$2 is not digit,please input digit” && exit
uid1=`cat /etc/passwd |head -n$1 |tail -n1 |cut -d: -f3`
uid2=`cat /etc/passwd |head -n$2 |tail -n1 |cut -d: -f3`
sum=$[uid1+uid2]
echo $sum
“`
在[ ]內變量用“”
[root@centos6 data]#[ $disk -ge 80 ] && echo warning
-bash: [: -ge: unary operator expected????? ###當變量值為空,變量沒加“”號,相當于[ -ge 80 ] 則是報語法錯誤
[root@centos6 data]#[ “$disk” -ge 80 ] && echo warning
-bash: [: : integer expression expected????? ###加上“”則報的是前面的變量必須是數字
創建用戶
#!/bin/bash
#
#********************************************************************
#Author:??????????????? wqf
#QQ:??????????????????? 88888888
#Date:????????????????? 2018-04-10
#FileName:???????????? createuser.sh
#URL:?????????????????? http://www.magedu.com
#Description:????????? The test script
#Copyright (C):???????? 2018 All rights reserved
#********************************************************************
id $1 &>/dev/null
[ “$?” -eq 0 ] && echo “$1 is exist” && exit
useradd “$1” && echo magedu |passwd –stdin “$1” &>/dev/null && echo “the user created successe”
“`
()與{}應用比較
語法:false || (echo cmd1; exit) 與false || { echo cmd1; exit; }
[root@centos6 data]#false || (echo cmd1;exit)
cmd1
[root@centos6 data]#false || { echo cmd1;exit; }
cmd1
logout
()執行命令是開啟了一個子進程,exit 是退出子進程
{}則是在當前進程執行命令,exit則是退出當前進程,從而退出當前終端
在腳本中想要退出來則使用{},
“`
判斷是否為文件夾和軟鏈接
-d判斷是否為文件夾
[root@centos7 ~]#[ -d /bin ] && echo true
true
[root@centos7 ~]#ll -d /bin
lrwxrwxrwx. 1 root root 7 Apr? 8 20:53 /bin -> usr/bin
此時判斷的是軟鏈接指向的文件夾本身
-L判斷是否為軟鏈接
[root@centos7 ~]#[ -L /bin ] && echo true
true
[root@centos7 ~]#[ -L /bin/ ] && echo true
此時/bin目錄后面不需要加/
判斷文件可讀可寫
-a 表示與,兩個條件都滿足為真
-o 表示或,滿足一個條件即為真
[wang@centos7 ~]$[ -r /etc/issue -a -w /etc/passwd ] && echo “read and write”
[wang@centos7 ~]$[ -r /etc/issue -o -w /etc/passwd ] && echo “read and write”
read and write
“`
“`
-v判斷變量是否設置
[wang@centos7 ~]$[ -v var ] && echo set || echo no set
no set
[wang@centos7 ~]$var=””
[wang@centos7 ~]$[ -v var ] && echo set || echo no set
set
注:var=””設置的變量為空,也算設置了變量
判斷變量是否為空字符串的幾種寫法
-z或者-n
[root@centos7 ~]#[ x”$var” = “x” ] && echo empty || echo “not empty”
not empty
[root@centos7 ~]#[ “$var” = “” ] && echo empty || echo “not empty”
not empty
[root@centos7 ~]#[ -z “var” ] && echo empty || echo “not empty”
not empty
[root@centos7 ~]#[ -n “var” ] && echo “not empty” || echo empty
not empty
“`
練習:
測試主機是否聯通,如果能聯通,則提示“主機可訪問” 否則提示“主機不可訪問”
#!/bin/bash
#
#********************************************************************
#Author:??????????????? wqf
#QQ:??????????????????? 88888888
#Date:????????????????? 2018-04-11
#FileName:???????????? hostping.sh
#URL:????????????????? ?http://www.magedu.com
#Description:????????? The test script
#Copyright (C):???????? 2018 All rights reserved
#********************************************************************
[[ ! “$1” =~ ^(([1-9]?[0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$ ]] && echo “please input the right ip” && exit
ping -c2 $1 &>/dev/null
[ $? -eq 0 ] && echo “the host is aviliable” || echo “the host is unreachable”
“`
“`
1、編寫腳本/bin/per.sh,判斷當前用戶對指定參數文件,是否不可讀并且不可寫
2、編寫腳本/root/bin/excute.sh ,判斷參數文件是否為sh后綴的普通文件,如果是,添加所有人可執行權限,否則提示用戶非腳本文件
3、編寫腳本/root/bin/nologin.sh和login.sh,實現禁止和充許普通用戶登錄系統
“`
“`
腳本一
#!/bin/bash
#
#********************************************************************
#Author:??????????????? wqf
#QQ:??????????????????? 88888888
#Date:????????????????? 2018-04-11
#FileName:???????????? per.sh
#URL:?????????????????? http://www.magedu.com
#Description:????????? The test script
#Copyright (C):???????? 2018 All rights reserved
#********************************************************************
[ ! -e $1 ] && echo “the file is not exist” && exit
[ -r “$1” -a -w “$1” ] && echo “r and w” || echo “not r and w”
“`
腳本二
“`
#!/bin/bash
#
#********************************************************************
#Author:??????????????? wqf
#QQ:??????????????????? 88888888
#Date:????????????????? 2018-04-11
#FileName:???????????? excute.sh
#URL:?????????????????? http://www.magedu.com
#Description:????????? The test script
#Copyright (C):???????? 2018 All rights reserved
#********************************************************************
[ ! -e $1 ] && echo “the file is not exist” && exit
[[ “$1” =~ .+\.sh$ ]] && chmod +x $1 || echo “the file is not the scripts”
“`
命令read
使用read命令來接受輸入
使用read來把輸入值分配給一個或多個shell變量
-p 指定要顯示的提示
-s 靜默輸入,一般用于密碼
-n N 指定輸入的字符長度N
-d ‘字符’ 輸入結束符
-t N TIMEOUT為N秒
read 從標準輸入中讀取值,給每個單詞分配一個變量
所有剩余單詞都被分配給最后一個變量
read -p “Enter a filename: “ FILE
例:read 批量賦值
[root@centos6 data]#read a b c
1 2 3
[root@centos6 data]#echo $a $b $c
1 2 3
[root@centos6 data]#cat >file
1 2 3
[root@centos6 data]#cat file
1 2 3
[root@centos6 data]#read a b c <file
[root@centos6 data]#echo $a $b $c
1 2 3
[root@centos6 data]#cat >file
22
33
44[root@centos6 data]#cat file
22
33
44[root@centos6 data]#read a b c <file
[root@centos6 data]#echo $a
22
[root@centos6 data]#echo $b
[root@centos6 data]#echo $c
批量賦值時,需要值用空格隔開,還可以read a b c <<<“1 2 3”
[root@centos6 data]#read a b c <<<“1 2 3”
[root@centos6 data]#echo $a $b $c
1 2 3
“`
系統中變量的特性
[root@centos6 data]#CMD=”hostname”
[root@centos6 data]#echo $CMD
hostname
[root@centos6 data]#$CMD
centos6.9
echo 打印時把hostname當作一個字符串
“`
[? ] 和[[ =~ ]]和[[ == ]]
“`
[ ]用于一般的字符串匹配
[[ =~ ]] 用擴展正則表達式
[[ == ]] 用類似于通配符
“`
判斷用戶輸入的變量$ANS,“yes”是否合適。合適的輸入方式為yes或者y ,且大小寫可以隨意組合
“`
[root@centos6 data]#ANS=Yes
[root@centos6 data]#[[ $ANS =~ ^([Yy]([Ee][Ss])?)$ ]]
[root@centos6 data]#echo $?
0
“`
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)執行腳本
(4)任何其它的bash實例
執行順序: ~/.bashrc –> /etc/bashrc –> /etc/profile.d/*.sh
“`
. 和source 與腳本執行./的區別
.和source 調用的是當前進程的變量,改變的是當前的環境。source+配置文件執行就是為了改變當前用戶的環境
./或者別的方式執行腳本都是調用子進程的變量,改變的是子進程的環境
“`
Bash 退出任務
保存在~/.bash_logout文件中(用戶)
在退出登錄shell時運行
用于
- 創建自動備份
- 清除臨時文件
文件查找和壓縮
locate命令
locate KEYWORD,locate 是基于索引搜索數據庫,搜索速度快,但不是實時搜索,及時更新數據庫執行updatedb
有用的選項
-i 不區分大小寫的搜索
-n N 只列舉前N個匹配項目
-r 使用正則表達式
示例
搜索名稱或路徑中帶有“conf”的文件
locate conf
使用Regex來搜索以“.conf”結尾的文件
locate -r ‘\.conf$’
“`
例:查找/etc目錄下以.conf結尾的文件
[root@centos7 data]#locate -r “^/etc/.*\.conf$”
/etc/GeoIP.conf
/etc/asound.conf
/etc/autofs.conf
/etc/autofs_ldap_auth.conf
/etc/brltty.conf
/etc/cgconfig.conf
/etc/cgrules.conf
/etc/cgsnapshot_blacklist.conf
“`
命令find
選項:
一、指定搜索層級
-maxdepth level最大搜索目錄深度,指定目錄等級為1
-mindepth level最小搜索目錄深度
-name “文件名稱”:支持使用glob
*, ?, [], [^]
-iname “文件名稱”:不區分字母大小寫
-inum n 按inode號查找
-samefile name 相同inode號的文件
-links n 鏈接數為n的文件
-regex “PATTERN”:以PATTERN匹配整個文件路徑字符串,而不僅僅是文件名稱
例:只查找第三層目錄下的文件
[root@centos6 ~]#find /etc -maxdepth 3 -mindepth 3 -name ifcfg-eth0
/etc/sysconfig/network-scripts/ifcfg-eth0
“
例:文件通配符匹配,但注意需要加上””
[root@centos6 data]#find -maxdepth 1 -name “*f*”
./sumfile.sh
./lost+found
./file
./sumfile2.sh
“`
“`
例:-inum
[root@centos6 data]#ls -i
1569793 aa?????? 18 createuser.sh?????? 16 diskcheck.sh?????? 12 file?????? 11 lost+found?????????? 13 sumfile2.sh?????? 15 sumfile.sh
[root@centos6 data]#find /data -inum 13
/data/sumfile2.sh
“`
“`
例:-samefile
[root@centos6 data]#ln file file_link
[root@centos6 data]#find /data -samefile file
/data/file_link
/data/file
“`
“`
例:-links
[root@centos6 data]#find /bin -links 2
/bin
/bin/ed
/bin/red
“`
“`
例:-regex
[root@centos6 data]#find /etc/ -regex “.*\.conf$”
/etc/gconf/2/evoldap.conf
/etc/asound.conf
/etc/security/pam_winbind.conf
/etc/security/namespace.conf
/etc/security/limits.d/90-nproc.conf
“““
二、根據所有者,所屬主查找
-user USERNAME:查找屬主為指定用戶(UID)的文件
-group GRPNAME: 查找屬組為指定組(GID)的文件
-uid UserID:查找屬主為指定的UID號的文件
-gid GroupID:查找屬組為指定的GID號的文件
-nouser:查找沒有屬主的文件
-nogroup:查找沒有屬組的文件
例:-user
[root@centos6 data]#find /home -user wang -name “*.sh” -ls
2097204??? 0 -rw-rw-r–?? 1 wang ????wang??????????? 0 Apr 12 08:48 /home/wang/file.sh
“`
例:-nouser
[root@centos6 data]#userdel zz
[root@centos6 data]#find /home -nouser -ls
2097196??? 4 drwx——?? 4 505????? 507????????? 4096 Apr 10 16:12 /home/zz
2097197??? 4 -rw-r–r–?? 1 505???? ?507?????????? 176 Mar 23? 2017 /home/zz/.bash_profile
2097198??? 4 -rw-r–r–?? 1 505????? 507?????????? 124 Mar 23? 2017
“`
例:-nouser 或者 -nogroup???? -o表示或,-a表示并且
[root@centos6 data]#find /home -nouser -o -nogroup -ls
2097205??? 4 drwx——?? 4 hh?? ????507????????? 4096 Apr 12 08:57 /home/hh
2097206??? 4 -rw-r–r–?? 1 hh?????? 507?????????? 176 Mar 23? 2017 /home/hh/.bash_profile
2097207??? 4 -rw-r–r–?? 1 hh?????? 507?????????? 124 Mar 23? 2017 /home/hh/.bashrc
“`
三、根據文件類型查找:
-type TYPE:
- f: 普通文件
- d: 目錄文件
- l: 符號鏈接文件
- s:套接字文件
- b: 塊設備文件
- c: 字符設備文件
- p: 管道文件
例:
[root@centos6 data]#find /dev -type b -ls
11084??? 0 brw-rw—-?? 1 root???? disk????????????? Apr 12 07:57 /dev/ram9
11073??? 0 brw-rw—-?? 1 root???? disk????????????? Apr 12 07:57 /dev/ram8
11062??? 0 brw-rw—-?? 1 root???? disk????????????? Apr 12 07:57 /dev/ram7
11051??? 0 brw-rw—-?? 1 root???? disk????????????? Apr 12 07:57 /dev/ram6
“`
“`
四、空文件或目錄
-empty
find /app -type d -empty
“`
“`
五、組合條件:
與:-a
或:-o
非:-not, !
“`
例:!或者not??? 查找目錄下非空的文件
[root@centos6 data]#find /data ! -empty -type f
/data/sumfile.sh
/data/file_link
/data/scp.sh
/data/diskcheck.sh
/data/file
“`
六、德·摩根定律:
(非 A) 或 (非 B) = 非(A 且 B)
(非 A) 且 (非 B) = 非(A 或 B)
示例:
!A -a !B = !(A -o B)
!A -o !B = !(A -a B)
“`
例:查找非空且非文件
[root@centos6 data]#find /data ! \( -empty -o -type f \)
/data
/data/a
/data/a/b
/data/a/b/c
“`
例:查找用戶名不是root,且文件名不以f開頭的文件
[root@centos6 data]#find /tmp ! -user root -a ! -name ‘f*’ -ls
1966179??? 0 -rw-rw-r–?? 1 wang???? wang??????????? 0 Apr 12 09:29 /tmp/aa
1966095??? 4 drwx——?? 2 gdm????? gdm????????? 4096 Apr? 8 13:15 /tmp/gconfd-gdm
1966105??? 4 drwx——?? 2 gdm????? gdm????????? 4096 Apr? 8 13:15 /tmp/pulse-Cw8Rk5C5uXxZ
“`
七、排除目錄
?示例:
查找/etc/下,除/etc/sane.d目錄的其它所有.conf后綴的文件
find /etc -path ‘/etc/sane.d’ -a –prune -o -name “*.conf”
查找/etc/下,除/etc/sane.d和/etc/fonts兩個目錄的所有.conf后綴的文件
find /etc \(–path ‘/etc/sane.d’ –o –path ’/etc/fonts’ \)
-a -prune –o -name “*.conf”
“`
八、根據文件大小來查找:
-size [+|-]#UNIT
常用單位:k, M, G,c(byte)
#UNIT: (#-1, #]
如:6k 表示(5k,6k]
-#UNIT:[0,#-1]
如:-6k 表示[0,5k]
+#UNIT:(#,∞)
如:+6k 表示(6k,∞)
“`
例:size
[root@centos6 data]#dd if=/dev/zero of=/data/f1 bs=1 count=1024
[root@centos6 data]#dd if=/dev/zero of=/data/f2 bs=1 count=1023
[root@centos6 data]#ll
total 12
-rw-r–r–. 1 root root 1024 Apr 12 09:49 f1
-rw-r–r–. 1 root root 1023 Apr 12 09:50 f2
-rw-r–r–. 1 root root??? 0 Apr 12 09:49 file1
-rw-r–r–. 1 root root??? 0 Apr 12 09:49 file2
-rw-r–r–. 1 root root?? 18 Apr 12 09:51 file3
[root@centos6 data]#find /data -size 1k
/data/f1
/data/file3
/data/f2
[root@centos6 data]#find /data -size 1024c
/data/f1
1k查找的范圍為(1k-1,1k]即(0,1k]
1024字節查找的范圍為(1024-1,1024c]即(1023,1024c]
“`
例:-size
[root@centos6 data]#find /data -size -1024c
[root@centos6 data]#find -size -1024c -ls
15??? 4 -rwxr-xr-x?? 1 root???? root????????? 346 Apr 13 19:50 ./hehe.sh
19??? 4 -rwxr-xr-x?? 1 root???? root????????? 610 Apr 14 11:11 ./ping.sh
11??? 0 ———- ??2 root???? root??????????? 0 Apr 14 15:01 ./link
1569794??? 0 -rw-r–r–?? 1 root???? root??????????? 0 Apr 14 14:57 ./aa/file
17??? 4 -rwxr-xr-x?? 1 root???? root????????? 511 Apr 14 08:48 ./disk.sh
14??? 4 -rwxr-xr-x?? 1 root???? root????????? 454 Apr 13 19:04 ./cp.sh
16??? 4 -rwxr-xr-x?? 1 root???? root????????? 480 Apr 13 20:33 ./sumid.sh
18??? 0 -rw-r–r–?? 1 root???? root??????????? 0 Apr 14 14:34 ./.sh
11??? 0 ———-?? 2 root???? root??????????? 0 Apr 14 15:01 ./file
13??? 0 -rw-r–r–?? 1 root???? root??????????? 0 Apr 14 14:30 ./ABC
20??? 4 -rwxr-xr-x?? 1 root???? root????????? 485 Apr 14 11:47 ./read.sh
22??? 4 -rw-r–r–?? 1 root???? root???????? 1023 Apr 14 15:13 ./f2
-1024c查找的范圍[0,1024c-1]即[0,1023c]
例:
[root@centos6 data]#find /data -size +1023c
/data
/data/f1
查找范圍(1023,∞)
“`
九、根據時間戳:
以“天”為單位;
-atime [+|-]#,
#: [#,#+1)
+#: [#+1,∞]
-#: [0,#)
-mtime
-ctime
以“分鐘”為單位:
-amin
-mmin
-cmin
“`
例:查找一分鐘修改的文件
[root@centos7 data]#useradd feng
[root@centos7 data]#find /etc -mmin -1
/etc
/etc/resolv.conf
/etc/group
/etc/gshadow
/etc/passwd
/etc/shadow
/etc/tuned/active_profile
/etc/cups
“`
十、MODE: 精確權限匹配
/MODE:任何一類(u,g,o)對象的權限中只要能一位匹配即可,或關系,+ 從centos7開始淘汰
-MODE:每一類對象都必須同時擁有指定權限,與關系
0 表示不關注
- find -perm 755 會匹配權限模式恰好是755的文件
- 只要當任意人有寫權限時,find -perm +222就會匹配
- 只有當每個人都有寫權限時,find -perm -222才會匹配
- 只有當其它人(other)有寫權限時,find -perm -002才會匹配
“`
例:-MODE表示模糊匹配,只要包含指定的權限就可以匹配
[root@centos6 data]#chmod 777 file1
[root@centos6 data]#find -perm -666
./file1
666轉換成二進制為110110110 其中1表示關心,需要檢查,則該位需要有權限才能匹配,0則表示不關心
“`
十一、處理動作
-print:默認的處理動作,顯示至屏幕
-ls:類似于對查找到的文件執行“ls -l”命令
-delete:刪除查找到的文件
-fls file:查找到的所有文件的長格式信息保存至指定文件中
-ok COMMAND {} \; 對查找到的每個文件執行由COMMAND指定的命令,對于每個文件執行命令之前,都會交互式要求用戶確認
-exec COMMAND {} \; 對查找到的每個文件執行由COMMAND指定的命令
{}: 用于引用查找到的文件名稱自身
find傳遞查找到的文件至后面指定的命令時,查找到所有符合條件的文件一次性傳遞給后面的命令
[root@centos6 data]#find -perm -222 -fls find.log1
等價于find -perm -222 ls > find.log
例:-ok
[root@centos6 data]#find -name “f*” -ok rm {} \;
< rm … ./file2 > ?
< rm … ./file4 > ?
< rm … ./f1 > ? y
{}代表匹配到的所有文件
find -name “f*” -exec rm {} \;?? -exec表示批量執行
例:查找文件并批量改名
[root@centos6 data]#touch file{1..10}
[root@centos6 data]#ls
file1? file10? file2? file3? file4? file5? file6? file7? file8? file9
[root@centos6 data]#find /data -name “file*” -exec mv {} {}.bak \;
[root@centos6 data]#ls
file10.bak? file2.bak? file4.bak? file6.bak? file8.bak
file1.bak?? file3.bak? file5.bak? file7.bak? file9.bak
“`
參數替換xargs
1.由于很多命令不支持管道|來傳遞參數,而日常工作中有這個必要,所以就有了xargs命令
2.xargs用于產生某個命令的參數,xargs 可以讀入 stdin 的數據,并且以空格符或回車符將 stdin 的數據分隔成為arguments
3.注意:文件名或者是其他意義的名詞內含有空格符的情況
有些命令不能接受過多參數,命令執行可能會失敗,xargs可以解決
示例:
ls f* |xargs rm
find /sbin -perm +700 |ls -l 這個命令是錯誤的
find /sbin -perm +7000 | xargs ls –l
find和xargs格式:find | xargs COMMAND
echo file{1..6666666} |xargs -n10 touch?? -n10表示每次處理10個
“`
find示例
1.備份配置文件,添加.orig這個擴展名
find -name “*.conf” -exec cp {} {}.orig \;
2.提示刪除存在時間超過3天以上的joe的臨時文件
find /tmp -ctime +3 -user joe -ok rm {} \;
3.在主目錄中尋找可被其它用戶寫入的文件
find ~ -perm -002 -exec chmod o-w {} \;
4.查找/data下的權限為644,后綴為sh的普通文件,增加執行權限
find /data –type f -perm 644 -name “*.sh” –exec chmod 755 {} \;
5.查看/home的目錄
find /home –type d -ls
“`
練習
?1、查找/var目錄下屬主為root,且屬組為mail的所有文件
[root@centos6 mail]#find /var -user root -a -group mail -ls
787624??? 4 drwxrwxr-x?? 2 root ????mail???????? 4096 Apr 12 08:57 /var/spool/mail
?2、查找/var目錄下不屬于root、lp、gdm的所有文件
[root@centos6 mail]#find /var ! \( -user root -o -user lp -o -user gdm \) -type f -ls
927032??? 4 -rw——-?? 1 rpc????? rpc?????????? 164 Apr 12 07:56 /var/cache/rpcbind/portmap.xdr
?3、查找/var目錄下最近一周內其內容修改過,同時屬主不為root,也不是postfix的文件
[root@centos6 mail]#find /var -mtime -7 ! \( -user root -o -user postfix \) -type f -ls
/var/spool/mail/hehe
786814??? 0 -rw-rw—-?? 1 bb?????? mail??????????? 0 Apr 10 15:53 /var/spool/mail/bb
786810??? 0 -rw-rw—-?? 1 hh?????? mail??????????? 0 Apr 12 08:57 /var/spool/mail/hh
?4、查找當前系統上沒有屬主或屬組,且最近一個周內曾被訪問過的文件
[root@centos6 mail]#find? -nouser -o -nogroup -atime -7
./hh
./zz
?5、查找/etc目錄下大于1M且類型為普通文件的所有文件
[root@centos6 data]#find /etc -size +1M -type f -ls
1706172 2176 -rw-r–r–?? 1 root???? root????? 2225495 Apr? 8 12:37 /etc/gconf/gconf.xml.defaults/%gconf-tree.xml
1705869 8280 -rw-r–r–?? 1 root???? root????? 8477071 Apr? 8 12:36
?6、查找/etc目錄下所有用戶都沒有寫權限的文件
[root@centos6 ~]#find /etc ! -perm /222
/etc/gshadow
/etc/ld.so.conf.d/kernel-2.6.32-696.el6.x86_64.conf
/etc/rc.d/init.d/lvm2-lvmetad
/etc/rc.d/init.d/blk-availability
/etc/rc.d/init.d/lvm2-monitor
/etc/shadow-
?7、查找/etc目錄下至少有一類用戶沒有執行權限的文件
[root@centos6 ~]#find /etc ! -perm -111 -ls
?8、查找/etc/init.d目錄下,所有用戶都有執行權限,且其它用戶有寫權限的文件
[root@centos6 ~]#find /etc/init.d/ -perm -111 -perm -002 -ls
1707849??? 0 -r-x–x-wx?? 1 root???? root??????????? 0 Apr 12 12:40 /etc/init.d/aa
“`
?
?
?
?
文本處理工具sed
用法:
sed [option]… ‘script’ inputfile…
常用選項:
-n:不輸出模式空間內容到屏幕,即不自動打印
-e: 多點編輯
-f:/PATH/SCRIPT_FILE: 從指定文件中讀取編輯腳本
-r: 支持使用擴展正則表達式
-i.bak: 備份文件并原處編輯
“`
地址定界:
(1) 不給地址:對全文進行處理
(2) 單地址:
#: 指定的行,$:最后一行
/pattern/:被此處模式所能夠匹配到的每一行
(3) 地址范圍:
#,#
#,+#
/pat1/,/pat2/
#,/pat1/
(4) ~:步進
1~2 奇數行
2~2 偶數行
“`
編輯命令:
d: 刪除模式空間匹配的行,并立即啟用下一輪循環
p:打印當前模式空間內容,追加到默認輸出之后
a [\]text:在指定行后面追加文本
支持使用\n實現多行追加
i [\]text:在行前面插入文本
c [\]text:替換行為單行或多行文本
w /path/somefile: 保存模式匹配的行至指定文件
r /path/somefile:讀取指定文件的文本至模式空間中
匹配到的行后
=: 為模式空間中的行打印行號
!:模式空間中匹配行取反處理
“`
例:只顯示第二行
[root@centos7 data]#ifconfig ens33 |sed -n ‘2p’
inet 192.168.67.129? netmask 255.255.255.0? broadcast 192.168.67.255
“`
例:顯示以root開頭的行
[root@centos7 data]#sed -n ‘/^root/p’ /etc/passwd
root:x:0:0:root:/root:/bin/bash
“`
例:顯示以w字母開頭行到以s開頭的結尾行
[root@centos7 data]#sed -n ‘/^w/,/^s/p’ /etc/passwd
wang:x:1000:1000:wang:/home/wang:/bin/bash
bash:x:1001:1001::/home/bash:/sbin/nologin
testbash:x:1002:1002::/home/testbash:/sbin/nologin
basher:x:1003:1003::/home/basher:/sbin/nologin
sh:x:1004:1004::/home/sh:/sbin/nologin
“`
例:打印奇數行
[root@centos7 data]#seq 10 >f1
[root@centos7 data]#sed -n ‘1~2p’ f1
1
3
5
7
9
“`
例:多點編輯-e
[root@centos7 data]#seq 10 >f1
[root@centos7 data]#sed -n -e ‘3p’ -e ‘6p’ f1
3
6
“`
例:-f
[root@centos7 data]#cat? >sedscripts.txt
1~2p
[root@centos7 data]#sed -n -f sedscripts.txt f1
1
3
5
7
9
“`
例:編輯命令d刪除
[root@centos7 data]#sed ‘2d’ f1?????? ###刪除第二行
1
3
4
5
6
7
8
9
10
[root@centos7 data]#sed ‘2!d’ f1????? ###刪除除了第二行以外的行
2
“`
例:= 打印行號
[root@centos7 data]#sed -n ‘/root/=’ /etc/passwd
1
10
“`
例:編輯命令a追加 -i.bak編輯并且備份
[root@centos7 ~]#[root@centos7 ~]# sed -i.bak ‘/functions/aalias rm=”mv -t”‘
“`
例:a 追加的內容中含有空格? -i在前面插入內容
[root@centos6 data]#sed ‘2,5a\?? ===’ file
1
2
===
3
===
4
===
5
===
6
7
8
9
10
“`
例:c
[root@centos6 data]#sed ‘2,5c\? ===’ file
1
===
6
7
8
9
10
“`
例:w保存內容到file文件中
[root@centos7 ~]#sed ‘2,6w file’ /etc/passwd
[root@centos7 ~]#cat file
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
“`
例:-r
[root@centos7 ~]#cat >f1
alias ll=”ls -l”
alias p=”pwd”
[root@centos7 ~]#sed ‘/Source/r f1′ .bashrc
# .bashrc
# User specific aliases and functions
alias rm=”mv -t /data”
alias cp=’cp -i’
mv=”mv -i”
# Source global definitions
alias ll=”ls -l”
alias p=”pwd”
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
“`
例:取ip地址
[root@centos6 ~]#ifconfig eth0 |sed -n ‘2p’ | sed -r ‘s@.*inet addr:(.*) Bcast.*@\1@’
192.168.67.128
[root@centos6 ~]#ifconfig eth0 |sed -n ‘2p’ |sed -r ‘s/(.*addr:)(.*) (Bcast.*)/\2/’
192.168.67.128
[root@centos7 ~]#ifconfig ens33 | sed -r ‘2!d;s/(.*inet )(.*)( netmask.*)/\2/’
192.168.67.130
[root@centos7 ~]#ifconfig ens33 | sed -n ‘2p’ | sed -r -e ‘s/.*inet //’ -e ‘s/ netmask.*//’
192.168.67.130
“`
例:取dirname
[root@centos6 ~]#echo “/etc/sysconfig/network” |sed -r ‘s/(.*\/)([^/]+\/?)/\1/’
/etc/sysconfig/
本文來自投稿,不代表Linux運維部落立場,如若轉載,請注明出處:http://www.www58058.com/96099