小知識:
在bash環境中變量有各自的范圍,有些的變量無法超出自己本身的范圍,也無法更改自己,
或提升自己的能力范圍
用source命令執行腳本,會對里面的變量發生改變包括范圍
例:命令行中寫name=wang 腳本中寫name=xdg 先命令行,再腳本,最后命令行的順序依次執行
1.正常的執行腳本 ./file.sh
輸出的結果: wang xdg wang
2.用source執行腳本 source ./file.sh
輸出的結果: wang xdg xdg
常量的有效時間是等于進程的時間
例:name=xdg; (name=mage; echo $name; name=wang; echo $name); echo $name
結果:mage wang xdg
注:在括號或者是括號外的 ; 分號一定要注意!()表示的是開啟一個子進程,
并不在當前的bash中,如果在()里寫入exit命令,只會退出當前的(),而不會退出當前的腳本。
例:name=xdg; { name=mage; echo $name; name=wang; echo $name; }; echo $name
結果:mage wang wang
在{}里代表是一個匿名函數的形式,同樣注意;的位置,還有{}邊上的空格要有
里面修改了變量的值,同樣在外面也有效
編程語言:
低級:匯編
高級:
編譯:高級語言–>編譯器–>目標代碼
java,C#
解釋:高級語言–>解釋器–>機器代碼
shell, perl, python
格式要求:首行shebang機制
#!/bin/bash
#!/usr/bin/python
#!/usr/bin/perl
注:因為當前系統默認的為bash,所以可有可無,如果換了其它系統或環境
會導致運行出錯,當前系統用的語言不一定是bash,所有還是把當前的環境給寫出來。
shell腳本的用途有:
自動化常用命令
執行系統管理和故障排除
創建簡單的應用程序
處理文本或文件
運行腳本
給予執行權限,在命令行上指定腳本的絕對或相對路徑
直接運行解釋器,將腳本作為解釋器程序的參數運行
腳本測試
檢測腳本中的語法錯誤
bash -n /path/to/some_script
調試執行
bash -x /path/to/some_script
強類型:變量不經過強制轉換,它永遠是這個數據類型,不允許隱式的類型轉換。
一般定義變量時必須指定類型、參與運算必須符合類型要求;
調用未聲明變量會產生錯誤 如 java,c#
弱類型:語言的運行時會隱式做數據類型轉換。無須指定類型,默認均為字符型;
參與運算會自動進行隱式類型轉換;變量無須事先定義可直接調用
如:bash 不支持浮點數,php
根據變量的生效范圍等標準:
本地變量:生效范圍為當前shell進程;對當前shell之外的其它shell進程,
包括當前shell的子shell進程均無效
變量賦值:name=‘value’
可以使用引用value:
(1) 可以是直接字串:name=”root”
(2) 變量引用:name=”$USER”
(3) 命令引用:name=COMMAND
或 name=$(COMMAND)
變量引用:${name} $name
注:有些時候要括起來,例:顯示第10個數,不能寫成$10,會識別成$1+0
“”:弱引用,其中的變量引用會被替換為變量值
”:強引用,其中的變量引用不會被替換為變量值,而保持原字符串
顯示已定義的所有變量 :set
刪除變量: unset name
環境變量:生效范圍為當前shell進程及其子進程
變量聲明、賦值:
export name=VALUE
declare -x name=VALUE
變量引用:$name, ${name}
顯示所有環境變量:
env
printenv
export
declare -x
刪除變量: unset name
bash中內建的環境變量
PATH 命令執行查找路徑
SHELL 當前系統的shell
USER 當前系統的UID(名字)
UID 當前系統的UID (數字)
HOME 當前系統的家目錄
PWD 當前系統路徑
SHLVL 當前進程的深度(查看 pstree )
LANG 當前系統的語言和編碼 LANG=en_US.UTF-8
MAIL 當前用戶的郵件家目錄 MAIL=/var/spool/mail/root
HOSTNAME 當前系統的主機名
HISTSIZE 命令歷史的最大長度
_ 上個命令的最后一個字符串 (下劃線)
注:如果有參數就是最后一個參數,如果沒有則就是命令(最后一個字符串)
局部變量:生效范圍為當前shell進程中某代碼片斷(通常指函數)
位置變量:$1, $2, …來表示,用于讓腳本在腳本代碼 中調用通過命令行傳遞給它的參數
位置變量:在腳本代碼中調用通過命令行傳遞給腳本的參數
$1, $2, …:對應第1、第2等參數,
shift [n]換位置 注:就是把當前指向第一個數的指針,向后移動n位(這個是累加)
例:shift 2;shift 2; 這是移動了4位
$0: 命令本身 單單只是命令的本身,不帶有任何的參數
$*: 傳遞給腳本的所有參數,全部參數合為一個字符串
$@: 傳遞給腳本的所有參數,每個參數為獨立字符串
$#: 傳遞給腳本的參數的個數
注: $@ $* 只在被雙引號包起來的時候才會有差異,沒有””是沒有區別的
注: set — 清空所有位置變量參數
特殊變量:
$? 上個命令的執行的結果(正確執行 0 非正確執行 非0)
$$ 當前進程的PID 如:當前進程的父進程的PID: $PPID
$- 例:echo $- –> himBH
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
declare -r name
查看只讀變量:
readonly –p
bash自定義退出狀態碼
exit [n]:自定義退出狀態碼
注意:腳本中一旦遇到exit命令,腳本會立即終止;終止退出狀態取決于exit命令后面的數字
注意:如果未給腳本指定退出狀態碼,整個腳本的退出狀態碼取決于腳本中執行的最后一條命令的狀態碼
bash中的算術運算:help let
+, -, *, /, %取模(取余), **(乘方)
實現算術運算: 如: a=5 b=7 c
(1) let var=算術表達式
let c=a+b
(2) var=$[算術表達式]
c=$[a+b] 比如:echo $[a+b]
(3) var=$((算術表達式))
c=$((a+b)) 比如:echo $((a+b))
(4) var=$(expr arg1 arg2 arg3 …)
c=$(expr 2+3)
c=$(expr $a+$b)
注:如果單單的expr的寫法,在下面
(5) declare –i var = 數值
declare -i c=a+b
(6) echo ‘算術表達式’ | bc
echo $[a+b] | bc
echo 3+5 | bc
注:無法識別當中的變量
乘法符號有些場景中需要轉義,如*
注:1 expr 0 + 0 ——> echo $? ——> 1
注:0 + 0 之間必須要有空格表示出來,不然出錯,再運算結果為0的話,運行的狀態是有問題的(非0)
2 let i=0 echo $i 輸出結果為:0 —> 但是程序的運行的狀態 —> 是非0的
例:k=0;let k++;echo $? —>輸出的結果也是非0
k=0;let ++k;echo $? —>輸出的結果也是0
bash有內建的隨機數生成器:
$RANDOM(0-32767)
echo $[$RANDOM%50] :0-49之間隨機數
增強型賦值:
+=, -=, *=, /=, %=
let varOPERvalue
例如:let count+=3
自加3后自賦值
自增,自減:
let var+=1
let var++
let var-=1
let var-
短路運算
短路與
第一個為0,結果必定為0
第一個為1,第二個必須要參與運算
短路或
第一個為1,結果必定為1
第一個為0,第二個必須要參與運算
異或:^ 異或的兩個值,相同為假,不同為真
例:如何把兩個整數變量的值給調換,而且不用第三者。
a=10; b=6; a=$[a^b]; b=$[a^b]; a=$[a^b];
a 110011011 c 111001101
b 001010110 —> b 001010110 注:兩者的運算的結果
異或c 111001101 異或結果a 110011011
測試命令: 注意:EXPRESSION前后必須有空白字符,格式要求。
test EXPRESSION 不支持
注:有些變量的時候,須要引號引起來才能判斷出來
[root@centos7 ~]# aa=””
[root@centos7 ~]# echo $aa
[root@centos7 ~]# test $aa && echo true 為假
[root@centos7 ~]# test “$aa” && echo true 為假
[root@centos7 ~]# aa=” ”
[root@centos7 ~]# echo $aa
[root@centos7 ~]# test $aa && echo true 為假
[root@centos7 ~]# test “$aa” && echo true 為真
true
[ EXPRESSION ] 不支持,里面的 <,>都需要轉意
[root@centos7 ~]# unset a
[root@centos7 ~]# [ $a == “wang” ]
-bash: [: ==: unary operator expected 出錯信息
[root@centos7 ~]# [ “$a” == “wang” ] 必須引號引起來
[root@centos7 ~]#
例:有的地方會出來這種寫法: [ X$a == X”wang” ] 或 [ X”$a” == X”wang” ]
上面兩個都可以,第一個是,添加額外的字符,來判斷。
注: [ id ] && { a=10; echo $a; } || echo Hello 在測試的時候{}外是沒有;號的,并且{}里面的 空格 要有
[[ EXPRESSION ]] 支持正則表達式
根據退出狀態而定,命令可以有條件地運行
&& 代表條件性的AND THEN
|| 代表條件性的OR ELSE
-v VAR
變量VAR是否設置
數值測試:
-gt 是否大于
-ge 是否大于等于
-eq 是否等于
-ne 是否不等于
-lt 是否小于
-le 是否小于等于
字符串測試:
== 是否等于
> ascii碼是否大于ascii碼
< 是否小于
!= 是否不等于
=~ 左側字符串是否能夠被右側的PATTERN所匹配
注意: 此表達式一般用于[[ ]]中;擴展的正則表達式
[root@centos6 xdg]# [[ $sh =~ “.*.sh$” ]]
[root@centos6 xdg]# echo $?
1
注:在使用的時候必須要用[[]] 用到了正則表達式,中間的空格也不能少
例:[root@centos6 ~]# str=abc;[[ $str == “abc” ]] && echo tree
tree
[root@centos6 ~]# str=abc;[[ $str =~ “abc” ]] && echo tree
tree
[root@centos6 ~]# str=abc;[[ $str =~ “^a” ]] && echo tree
[root@centos6 ~]# str=abc;[[ $str =~ ^a ]] && echo tree
tree
-z “STRING“ 字符串是否為空,空為真,不空為假
[root@centos7 ~]# aa=xxx
[root@centos7 ~]# [ -z “$aa” ] && echo true 為假
[root@centos7 ~]# [ -z ‘$aa’ ] && echo true 為假
[root@centos7 ~]# aa=””
[root@centos7 ~]# [ -z ‘$aa’ ] && echo true 為假
[root@centos7 ~]# [ -z “$aa” ] && echo true 為真
true
-n “STRING“ 字符串是否不空,不空為真,空為假
注意:用于字符串比較時的用到的操作數都應該使用引號,如上test一樣
存在性測試
-a FILE:同-e
-e FILE: 文件存在性測試,存在為真,否則為假
存在性及類別測試
-b FILE:是否存在且為塊設備文件
-c FILE:是否存在且為字符設備文件
-d FILE:是否存在且為目錄文件
-f FILE:是否存在且為普通文件
-h FILE 或 -L FILE:存在且為符號鏈接文件
注:在判斷一個文件是否存在時,要先判斷它是否是一個符號鏈接文件
-p FILE:是否存在且為命名管道文件
-S FILE:是否存在且為套接字文件
文件權限測試: 測試文件,首先判斷是否是軟硬鏈接
-r FILE:是否存在且可讀
-w FILE: 是否存在且可寫
-x FILE: 是否存在且可執行
文件特殊權限測試:
-u FILE:是否存在且擁有suid權限
-g FILE:是否存在且擁有sgid權限
-k FILE:是否存在且擁有sticky權限
文件大小測試:
-s FILE: 是否存在,且非空
文件是否打開:
* -t fd: fd表示文件描述符是否已經打開且與某終端相關
-N FILE:文件自動上一次被讀取之后是否被修改過
-O FILE:當前有效用戶是否為文件屬主
-G FILE:當前有效用戶是否為文件屬組
雙目測試:
FILE1 -ef FILE2: FILE1與FILE2是否指向同一個設備上的相同inode
注:判斷的是否是一個硬連接
FILE1 -nt FILE2: FILE1是否新于FILE2(mtime)
FILE1 -ot FILE2: FILE1是否舊于FILE2
第一種方式:
COMMAND1 && COMMAND2 并且
COMMAND1 || COMMAND2 或者
! COMMAND 非
如:[[ -r FILE ]] && [[ -w FILE ]]
第二種方式:
EXPRESSION1 -a EXPRESSION2 并且
EXPRESSION1 -o EXPRESSION2 或者
! EXPRESSION 必須使用測試命令進行
使用read來把輸入值分配給一個或多個shell變量
-p 指定要顯示的提示
-s 靜默輸入,一般用于密碼
-n N 指定輸入的字符長度N
-d ‘字符’ 輸入結束符
-t N TIMEOUT為N秒
read 從標準輸入中讀取值,給每個單詞分配一個變量 所有剩余單詞都被分配給最后一個變量
read -p “Enter a filename: “ FILE
注:在shell腳本中,運行的優先級
把命令行分成單個命令詞
展開別名
展開大括號的聲明({})
展開波浪符聲明(~)
命令替換$() 和 “)
再次把命令行分成命令詞
展開文件通配(*、?、[abc]等等)
準備I/0重導向(<、>)
運行命令
反斜線(\)會使隨后的字符按原意解釋
$ echo Your cost: \$5.00
Your cost: $5.00
加引號來防止擴展
單引號(’)防止所有擴展
雙引號(”)也防止所有擴展,但是以下情況例外:
$(美元符號) - 變量擴展
`(反引號) - 命令替換
\(反斜線) - 禁止單個字符擴展
!(嘆號) - 歷史命令替換
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
profile類
按功能劃分,存在兩類:
profile類和bashrc類
profile類:為交互式登錄的shell提供配置
全局:/etc/profile, /etc/profile.d/*.sh
個人:~/.bash_profile
功用: (1) 用于定義環境變量
(2) 運行命令或腳本
bashrc類
bashrc類:為非交互式和交互式登錄的shell提供配置
全局:/etc/bashrc
個人:~/.bashrc
功用: (1) 定義命令別名和函數
(2) 定義本地變量
編輯配置文件生效
修改profile和bashrc文件后需生效
兩種方法: 1重新啟動shell進程
2 . 或source
例: . ~/.bashrc
bash退出任務
保存在~/.bash_logout文件中(用戶)在退出登錄shell時運行用于
創建自動備份
清除臨時文件
原創文章,作者:_xddggg,如若轉載,請注明出處:http://www.www58058.com/83951