目錄php
chmod +x ./test.sh #使腳本具備執行權限 ./test.sh #執行腳本
/bin/sh test.sh /bin/php test.php
name='bob' echo $name echo "my name id $name" echo "Hello,"$name"!" echo ${#name} #輸出 4 (長度) string="你原本就很帥" echo "長度"${#string} echo ${string:1:4} #從第二個字符開始截取4個字符 echo `expr index "$string" 原本` #查找字符本或來的位置(哪一個字母先出現就計算哪一個) ##shell數組 array_name=(value0 value1 value2 value3) echo ${array_name[@]} #@獲取數組全部元素 length=${#array_name[@]} #獲取數組長度 echo $length lengthn=${#array_name[2]} #獲取第二個元素的長度 echo $lengthn
#---------------------------------- # 這是一個註釋 # author:walkingsun #---------------------------------- # 多行註釋 :<<EOF 註釋內容... 註釋內容... 註釋內容... EOF :<<! 註釋內容... 註釋內容... 註釋內容... !
#!/bin/bash echo "Shell 傳遞參數實例!"; echo "執行的文件名:$0"; # $0 爲執行的文件名 echo "第一個參數爲:$1"; echo "第二個參數爲:$2"; echo "第三個參數爲:$3";
執行git
./test.sh 1 2 3
參數處理 說明 $# 傳遞到腳本的參數個數 $* 以一個單字符串顯示全部向腳本傳遞的參數。 如"$*"用「"」括起來的狀況、以"$1 $2 … $n"的形式輸出全部參數。 $$ 腳本運行的當前進程ID號 $! 後臺運行的最後一個進程的ID號 $@ 與$*相同,可是使用時加引號,並在引號中返回每一個參數。 如"$@"用「"」括起來的狀況、以"$1" "$2" … "$n" 的形式輸出全部參數。 $- 顯示Shell使用的當前選項,與set命令功能相同。 $? 顯示最後命令的退出狀態。0表示沒有錯誤,其餘任何值代表有錯誤。 $* 與 $@ 區別: 相同點:都是引用全部參數。 不一樣點:只有在雙引號中體現出來。假設在腳本運行時寫了三個參數 一、二、3,,則 " * " 等價於 "1 2 3"(傳遞了一個參數),而 "@" 等價於 "1" "2" "3"(傳遞了三個參數)。
## 算數運算符 運算符 說明 舉例 + 加法 `expr $a + $b` 結果爲 30。 - 減法 `expr $a - $b` 結果爲 -10。 * 乘法 `expr $a \* $b` 結果爲 200。 / 除法 `expr $b / $a` 結果爲 2。 % 取餘 `expr $b % $a` 結果爲 0。 = 賦值 a=$b 將把變量 b 的值賦給 a。 == 相等。用於比較兩個數字,相同則返回 true。 [ $a == $b ] 返回 false。 != 不相等。用於比較兩個數字,不相同則返回 true。 [ $a != $b ] 返回 true。 ## 關係運算符 -eq 檢測兩個數是否相等,相等返回 true。 [ $a -eq $b ] 返回 false。 -ne 檢測兩個數是否不相等,不相等返回 true。 [ $a -ne $b ] 返回 true。 -gt 檢測左邊的數是否大於右邊的,若是是,則返回 true。 [ $a -gt $b ] 返回 false。 -lt 檢測左邊的數是否小於右邊的,若是是,則返回 true。 [ $a -lt $b ] 返回 true。 -ge 檢測左邊的數是否大於等於右邊的,若是是,則返回 true。 [ $a -ge $b ] 返回 false。 -le 檢測左邊的數是否小於等於右邊的,若是是,則返回 true。 [ $a -le $b ] 返回 true。 ## 布爾運算符 運算符 說明 舉例 ! 非運算,表達式爲 true 則返回 false,不然返回 true。 [ ! false ] 返回 true。 -o 或運算,有一個表達式爲 true 則返回 true。 [ $a -lt 20 -o $b -gt 100 ] 返回 true。 -a 與運算,兩個表達式都爲 true 才返回 true。 [ $a -lt 20 -a $b -gt 100 ] 返回 false。 ## 邏輯運算符 && 邏輯的 AND [[ $a -lt 100 && $b -gt 100 ]] 返回 false || 邏輯的 OR [[ $a -lt 100 || $b -gt 100 ]] 返回 true ## 字符串運算符 = 檢測兩個字符串是否相等,相等返回 true。 [ $a = $b ] 返回 false。 != 檢測兩個字符串是否相等,不相等返回 true。 [ $a != $b ] 返回 true。 -z 檢測字符串長度是否爲0,爲0返回 true。 [ -z $a ] 返回 false。 -n 檢測字符串長度是否爲0,不爲0返回 true。 [ -n "$a" ] 返回 true。 str 檢測字符串是否爲空,不爲空返回 true。 [ $a ] 返回 true。 ## 文件測試運算符 操做符 說明 舉例 -b file 檢測文件是不是塊設備文件,若是是,則返回 true。 [ -b $file ] 返回 false。 -c file 檢測文件是不是字符設備文件,若是是,則返回 true。 [ -c $file ] 返回 false。 -d file 檢測文件是不是目錄,若是是,則返回 true。 [ -d $file ] 返回 false。 -f file 檢測文件是不是普通文件(既不是目錄,也不是設備文件),若是是,則返回 true。 [ -f $file ] 返回 true。 -g file 檢測文件是否設置了 SGID 位,若是是,則返回 true。 [ -g $file ] 返回 false。 -k file 檢測文件是否設置了粘着位(Sticky Bit),若是是,則返回 true。 [ -k $file ] 返回 false。 -p file 檢測文件是不是有名管道,若是是,則返回 true。 [ -p $file ] 返回 false。 -u file 檢測文件是否設置了 SUID 位,若是是,則返回 true。 [ -u $file ] 返回 false。 -r file 檢測文件是否可讀,若是是,則返回 true。 [ -r $file ] 返回 true。 -w file 檢測文件是否可寫,若是是,則返回 true。 [ -w $file ] 返回 true。 -x file 檢測文件是否可執行,若是是,則返回 true。 [ -x $file ] 返回 true。 -s file 檢測文件是否爲空(文件大小是否大於0),不爲空返回 true。 [ -s $file ] 返回 true。 -e file 檢測文件(包括目錄)是否存在,若是是,則返回 true。 [ -e $file ] 返回 true。
echo -e "OK! \n" # -e 開啓轉義 \n顯示換行 echo -e "OK! \c" # -e 開啓轉義 \c 不換行 echo "It is a test" > myfile #顯示結果定向到文件 echo `date` #顯示命令執行結果
printf format-string [arguments...]
模仿c程序庫的printf(php也是如此)github
printf "%-10s %-8s %-4s\n" 姓名 性別 體重kg printf "%-10s %-8s %-4s\n" walkingsun boy 150 # %s %c %d %f都是格式替代符 # %-10s 指一個寬度爲10個字符(-表示左對齊,沒有則表示右對齊),任何字符都會被顯示在10個字符寬的字符內,若是不足則自動以空格填充,超過也會將內容所有顯示出來。 # %-4.2f 指格式化爲小數,其中.2指保留2位小數。
Shell中的 test 命令用於檢查某個條件是否成立,它能夠進行數值、字符和文件三個方面的測試。shell
# 數值測試 參數 說明 -eq 等於則爲真 -ne 不等於則爲真 -gt 大於則爲真 -ge 大於等於則爲真 -lt 小於則爲真 -le 小於等於則爲真 # 字符串測試 = 等於則爲真 != 不相等則爲真 -z 字符串 字符串的長度爲零則爲真 -n 字符串 字符串的長度不爲零則爲真 # 文件測試 -e 文件名 若是文件存在則爲真 -r 文件名 若是文件存在且可讀則爲真 -w 文件名 若是文件存在且可寫則爲真 -x 文件名 若是文件存在且可執行則爲真 -s 文件名 若是文件存在且至少有一個字符則爲真 -d 文件名 若是文件存在且爲目錄則爲真 -f 文件名 若是文件存在且爲普通文件則爲真 -c 文件名 若是文件存在且爲字符型特殊文件則爲真 -b 文件名 若是文件存在且爲塊特殊文件則爲真
if [ $(ps -ef | grep -c "ssh") -gt 1 ]; then echo "true"; fi # 查詢進程中命令行包含ssh的數量是否大於1,是返回true -c 統計數量
if ... elseif ...else ... fi數組
if condition1 then command1 elif condition2 then command2 else commandN fi
for var in item1 item2 ... itemN do command1 command2 ... commandN done
實例:bash
for loop in 1 2 3 4 5 do echo "The value is: $loop" done ## 順序輸出字符串中的字符 for str in 'This is a string' do echo $str done
while condition do command done
實例:markdown
#!/bin/bash int=1 while(( $int<=5 )) do echo $int let "int++" done
無線循環app
while : do command done 或者 while true do command done 或者 for (( ; ; ))
until 循環 until 循環執行一系列命令直至條件爲 true 時中止。 until 循環與 while 循環在處理方式上恰好相反。 通常 while 循環優於 until 循環,但在某些時候—也只是極少數狀況下,until 循環更加有用。 until 語法格式: until condition do command done
case 值 in 模式1) command1 command2 ... commandN ;; 模式2) command1 command2 ... commandN ;; esac
實例ssh
echo '輸入 1 到 4 之間的數字:' echo '你輸入的數字爲:' read aNum case $aNum in 1) echo '你選擇了 1' ;; 2) echo '你選擇了 2' ;; 3) echo '你選擇了 3' ;; 4) echo '你選擇了 4' ;; *) echo '你沒有輸入 1 到 4 之間的數字' ;; esac
break和continue (同PHP)函數
esac
須要一個esac(就是case反過來)做爲結束標記,每一個case分支用右圓括號,用兩個分號表示break。
[ function ] funname [()] { action; [return int;] }
實例:
funWithReturn(){ echo "這個函數會對輸入的兩個數字進行相加運算..." echo "輸入第一個數字: " read aNum echo "輸入第二個數字: " read anotherNum echo "兩個數字分別爲 $aNum 和 $anotherNum !" return $(($aNum+$anotherNum)) } funWithReturn echo "輸入的兩個數字之和爲 $? !" # 傳參 funWithParam(){ echo "第一個參數爲 $1 !" echo "第二個參數爲 $2 !" echo "第十個參數爲 $10 !" echo "第十個參數爲 ${10} !" echo "第十一個參數爲 ${11} !" echo "參數總數有 $# 個!" echo "做爲一個字符串輸出全部參數 $* !" } funWithParam 1 2 3 4 5 6 7 8 9 34 73 #注意,$10 不能獲取第十個參數,獲取第十個參數須要${10}。當n>=10時,須要使用${n}來獲取參數。
注意
參數處理 說明 $# 傳遞到腳本的參數個數 $* 以一個單字符串顯示全部向腳本傳遞的參數 $$ 腳本運行的當前進程ID號 $! 後臺運行的最後一個進程的ID號 $@ 與$*相同,可是使用時加引號,並在引號中返回每一個參數。 $- 顯示Shell使用的當前選項,與set命令功能相同。 $? 顯示最後命令的退出狀態。0表示沒有錯誤,其餘任何值代表有錯誤。
命令 說明 command > file 將輸出重定向到 file。 command < file 將輸入重定向到 file。 command >> file 將輸出以追加的方式重定向到 file。 n > file 將文件描述符爲 n 的文件重定向到 file。 n >> file 將文件描述符爲 n 的文件以追加的方式重定向到 file。 n >& m 將輸出文件 m 和 n 合併。 n <& m 將輸入文件 m 和 n 合併。 << tag 將開始標記 tag 和結束標記 tag 之間的內容做爲輸入。
實例
who > users #執行 who 命令,它將命令的完整的輸出重定向在用戶文件中(users)
重定向深刻
command 2 > file #stderr 重定向到 file command 2 >> file #stderr 追加到 file 文件末尾 command > file 2>&1 #stdout 和 stderr 合併後重定向到 file command < file1 >file2 #stdin 和 stdout 都重定向,command 命令將 stdin 重定向到 file1,將 stdout 重定向到 file2
command << delimiter document delimiter
實例
在命令行中經過 wc -l 命令計算 Here Document 的行數: $ wc -l << EOF 歡迎來到 菜鳥教程 www.runoob.com EOF 3 # 輸出結果爲 3 行 $
若是但願執行某個命令,但又不但願在屏幕上顯示輸出結果,那麼能夠將輸出重定向到 /dev/null:
$ command > /dev/null
/dev/null 是一個特殊的文件,寫入到它的內容都會被丟棄;若是嘗試從該文件讀取內容,那麼什麼也讀不到。可是 /dev/null 文件很是有用,將命令的輸出重定向到它,會起到"禁止輸出"的效果。
若是但願屏蔽 stdout 和 stderr,能夠這樣寫:
$ command > /dev/null 2>&1
. filename # 注意點號(.)和文件名中間有一空格 或 source filename
nohup command > myout.file 2>&1 & 0 – stdin (standard input),1 – stdout (standard output),2 – stderr (standard error) ; 2>&1是將標準錯誤(2)重定向到標準輸出(&1),標準輸出(&1)再被重定向輸入到myout.file文件中。
&是指在後臺運行,但當用戶推出(掛起)的時候,命令自動也跟着退出
sh test.sh &
使命令永久的在後臺執行
nohup COMMAND &
這裏會記錄典型的shell應用場景
#!/bin/sh # 清理日誌 # author:walkingsun # test path=/data/app/WindBlog/runtime/logs/ #指定清理目錄 timeout=`expr 30 \* 86400` #過時時間(當前設爲30天) systime=`date +%s` #獲取當前系統的時間 (秒爲單位) files=$(ls $path) for filename in $files do fileuptime=`stat -c %Y $path$filename` #獲取文件修改時間(秒) if [ $[ $systime - $fileuptime ] -gt $timeout ] then echo $path$filename echo `rm -rf $apth$filename` fi done
你能夠假設每行列數相同,而且每一個字段由 ' ' 分隔.
示例:
假設 file.txt 文件內容以下: name age alice 21 ryan 30 應當輸出: name alice ryan age 21 30
解答
#!/bin/bash awk '{for(i=1;i<=NF;i++){if(NR==1){data[i]=$i}else{data[i]=data[i]" "$i}}}END{for(i=1;i<=NF;i++) print data[i]}' file.txt
你能夠假設一個有效的電話號碼必須知足如下兩種格式: (xxx) xxx-xxxx 或 xxx-xxx-xxxx。(x 表示一個數字)
你也能夠假設每行先後沒有多餘的空格字符。
示例:
假設 file.txt 內容以下:
987-123-4567
123 456 7890
(123) 456-7890
你的腳本應當輸出下列有效的電話號碼:
987-123-4567
(123) 456-7890
#!/bin/bash awk '/^(\([0-9]{3}\) |[0-9]{3}-)[0-9]{3}-[0-9]{4}$/{print $0}' file.txt
爲了簡單起見,你能夠假設: words.txt只包括小寫字母和 ' ' 。 每一個單詞只由小寫字母組成。 單詞間由一個或多個空格字符分隔。 示例: 假設 words.txt 內容以下: the day is sunny the the the sunny is is 你的腳本應當輸出(以詞頻降序排列): the 4 is 3 sunny 2 day 1
#!/bin/bash awk '{for(i=1;i<=NF;i++){a[$i]=a[$i]+1}}END{for(k in a){print k" "a[k]}}' words.txt |sort -nr -k 2