循環
for循環
通過使用一個變量去遍歷給定列表中的每個元素,在每次變量賦值時執行一次循環體,直至賦值完成所有元素退出循環
格式1
[java] view plain copyfor ((i=0;i《10;i++))
do
。。。
Done
格式2
[java] view plain copyfor i in 0 1 2 3 4 5 6 7 8 9
do
。。。
Done
格式3
[java] view plain copyfor i in {0..9}
do
。。。
done
注意:for i in {0..9} 等于for i in {0..9..1} , 第三個參數為跨步。
例如:
{0..9..2} 表示 0,2,4,6,8
while循環
適用于循環次數未知,或不便用for直接生成較大的列表時
格式:
[java] view plain copywhile 測試條件
do
循環體
done
如果測試條件為“真”,則進入循環,測試條件為假,則退出循環。
打印結果為0~9.
循環控制
循環控制命令——break
break命令是在處理過程中跳出循環的一種簡單方法,可以使用break命令退出任何類型的循環,包括while循環和for循環
循環控制命令——continue
continue命令是一種提前停止循環內命令,而不完全終止循環的方法,這就需要在循環內設置shell不執行命令的條件
條件
bash條件測試
格式:
[java] view plain copytest EXPR
[ EXPR ]:注意中括號和表達式之間的空格
整型測試:
-gt:大于:
-lt:小于
-ge:大于等于
-le:小于等于
-eq:等于
-ne:不等于
例如[ $num1 -gt $num2 ]或者test $num1 -gt $num2
字符串測試:
=:等于,例如判斷變量是否為空 [ “$str” = “” ] 或者[ -z $str ]
!=:不等于
判斷
if判斷:
單分支
[java] view plain copy if 測試條件;then
選擇分支
fi
雙分支
[java] view plain copyif 測試條件
then
選擇分支1
else
選擇分支2
fi
多分支
[java] view plain copyif 條件1; then
分支1
elif 條件2; then
分支2
elif 條件3; then
分支3
。。。
else
分支n
i
雙分支示例:
Case判斷
有多個測試條件時,case語句會使得語法結構更清晰
格式:
[java] view plain copycase 變量引用 in
PATTERN1)
分支1
;;
PATTERN2)
分支2
;;
。。。
*)
分支n
;;
esac
PATTERN :類同于文件名通配機制,但支持使用|表示或者
a|b:a或者b
*:匹配任意長度的任意字符
?:匹配任意單個字符
[a-z]:指定范圍內的任意單個字符
示例:
算術運算
[java] view plain copylet varName=算術表達式
varName=$[算術表達式]
varName=$((算術表達式))
varName=`expr $num1 + $num2`
使用這種格式要注意兩個數字和+號中間要有空格。
示例:
邏輯運算符
if [ 條件A && 條件B ] 在shell中怎么寫?
if [ 條件A && 條件B ];then 是不對的
解決方法:
(1)需要用到shell中的邏輯操作符
-a 與
-o 或
! 非
如if [ 條件A -a 條件B ]
(2)if [ 條件A ] && [條件B ]
(3)if((A&&B))
(4)if [[ A&&B ]]
自定義函數
格式:
[java] view plain copyfunction 函數名(){
。。。
}
引用自定義函數文件時,使用source func.sh
有利于代碼的重用性
函數傳遞參數(可以使用類似于Java中的args,args[1]代表Shell中的$1)
函數的返回值,只能是數字
read
read命令接收標準輸入(鍵盤)的輸入,或者其他文件描述符的輸入。得到輸入后,read命令將數據放入一個標準變量中。
格式
[java] view plain copyread VAR_NAME
read如果后面不指定變量,那么read命令會將接收到的數據放置在環境變量REPLY中
[java] view plain copy#表示輸入時的提示字符串:
read -p “Enter your name:” VAR_NAME
[java] view plain copy# -t表示輸入等待的時間
read -t 5 -p “enter your name:” VAR_NAME
[java] view plain copy# -s 表示安全輸入,鍵入密碼時不會顯示
read -s -p “Enter your password: ” pass
declare
用來限定變量的屬性
-r 只讀
-i 整數:某些算術計算允許在被聲明為整數的變量中完成,而不需要特別使用expr或let來完成。
-a 數組
示例:
字符串操作
獲取長度:
[java] view plain copy${#VAR_NAME}
字符串截取
[java] view plain copy${variable:offset:length}或者${variable:offset}
取尾部的指定個數的字符
[java] view plain copy${variable: -length}:注意冒號后面有空格
大小寫轉換
小--》大:
[java] view plain copy${variable^^}
大--》小:
[java] view plain copy${variable,,}
示例:
數組
定義:declare -a:表示定義普通數組
特點
支持稀疏格式
僅支持一維數組
數組賦值方式
一次對一個元素賦值a[0]=$RANDOM
一次對多個元素賦值a=(a b c d)
按索引進行賦值a=([0]=a [3]=b [1]=c)
使用read命令read -a ARRAY_NAME查看元素
[java] view plain copy${ARRAY[index]}:查看數組指定角標的元素
${ARRAY}:查看數組的第一個元素
${ARRAY[*]}或者${ARRAY[@]}:查看數組的所有元素
獲取數組的長度
[java] view plain copy${#ARRAY[*]}
${#ARRAY[@]}
獲取數組內元素的長度
[java] view plain copy${#ARRAY[0]}
注意:${#ARRAY[0]}表示獲取數組中的第一個元素的長度,等于${#ARRAY}
從數組中獲取某一片段之內的元素(操作類似于字符串操作)
格式:
[java] view plain copy${ARRAY[@]:offset:length}
offset:偏移的元素個數
length:取出的元素的個數
${ARRAY[@]:offset:length}:取出偏移量后的指定個數的元素
${ARRAY[@]:offset}:取出數組中偏移量后的所有元素
數組刪除元素:
[java] view plain copyunset ARRAY[index]
示例:
其他命令
date
顯示當前時間
格式化輸出 +%Y-%m-%d
格式%s表示自1970-01-01 00:00:00以來的秒數
指定時間輸出 --date=‘2009-01-01 11:11:11’
指定時間輸出 --date=‘3 days ago’ (3天之前,3天之后可以用-3)
示例:
后臺運行腳本
在腳本后面加一個&
[java] view plain copytest.sh &
這樣的話雖然可以在后臺運行,但是當用戶注銷(logout)或者網絡斷開時,終端會收到Linux HUP信號(hangup)信號從而關閉其所有子進程
nohup命令
不掛斷的運行命令,忽略所有掛斷(hangup)信號
[java] view plain copynohup test.sh &
nohup會忽略進程的hangup掛斷信號,所以關閉當前會話窗口不會停止這個進程的執行。
nohup會在當前執行的目錄生成一個nohup.out日志文件
標準輸入、輸出、錯誤、重定向
標準輸入、輸出、錯誤可以使用文件描述符0、1、2引用
使用重定向可以把信息重定向到其他位置
ls 》file 或者 ls 1》file(ls 》》file)
lk 2》file(lk是一個錯誤命令)
ls 》file 2》&1
ls 》 /dev/null(把輸出信息重定向到無底洞)
例子:
[java] view plain copycommand 》/dev/null 2》&1
Crontab定時器
linux下的定時任務
編輯使用crontab -e
一共6列,分別是:分 時 日 月 周 命令
查看crontab執行日志
[java] view plain copytail -f /var/log/cron
必須打開rsyslog服務cron文件中才會有執行日志(service rsyslog status)
[java] view plain copytail -f /var/spool/mail/root(查看crontab最近的執行情況)
查看cron服務狀態
[java] view plain copyservice crond status
啟動cron服務
[java] view plain copyservice crond start
小結及示例:
基本格式 :
* * * * * command
分 時 日 月 周 命令
第1列表示分鐘1~59 每分鐘用*或者 */1表示
第2列表示小時1~23(0表示0點)
第3列表示日期1~31
第4列表示月份1~12
第5列標識號星期0~6(0表示星期天)
第6列要運行的命令
crontab文件的一些例子:
30 21 * * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每晚的21:30重啟apache。
45 4 1,10,22 * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每月1、10、22日的4 : 45重啟apache。
10 1 * * 6,0 /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每周六、周日的1 : 10重啟apache。
0,30 18-23 * * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示在每天18 : 00至23 : 00之間每隔30分鐘重啟apache。
0 23 * * 6 /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每星期六的11 : 00 pm重啟apache。
* */1 * * * /usr/local/etc/rc.d/lighttpd restart
每一小時重啟apache
* 23-7/1 * * * /usr/local/etc/rc.d/lighttpd restart
晚上11點到早上7點之間,每隔一小時重啟apache
0 11 4 * mon-wed /usr/local/etc/rc.d/lighttpd restart
每月的4號與每周一到周三的11點重啟apache
0 4 1 jan * /usr/local/etc/rc.d/lighttpd restart
一月一號的4點重啟apache
ps和jps
ps:用來顯示進程的相關信息
ps顯示當前shell啟動的所有進程
ps -e顯示系統中所有進程
ps -ef|grep java
jps:類似linux的ps命令,不同的是ps是用來顯示所有進程,而jps只顯示java進程,準確的說是顯示當前用戶已啟動的部分java進程信息,信息包括進程號和簡短的進程command。
問題:某個java進程已經啟動,用jps卻顯示不了該進程進程號,使用ps -ef|grep java卻可以看到?
java程序啟動后,默認(請注意是默認)會在/tmp/hsperfdata_userName目錄下以該進程的id為文件名新建文件,并在該文件中存儲jvm運行的相關信息,其中的userName為當前的用戶名,/tmp/hsperfdata_userName目錄會存放該用戶所有已經啟動的java進程信息。而jps、jconsole、jvisualvm等工具的數據來源就是這個文件(/tmp/hsperfdata_userName/pid)。所以當該文件不存在或是無法讀取時就會出現jps無法查看該進程號。
原因:1,磁盤讀寫、目錄權限問題。2,臨時文件丟失,被刪除或是定期清理。3,java進程信息文件存儲地址被設置,不在/tmp目錄下
登錄Shell和交互shell
交互式的:顧名思義,這種shell中的命令時由用戶從鍵盤交互式地輸入的,運行的結果也能夠輸出到終端顯示給用戶看。
非交互式的:這種shell可能由某些自動化過程啟動,不能直接從請求用戶的輸入,也不能直接輸出結果給終端用戶看。輸出最好寫到文件。比如使用Shell腳本。
登錄式:意思是這種是在某用戶由/bin/login登陸進系統后啟動的shell,跟這個用戶綁定。這個shell是用戶登陸后啟動的第一個進程。login進程在啟動shell時傳遞第0個參數指明shell的名字,該參數第一個字符為“-”,指明這是一個login shell。比如對bash而言,啟動參數為“-bash”。
非登錄式:不需login而由某些程序啟動的shell。傳遞給shell的參數,是沒有‘-’前綴的。還以Bash為例,當以非login方式啟動時,它會調用~/.bashrc,隨后~/.bashrc中調用/etc/bashrc,最后/etc/bashrc調用所有/etc/profile.d目錄下的腳本。
一旦打開一個交互式login shell,或者以--login選項登錄的非交互式shell,都會首先加載并執行/etc/profile中的命令,然后再依次加載~/.bash_profile, ~/.bash_login, 和~/.profile中的命令。
當bash以login shell啟動時,它會執行/etc/profile中的命令,然后/etc/profile調用/etc/profile.d目錄下的所有腳本;然后執行~/.bash_profile,~/.bash_profile調用~/.bashrc,最后~/.bashrc又調用/etc/bashrc。要識別一個shell是否為login shell,只需在該shell下執行echo $0。
注意: /etc/profile中的設置只對Login Shell生效,而crontab運行腳本的shell環境是non-login的,不會加載/etc/profile的設置。
評論