接上節繼續,
1. 從鍵盤讀取輸入內容
#!/bin/bash read -p 'please input something:' input echo 'your input:' $input
運行效果:
./read1.sh please input something:123 your input: 123
2. while循環及case分支
#!/bin/bash printf '\nplease input a number or character, press "q" or "Q" to quit:\n' while true do read reply case $reply in q|Q) echo 'bye!'; break;; #結束循環 [A-Za-z]*) echo 'you input a character:' $reply;; #如果輸入的是純英文字符 [0-9]*) echo 'you input a number:' $reply;; #如果輸入的是純數字 esac printf 'please go on ...\n' done
運行效果:
./read1.sh please input a number or character, press "q" or "Q" to quit: 123 you input a number: 123 please go on ... qwe you input a character: qwe please go on ... Q bye!
3. 文件操作相關
3.1 文件權限及所有者
ll (2個小寫字母L)用于列出當前目錄的所有文件(及目錄)詳細信息
[deploy@deploy myservice]$ ll total 4 drwxrwxr-x. 2 deploy deploy 6 Jan 21 17:10 a -rw-r--r--. 1 root root 40 Jan 21 14:41 test.txt
解讀下這些輸出,最開始的10個字符,拆分一下,其格式為:
類型(1位) 所屬用戶權限(3位) 所屬用戶組權限(3位) 其它組權限(3位)
所以:
d rwx rwx r-x 表示這是一個目錄(第1位是d, Directory的首字母),然后所屬用戶有讀(r,Read的首字母)、寫(w,Write的首字母)、執行(x,代表eXecute)權限,所屬用戶組也同樣具有所有權限,其它用戶組具有讀、執行權限。
- rw- r-- r-- 表示這是一個普通文件(第1位是-,表示普通文件),然后所屬用戶有read、write權限,所屬用戶組及其它組只能讀。
注:第1位,除了d及-外,還有l表示link,說明這是符號鏈接,另外b表示塊(block)設備,c表示字符(character)設備
繼續看后面的輸出,后面的二個字符串,即 deploy deploy 表示的是 所屬用戶及所屬用戶組,換句話說 目錄 a 屬于用戶deploy及用戶組deploy,而 test.txt屬于用戶root及用戶組root
可以通過chown修改文件所屬用戶,示例:
sudo chown deploy test.txt
表示將test.txt的所屬用戶修改為deploy,因為該命令需要較高權限,所以前面加sudo切換到root身份,執行以后,再ll檢測
[deploy@deploy myservice]$ ll total 4 drwxrwxr-x. 2 deploy deploy 6 Jan 21 17:10 a -rw-r--r--. 1 deploy root 40 Jan 21 14:41 test.txt
可以看到test.txt的所屬用戶已經變成deploy了。
chmod用于修改用戶及目錄權限,示例:
[deploy@deploy myservice]$ chmod +w test.txt [deploy@deploy myservice]$ ll total 4 drwxrwxr-x. 2 deploy deploy 6 Jan 21 17:10 a -rw-rw-r--. 1 deploy root 40 Jan 21 14:41 test.txt
chmod +w test.txt表示將test.txt的所屬用戶及所屬用戶組的權限增加寫(w,write)權限
chmod a+w test.txt [deploy@deploy myservice]$ ll total 4 drwxrwxr-x. 2 deploy deploy 6 Jan 21 17:10 a -rw-rw-rw-. 1 deploy root 40 Jan 21 14:41 test.txt
這次在+w前加了一個a,表示all,即給所有人都增加了test.txt的寫權限
[deploy@deploy myservice]$ chmod u-w test.txt [deploy@deploy myservice]$ ll test.txt -r--rw-rw-. 1 deploy root 40 Jan 21 14:41 test.txt
猜一下,也能大概知道u-w的意思,u即user縮寫,-表示去掉權限,所以u-w表示將所屬用戶的write權限去掉,類似的
[deploy@deploy myservice]$ chmod g-r test.txt [deploy@deploy myservice]$ ll test.txt -r---w-rw-. 1 deploy root 40 Jan 21 14:41 test.txt
g-r表示將所屬用戶組的read權限去掉。
另外,從計算機內部的二進制來看,權限可以用3位2進制表示,從左向右依次為: 讀、寫、執行,所以111表示所有權限,101表示讀及執行權限,000表示沒任何權限,再考慮到 所屬用戶、所屬用戶組、其它組,也就是說有3組二進制,因此
chmod a+rwx 可以簡化為 chmod 777
注:777是10進制表示,轉換成權限2進制,即 111 111 111
[deploy@deploy myservice]$ chmod 777 test.txt [deploy@deploy myservice]$ ll test.txt -rwxrwxrwx. 1 deploy root 40 Jan 21 14:41 test.txt
類似的,如果要去掉所有人的所有權限
[deploy@deploy myservice]$ chmod -777 test.txt [deploy@deploy myservice]$ ll test.txt ----------. 1 deploy root 40 Jan 21 14:41 test.txt
3.2 文件測試
#!/bin/bash [ -f "test.txt" ] && echo 'test.txt is exists' [ ! -f 'abc.txt' ] && echo 'abc.txt is not exist'
上面這段表示,表示如果文件test.txt存在,則輸出test.txt is exists,類似的,如果文件abc.txt不存在,則輸出abc.txt is not exists
再增加一些判斷:
#!/bin/bash [ -f "test.txt" ] && echo 'test.txt is exists' [ ! -f 'abc.txt' ] && echo 'abc.txt is not exist' [ -x "test.txt" ] || echo 'test.txt can not execute' [ -d "a" ] && echo "a is directory" [ -d "a" ] && [ -r "a" ] && echo "a is directory and can read "
完整的文件判斷條件收集如下:
-e filename 如果 filename存在,則為真 (e即Exist的首字母) -d filename 如果 filename為目錄,則為真 (d即Directory的首字母) -f filename 如果 filename為常規文件,則為真 (f即File的首字母) -L filename 如果 filename為符號鏈接,則為真 (L即Link的首字母,注意這個是大寫的) -r filename 如果 filename可讀,則為真 (r即Read的首字母) -w filename 如果 filename可寫,則為真 (w即Write的首字母) -x filename 如果 filename可執行,則為真 (x即eXecute) -s filename 如果文件長度不為0,則為真(可記憶為Substance的意思) -h filename 如果文件是軟鏈接,則為真 filename1 -nt filename2 如果 filename1比 filename2新,則為真(-nt 可記憶為new than) filename1 -ot filename2 如果 filename1比 filename2舊,則為真(-nt 可記憶為old than)
4. 獲取其它命令的輸出
cmd_pwd=`pwd` cmd_date=`date "+%Y-%m-%d %H:%M:%d"` current_dir=${cmd_pwd} current_time=${cmd_date}
注意:命令字符串兩端的不是單引號,而是`(即:鍵盤最左上角esc鍵下的~鍵)
輸出:
當前目錄:/Users/yjmyzz 當前時間:2016-01-21 18:13:21
5. 獲取nohup的進程id
先建一個app-test.sh來模擬應用程序,內容如下:
#!/bin/bash echo 'I want to sleep 100 second' sleep 100
這段代碼,啥也不干,上來就sleep 100秒
再建一個app-run.sh來模擬后臺啟動app-test,內容如下:
#!/bin/bash echo 'app is starting...' nohup ./app-test.sh >/dev/null 2>&1 & echo 'ok,the pid is :'$!
測試一下:
➜ ~ ./app-run.sh app is starting... ok,the pid is :3168 ➜ ~ ps -ef|grep app-test.sh 501 3168 1 0 6:26PM ttys001 0:00.01 /bin/bash ./app-test.sh
即: $!可以取到nohup后臺啟動的程序對應的pid
將前面寫到的這些知識,來一個綜合練習:
#!/bin/bash cmd_pwd=`pwd` pwd_dir=${cmd_pwd} pid_file=${pwd_dir}/my.pid #啟動 sub_start() { printf "starting..." if [ -w "${pid_file}" ]; then echo ${pid_file}' has already exists' else nohup ./netty-sample >/dev/null 2>&1 & pid=$! echo $! > ${pid_file} sleep 2 printf 'ok!\n' fi } #停止 sub_stop() { printf "stopping..." if [ -w "${pid_file}" ]; then pkill -F ${pid_file} sleep 2 printf 'ok!\n' else printf '\n'${pid_file}' NOT exists' fi } #查看狀態 sub_status(){ if [ -w "${pid_file}" ]; then printf "running.\n" else printf "NOT running.\n" fi } case $1 in start) sub_start ;; stop) sub_stop ;; restart) printf "restarting...\n" sub_stop sleep 1 sub_start sleep 1 sub_status ;; status) sub_status ;; *) printf "usage: $0 {start|stop|restart|status}\n" exit 1 ;; esac exit 0
這是一段通用的啟動shell腳本,大意是啟動指定應用(上面的代碼中,待啟用的應用為netty-sample,大家可以自行修改)時,先找到進程id,然后保存到pid文件中,這樣后面就通過檢測pid是否存在,來判斷程序是否在運行中,也可用于結束程序或重啟程序。
6、編寫自己的linux服務
linux下的服務,只要在/etc/rc.d/init.d/下放一個自己的shell腳本就可以了,參考內容如下:
#! /bin/bash # chkconfig: 2345 10 90 # description: myservice .... #. /etc/init.d/functions desc='my-service' cmd=`date "+%Y-%m-%d %H:%M:%S"` case "$1" in start) printf '%s is starting...' ${desc} sleep 1 printf 'ok!\n' echo ${cmd} >> /opt/myservice/test.txt ;; stop) printf '%s is stopping...' ${desc} sleep 1 printf 'ok!\n' ;; status) printf '%s is ok!\n' ${desc} ;; restart|reload|force-reload) $0 stop $0 start ;; *) echo $"Usage: $0 {start|stop|status|restart|reload|force-reload}" exit 2 esac exit 0
代碼不復雜,啟動時在指定目錄寫個文件而已,將其保存成myservice.sh,賦予執行權限,應該就可以service myservice start|stop|restart|status了,很簡單吧。
(注:第3,4行的注釋不能刪除,否則后面加入開機啟動時會報錯。)
如果想讓myservice服務開機即自動啟動,可以執行
sudo chkconfig --add myservice
加好后,可以嘗試重啟下機器,看指定目錄下的文件是否有生成,如果生成且寫入了新內容,表明服務確實運行了。
另外:chkconfig 不加任何參數,可以查看當前有哪些服務配置了開機自動啟動。如果要從開機啟動的服務列表中刪除,chkconfig --del myservice.
文章列表