shell 指令碼-符號-基礎語法
為了便於識別 建議 以.sh 結尾
shell指令碼 可以放上所有的命令列的指令(源於bash)
shell指令碼 是 解釋型語言 c/c++ 是編譯型語言
下面用到的 shell程式碼sh_1.sh
#!/bin/bash cd ../ ls pwd
解釋型指令碼的執行過程:
script.sh 是文字檔案,根本沒有程式碼段和 _start 函式 , exec 怎麼執行。
解釋:
Shell會fork 一個子程序並呼叫 exec執行 ./script.sh這個程式,exec 系統呼叫應該把子程序的程式碼
段替換成./script.sh程式的程式碼段 ,並從它的 _start開始執行。然而 script.sh
沒有程式碼段和 _start函式 ,怎麼辦呢 ?其實 exec還有另外一種機制 ,如果要執行的是一個文字文
件, 並且第一行用 Shebang 指定了直譯器 ,則用 直譯器程式的程式碼段替換當前程序 ,並且從解釋
器 的_start開始執行 ,而這個文字檔案被當作命令列引數傳給直譯器 。因此, 執行上述指令碼相
當於執 行程式
1. 互動 Shell(bash)fork/exec一個子 Shell(sh)用於執行指令碼 ,父程序 bash等待子程序 sh終止。
2. sh讀取指令碼中的 cd ..命令 ,呼叫相應的函式 執行內建命令 ,改變當前工作目錄為上一級
目 錄。
3. sh讀取指令碼中的
4. ls終止後 ,sh繼續執行 ,讀到指令碼檔案末尾 ,sh終止。
5. sh終止後 ,bash繼續執行 ,列印提示符等待使用者輸入。
如果將命令列下輸入的命令用 ()括號括起來 ,那麼也會 fork出一個子 Shell執行小括號中的命令 ,
一 行中可以輸入由分號 ;隔開的多個命令 ,比如 : $ (cd ..;ls -l)
和上面兩種方法執行 Shell指令碼的效果是相同的 ,cd ..命令改變的是子 Shell的 PWD,而不會影響
到 互動式Shell。
chmod + x script.sh方式
sh檔案中,cd ..
然而source ./script.sh 和 . ./script.sh 方式
則有不同的效果,cd ..命令是直接在互動式Shell1下執行的,改變互動式Shell的PWD
對於php 。。。指令碼語言 執行也是 直譯器這個流程
sh_1.sh程式碼:
#!/bin/bash
cd ../
ls
pwd
[[email protected] 1_shell]$ /bin/bash sh_1.sh // shell指令碼中 cd 直接在子bash中執行 整個過程父程序 不參與
1_shell
/home/bozi/linux_test/shell
[[email protected] 1_shell]$ pwd
/home/bozi/linux_test/shell/1_shell // 所以 不影響父程序 的路徑 還在子程序的路徑中
[[email protected] 1_shell]$ cd .. // cd內建命令 shell 自己直接親自執行(不建立子程序) 影響自己的路徑
[[email protected] shell]$ pwd
/home/bozi/linux_test/shell // 直接執行 影響了 跑到上級目錄
路徑
[[email protected] shell]$ ll
總用量 4
drwxrwxr-x. 2 bozi bozi 4096 8月 14 10:18 1_shell
[[email protected] shell]$ cd 1_shell/
[[email protected] 1_shell]$ ll
總用量 4
-rw-rw-r--. 1 bozi bozi 298 8月 14 10:18 sh_1.sh
source 與(. 命令一樣)
例子:
source 不建立子bash,遇見bash中有內建命令 cd 互動式shell(父程序自己直接執行) 所以 退出時 父程序的路徑 變了 影響父程序
[[email protected] 1_shell]$ ll
總用量 4
-rw-rw-r--. 1 bozi bozi 298 8月 14 10:18 sh_1.sh
[[email protected] 1_shell]$ source sh_1.sh
1_shell
/home/bozi/linux_test/shell
[[email protected] shell]$ pwd
/home/bozi/linux_test/shell
.命令 效果相同
[[email protected] 1_shell]$ . sh_1.sh
1_shell
/home/bozi/linux_test/shell
[[email protected] shell]$ pwd
/home/bozi/linux_test/shell
set 顯示 本地變數 和 環境變數(本地變數只存在當前程序中)
env 只顯示環境變數 (環境變數 可以傳遞給 子程序 父子程序共享)
變數
shell 中 所有變數varname都是字串 ,且都是全域性本地變數 沒有int ,float等型別 顯示變數 用 $varname或 ${varname}
如果變數不存在 shell顯示空串
變數拼接 用{}花括號 如: ${varname}aaa $varname"aaa"
演示程式碼:
[[email protected] 2_shell]$ SHELL=1 [[email protected] 2_shell]$ echo $SHELL 1 [[email protected] 2_shell]$ echo $SHELLabc [[email protected] 2_shell]$ echo ${SHELL} 1 [[email protected] 2_shell]$ echo ${SHELL}abc 1abc
unset 取消一個變數
[[email protected] 2_shell]# v=a [[email protected] 2_shell]# echo $v a [[email protected] 2_shell]# unset $v [[email protected] 2_shell]#
顯示本shell的pid
[[email protected] 2_shell]# echo $$ 6699
read
-p 提示符 -t 等待的秒數
[[email protected] 2_shell]$ read -p '>>' -t 10 arg >>nihao [[email protected] 2_shell]$ echo $arg nihao
陣列變數
var[1]="small min" var[2]="big min" var[3]="nice min" echo "${var[1]}, ${var[2]},${var[3]}" [[email protected] 2_shell]$ ./1_test.sh small min, big min,nice min
test指令
兩個整數之間的判定
-eq 相等(equal)
-ne 不等(not equal)
-gt 大於 (greaater than)
-lt 小於 (less than)
-ge 大於等於 (greater than or equal)
-le 小於等於 (less than or equal)
例子:
[[email protected] 2_shell]$ test 1 -lt 2; echo $? 0 ---------------》【真】 [[email protected] 2_shell]$ test 5 -lt 2; echo $? 1
判定字串的資料
test -z string [string 為空 返回true] test -n string [string 為空 返回false] test str1 = str2 [str1=str2 回傳true] test str1 != str2 [str1 與str2相等返回 false] 例子: [[email protected] 2_shell]$ test -z "";echo $? 0 [[email protected] 2_shell]$ test -z "-";echo $? 1 [[email protected] 2_shell]$ test -n "";echo $? 1 [[email protected] 2_shell]$ test -n "-";echo $? 0 [[email protected] 2_shell]$ test "nihao" = "hello" ; echo $? 1 [[email protected] 2_shell]$ test "nihao" == "hello" ; echo $? 1 [[email protected] 2_shell]$ test "nihao" != "hello" ; echo $? 0
error
[[email protected] 2_shell]$ test "nihao"=="hello" ; echo $?
0 ----》“==兩邊少空格 結果 不正確”
test擴充套件:
當要檢測系統上面某些檔案或者是相關的屬性時,利用test這個命令來工作真是好用得不得了,如檢查/dmtsai是否存在時,使用:test –e /dmtsai
上面的執行結果並不會顯示任何資訊,但最後可以通過$?或&&及||來顯示整個結果。
test –e /dmtsai && echo “exist” ||echo “Not exist”
最終結果可以顯示exist還是not exist。-e是測試一個東西存在不存在。常用的測試命令如下:
測試的標誌 | 代表意義 |
關於某個檔名的“檔案型別”判斷,如test – e filename表示存在否 | |
-e | 該檔名是否存在 |
-f | 該檔名是否存在且為檔案(file) |
-d | 該檔名是否存在且為目錄(directory) |
-b | 該檔名是否存在且為一個block device裝置 |
-c | 該檔名是否存在且為一個character device裝置 |
-S | 該檔名是否存在且為一個Socket檔案 |
-p | 該檔名是否存在且為一個FIFO(pipe)檔案 |
-L | 該檔名是否存在且為一個連線檔案 |
關於檔案的許可權檢測,如test –r filename表示可讀否(但root許可權常有例外) | |
-r | 檢測該檔名是否存在且具有“可讀”的許可權 |
-w | 檢測該檔名是否存在且具有“可寫”的許可權 |
-x | 檢測該檔名是否存在且具有“可執行”的許可權 |
-u | 檢測該檔名是否存在且具有“SUID”的屬性 |
-g | 檢測該檔名是否存在且具有“SGID“的屬性 |
-k | 檢測該檔名是否存在且具有“Sticky bit”的屬性 |
-s | 檢測該檔名是否存在且具有“非空白檔案” |
兩個檔案之間的比較,如test file1 –nt file2 | |
-nt | (newer than)判斷file1是否比file2新 |
-ot | (older than)判斷file1是否比file2舊 |
-ef | 判斷file1與file2是否為同一檔案,可用在判斷hard link的判定上。主要意義在於判定兩個檔案是否均指向同一個inode |
關於兩個整數之間的判定嗎,如test n1 –eq n2 | |
-eq | 兩數值相等(equal) |
-ne | 兩數值不等(not equal) |
-gt | N1大於n2(greate than) |
-lt | N1小於n2(less than) |
-ge | N1大於等於n2(greater than or equal) |
-le | N1小於等於n2(less than or equal) |
判定字串的資料 | |
test –z string | 判定字串是否為0,若string為空字串,則為true |
test –n string | 判定字串是否非為0,若string為空字串,則為false |
test str1 = str2 | 判定str1是否等於str2,若相等,則回傳true |
test str1 != str2 | 判定str1是否不等於str2,若相等,則回傳false |
多重條件判定,若test –r filename –a –x filename | |
-a | 兩個條件同時成立!如test –r file –a –x file,則file同時具有r與x許可權時,才回傳true |
-o | 任何一個條件成立!如test –r file –o –x file,則file具有r或x許可權時,就可回傳true |
! | 反向狀態,如test ! –x file,但file不具有x時,回傳true |
多重條件判定
-a [先當於 與&&]
-o 【或】
! 【非】
例子:
[[email protected] 2_shell]$ test 1 -eq 1 -a 2 -lt 5; echo $? 0 [[email protected] 2_shell]$ test 1 -eq 1 -a 5 -lt 2; echo $? 1
判斷符號[]
[[email protected] 2_shell]$ [ "" == "HOME" ];echo $? 1 [[email protected] 2_shell]$ [ "" != "HOME" ];echo $? 0
error
[[email protected] 2_shell]$ [ ""!="HOME" ];echo $? 0 [[email protected] 2_shell]$ [ ""=="HOME" ];echo $? 0
注意 空格不能少 否則出錯:
[[email protected] 2_shell]$ [ 空格"" 空格== 空格"HOME" 空格];echo $?
建議:
1 在中括號[]中的每個元件用 空格 隔開
2 在中括號內的變數, 最好用雙引號括起來
3 在中括號裡面的常量最好用單引號或 雙引號括起來
2的一個錯誤例子:
[[email protected] 2_shell]$ name="hello world" [[email protected] 2_shell]$ [ $name == "hello" ] bash: [: too many arguments --------------------------》 太多引數 本來是兩個引數比較 因為name變數的字串中間有空格 不加“” 解析為 [ hello world == "hello" ] 肯定引數太多 [[email protected] 2_shell]$ [ "$name" == "hello" ] [[email protected] 2_shell]$ echo $? 1 [[email protected] 2_shell]$ [ "$name" != "hello" ] [[email protected] 2_shell]$ echo $? 0
小練習:
read -p "please inoput (Y/N):" yn [ "$yn" == "Y" -o "$yn" == "y" ] && echo "ok, continue" && exit 0 [ "$yn" == "N" -o "$yn" == "n" ] && echo "oh, interrupt" && exit 0 echo "I dont know what your chonice is " && exit 0 執行: [[email protected] 2_shell]$ ./1_test.sh please inoput (Y/N):y ok, continue [[email protected] 2_shell]$ ./1_test.sh please inoput (Y/N):n oh, interrupt [[email protected] 2_shell]$ ./1_test.sh please inoput (Y/N): I dont know what your chonice is
shell中&&和||的使用方法
&&運算子:
command1 && command2
&&左邊的命令(命令1)返回真(即返回0,成功被執行)後,&&右邊的命令(命令2)才能夠被執行;換句話說,“如果這個命令執行成功&&那麼執行這個命令”。
語法格式如下:
command1 && command2 [&& command3 ...]
1 命令之間使用 && 連線,實現邏輯與的功能。
2 只有在 && 左邊的命令返回真(命令返回值 $? == 0),&& 右邊的命令才會被執行。
3 只要有一個命令返回假(命令返回值 $? == 1),後面的命令就不會被執行。
||運算子:
command1 || command2
||則與&&相反。如果||左邊的命令(命令1)未執行成功,那麼就執行||右邊的命令(命令2);或者換句話說,“如果這個命令執行失敗了||那麼就執行這個命令。
1 命令之間使用 || 連線,實現邏輯或的功能。
2 只有在 || 左邊的命令返回假(命令返回值 $? == 1),|| 右邊的命令才會被執行。這和 c 語言中的邏輯或語法功能相同,即實現短路邏輯或操作。
3 只要有一個命令返回真(命令返回值 $? == 0),後面的命令就不會被執行。
&& || 與 -a -o
區別
-a -o 連線的是兩個表示式 即 測試條件
而 && 與 || 連線的是兩條 命令
程式碼:
val=10 str="hello" test $val -eq 10 -a "$str" == "hello" echo $? test $val -eq 10 && test "$str" == "hello" echo $? 執行: [[email protected] 2_shell]$ ./12_test.sh 0 0
預設變數 $0 $1 $2 ...
例子:$ ./1_test.sh nihao sunshine
$0 $1 $2
$# :代表後接的引數的個數, 如上例子為2
[email protected]:代表"$1" "$2" ... 之意, 每個變數獨立的用雙括號括起來
$*: 代表“$1c$2c$3c$4” c為分隔符號,預設是空格鍵
[email protected] 和 $*還是有所不同的 一般用 [email protected]
程式碼:
#! /bin/bash echo "\$0 is $0" echo "\$1 is $1" echo "\$2 is $2" echo "\$# is $#" echo "\[email protected] is [email protected]" echo "\$* is $*"
執行:
[[email protected] 2_shell]$ ./1_test.sh $0 is ./1_test.sh $1 is $2 is $# is 0 [email protected] is $* is
[[email protected] 2_shell]$ ./1_test.sh 1 2 3 4 $0 is ./1_test.sh $1 is 1 $2 is 2 $# is 4 [email protected] is 1 2 3 4 $* is 1 2 3 4
程式碼:
echo "your whole parameter is ===>$0" echo "total parameter numbers is ===>$#" [ "$#" -lt 2 ]&&echo "the numbers of paramater is less than 2. stop here"\ && exit 0; echo "your whole parameter is ===>[email protected]" echo "the 1st parameter ===>$1" echo "the 2nd parameter ===> $2 "
執行:
[[email protected] 2_shell]$ ./1_test.sh your whole parameter is ===>./1_test.sh total parameter numbers is ===>0 the numbers of paramater is less than 2. stop here [[email protected] 2_shell]$ ./1_test.sh nihao sunshine your whole parameter is ===>./1_test.sh total parameter numbers is ===>2 your whole parameter is ===>nihao sunshine the 1st parameter ===>nihao the 2nd parameter ===> sunshine
執行:
[[email protected] 1_shell]$ cat sh_1.sh #!/bin/bash myint=10 echo '\$ \\ $myint \"' echo '###############' echo "\$ \\ $myint \"" [[email protected] 2_shell]$ ./1_test.sh your whole parameter is ===>./1_test.sh total parameter numbers is ===>0 the numbers of paramater is less than 2. stop here [[email protected] 2_shell]$ ./1_test.sh nihao sunshine your whole parameter is ===>./1_test.sh total parameter numbers is ===>2 your whole parameter is ===>nihao sunshine the 1st parameter ===>nihao the 2nd parameter ===> sunshine [[email protected] 2_shell]$ ./1_test.sh nihao sunshine here your whole parameter is ===>./1_test.sh total parameter numbers is ===>3 your whole parameter is ===>nihao sunshine here the 1st parameter ===>nihao the 2nd parameter ===> sunshine
shift:造成引數號碼偏移,移除前num個引數
shift+num num 及num之前的引數全部移除 num之後的引數從$1開始
如:
echo [email protected] echo "arg count $#" shift 1 echo "after shift 1" echo [email protected] echo "arg count $#" shift 3 echo "after shift 3" echo [email protected] echo "arg count $#"
執行:
[[email protected] 2_shell]$ ./1_test.sh one two three four five six seven one two three four five six seven arg count 7 after shift 1 two three four five six seven arg count 6 after shift 3 five six seven arg count 3
條件判斷式
1 if ... then
if [條件判斷式];then
條件成立執行
fi
&&代表AND
|| 代表 or
程式碼:
#!/bin/bash read -p "please input (Y/N):" yn if [ "X$yn" == "XY" ] || [ "X$yn" == "Xy" ];then echo "ok, continue" exit 0 fi if [ "X$yn" == "XN" ] || [ "X$yn" == "Xn" ];then echo "oh, interupt!" exit 0 fi
執行:
please input (Y/N):y ok, continue [[email protected] 2_shell]$ ./2_test.sh please input (Y/N):Y ok, continue [[email protected] 2_shell]$ ./2_test.sh please input (Y/N):N oh, interupt! [[email protected] 2_shell]$ ./2_test.sh please input (Y/N):n oh, interupt!
多重複雜條件判斷式
if [條件判斷式];then
條件成立
else
...
if
if [條件判斷式1];then
...
elif [條件判斷式2];then
...
else
...
if
程式碼:
read -p "please input (Y/N):" yn if [ "x$yn" == "xY" ] || [ "x$yn" == "xy" ]; then echo "ok, continue" elif [ "x$yn" == "xN" ] || [ "x$yn" == "xn" ]; then echo "oh, interupt" else echo "I dont know what your choice is" fi
執行:
[[email protected] 2_shell]$ vim 2_test.sh [[email protected] 2_shell]$ ./2_test.sh please input (Y/N):y ok, continue [[email protected] 2_shell]$ ./2_test.sh please input (Y/N):n oh, interupt [[email protected] 2_shell]$ ./2_test.sh please input (Y/N):s I dont know what your choice is 程式碼: testing=$(netstat -tuln |grep ':80' ) if [ "X$testing" != "X" ];then echo "WWW is running in your system ." fi testing=$(netstat -tuln | grep ':22') if [ "X$testing" != "X" ]; then echo "SSH is running in your system." fi testing=$(netstat -tuln | grep ':21') if [ "X$testing" != "X" ]; then echo "FTP is running in your system." fi testing=$(netstat -tuln | grep ':25') if [ "X$tesing" != "X" ]; then echo "Mail is running in your system." fi
執行:
[[email protected] 2_shell]$ ./3_text.sh Now, I will detect your linux server's services! The wwww, ftp, ssh , and mail will be detect ! SSH is running in your system.
利用case ...... esac判斷
case $變數名稱 in
”第1個變數名稱“)
程式段
;;
”第2個變數名稱“)
程式段
;; # ;; 相當於break
*) #*)相當於default
程式段
;;
esac
程式碼:
#!/bin/bash case $1 in "one") echo "your choice is ONE" ;; "two") echo "your choice is TWO" ;; "three") echo "your choice is THREE" ;; *) echo "Usage $0 {one|two|three}" ;; esac
執行:
[[email protected] 2_shell]$ ./4_test.sh Usage ./4_test.sh {one|two|three} [[email protected] 2_shell]$ ./4_test.sh one your choice is ONE [[email protected] 2_shell]$ ./4_test.sh two your choice is TWO [[email protected] 2_shell]$ ./4_test.sh three your choice is THREE
函式 function
函式的引數 也是$1$2$.... 但是函式體裡面的$1$2...與函式外面的 是相對獨立的
函式返回值: return後 用 $? 來接收 【返回值】(缺陷 返回257 是 1 範圍0-255)
程式碼:
#!/bin/bash function printit() # 也可以不加關鍵字function 即 printit(){...} 也是可以的 { echo -n "Your choice is " #加上-n表示不斷行繼續在一行顯示 } case $1 in "one") printit;echo $1 |tr 'a-z' 'A-Z' #大小寫轉化 ;; "two") printit;echo $1 |tr 'a-z' 'A-Z' #大小寫轉化 ;; "three") printit;echo $1 |tr 'a-z' 'A-Z' #大小寫轉化 ;; *) echo "Usage $0 {one|two|three}" ;; esac
執行:
[[email protected] 2_shell]$ ./5_test.sh one Your choice is ONE [[email protected] 2_shell]$ ./5_test.sh Usage ./5_test.sh {one|two|three} [[email protected] 2_shell]$ ./5_test.sh one Your choice is ONE [[email protected] 2_shell]$ ./5_test.sh two Your choice is TWO [[email protected] 2_shell]$ ./5_test.sh three Your choice is THREE
經典的fork炸彈 【!!!立馬宕機】
.() { .|.& }; . #遞迴呼叫 後臺執行
類似的 function a() { a|a }; a
防範措施 ulimit -Hu num 限定使用者最多num個程序
-------------------------------------------------
以下程式段就是由Jaromil所作的在類UNIX系統的shell環境下觸發fork炸彈的shell指令碼程式碼,總共只用了13個字元(包括空格):
:(){ :|:& };:
註解如下:
:() # 定義函式,函式名為":",即每當輸入":"時就會自動呼叫{}內程式碼
{ # ":"函式開始標識
: # 用遞迴方式呼叫":"函式本身
| # 並用管道(pipe)將其輸出引至...
: # 另一次遞迴呼叫的":"函式
# 綜上,":|:"表示的即是每次呼叫函式":"的時候就會生成兩份拷貝【二倍指數增長】
& # 呼叫間脫鉤,以使最初的":"函式被殺死後為其所呼叫的兩個":"函式還能繼續執行
} # ":"函式結束標識
; # ":"函式定義結束後將要進行的操作...
: # 呼叫":"函式,"引爆"fork炸彈
其中函式名“:”只是簡化的一例,實際實現時可以隨意設定,一個較易理解(將函式名替換為“forkbomb”)的版本如下:
forkbomb(){ forkbomb|forkbomb &} ; forkbomb
Windows下則可以批處理命令如下實現:
%0|%0
POSIX標準下的C與C++的實現:
#include <unistd.h>int main(){while(1) fork();return0;}
Perl語言的實現:
fork while fork
-------------------------------------------------
迴圈
while do done, until do done(不定迴圈)
程式碼:
#!/bin/bash while [ "X$yn" != "Xyes" -a "X$yn" != "XYES" ] do read -p "please input yes/YES to stop this program:" yn done echo "ok, you input the correct answer."
執行:
[[email protected] 2_shell]$ chmod u+x 6_test.sh [[email protected] 2_shell]$ ./6_test.sh please input yes/YES to stop this program:e please input yes/YES to stop this program:e please input yes/YES to stop this program:yes ok, you input the correct answer.
until程式碼:
sum=0 i=0 until [ $i -gt 100 ] do if (( i%2==0 ));then let sum+=i fi: let i++ done echo $sum
執行:
[[email protected] 2_shell]$ ./6_test.sh 2550 程式碼: s=0 i=0 while [ "$i" != "100" ] do i=$(($i+1)) s=$(($s+$i)) done echo "sum of 1+2+3+...+100 is : $s"
執行:
[[email protected] 2_shell]$ ./7_test.sh sum of 1+2+3+...+100 is : 5050
for ... do... done(固定迴圈)
for var in con1 con2 con3 ...
do
程式段
done
程式碼:
for animal in dog cat elephant do echo "there are ${animal}s..." done 執行: [[email protected] 2_shell]$ ./8_test.sh there are dogs... there are cats... there are elephants...
程式碼:
users=$(cut -d':' -f1 /etc/passwd) for username in $users do id $username done
執行:
[[email protected] 2_shell]$ ./9_test.sh uid=0(root) gid=0(root) 組=0(root) uid=1(bin) gid=1(bin) 組=1(bin),2(daemon),3(sys) uid=2(daemon) gid=2(daemon) 組=2(daemon),1(bin),4(adm),7(lp) uid=3(adm) gid=4(adm) 組=4(adm),3(sys) uid=4(lp) gid=7(lp) 組=7(lp) uid=5(sync) gid=0(root) 組=0(root)
測ip程式碼:
read -p "enter like 192.168.1->" network for sitenu in $(seq 1 100) do ping -c 1 -w 1 ${network}.${sitenu} &>/dev/null && result=0 || result=1 if [ "$result" == 0 ];then echo "server ${network}.${sitenu} is up." else echo "server ${network}.${sitenu} is down" fi done
執行:
[[email protected] 2_shell]$ ./9_test.sh enter like 192.168.1->192.168.174 server 192.168.174.1 is up. server 192.168.174.2 is up. server 192.168.174.3 is down server 192.168.174.4 is down server 192.168.174.5 is down server 192.168.174.6 is down server 192.168.174.7 is down
程式碼:
#!/bin/bash read -p "please input a diretory:" dir if [ "$dir" == "" -o ! -d "$dir" ];then echo "then $dir is not exist in your system." exit 1 fi filelist=$(ls $dir) for filename in $filelist do perm="" test -r "$dir/$filename" && perm="$perm readable" test -w "$dir/$filename" && perm="$perm writable" test -x "$dir/$filename" && perm="$perm executable" echo "the file $dir/$filename's permission is $perm" done
執行:
[[email protected] 2_shell]$ ./10_test.sh please input a diretory:../1_shell the file ../1_shell/2's permission is readable writable the file ../1_shell/3's permission is readable writable the file ../1_shell/sh_1.sh's permission is readable writable the file ../1_shell/sh_2.sh's permission is readable writable executable
for ....do...done 的數值處理
for ((初始值; 限制值;執行步階))
do
程式段
done
這種寫法 適合在數值運算中
程式碼:
read -p "please input a number . I will count for 1+2+3+...+your_input" num s=0 for ((i=1; i <= $num; i++)) do ((s += i)) done echo "the result of '1+2+3+...+$num 'is $s"
執行:
[[email protected] 2_shell]$ ./11_test.sh please input a number . I will count for 1+2+3+...+your_input10 the result of '1+2+3+...+10 'is 55 程式碼: #!/bin/bash for i in {A..b} do echo "val is: $i" done
執行:
[[email protected] 2_shell]$ sh 14_test.sh val is: A val is: B val is: C val is: D val is: E val is: F val is: G val is: H val is: I val is: J val is: K val is: L val is: M val is: N val is: O val is: P val is: Q val is: R val is: S val is: T val is: U val is: V val is: W val is: X val is: Y val is: Z val is: [ val is: val is: ] val is: ^ val is: _ val is: ` val is: a val is: b
shell script 的 追蹤 與 debug
-n : 不執行script,僅查詢語法錯誤
-v: 在執行script之前,現將script的內容輸出到螢幕上
-x: 將使用到的script內容顯示到螢幕上
程式碼:
檢查是否有語法問題 沒有問題就什麼也不輸出
執行:
[[email protected] 2_shell]$ sh -n 12_test.sh
[[email protected] 2_shell]$
程式碼:
將使用到的程式碼顯示出來
執行:
[[email protected] 2_shell]$ sh -x 12_test.sh + val=10 + str=hello + test 10 -eq 10 -a hello == hello + echo 0 0 + test 10 -eq 10 + test hello == hello + echo 0 0
一是在命令列提供引數
$ sh -x ./script.sh
二是在指令碼開頭提供引數
#! /bin/sh -x
第三種方法是在指令碼中用 set命令啟用或禁用引數
set -x和set +x 分別表示啟用和禁用 -x引數 ,這樣可以只對指令碼中的某一段進行跟蹤除錯。
程式碼:
val=10 str="hello" set -x test $val -eq 10 -a "$str" == "hello" echo $? set +x test $val -eq 10 && test "$str" == "hello" echo $?
執行:
[[email protected] 2_shell]$ sh -x 12_test.sh + val=10 + str=hello + set -x + test 10 -eq 10 -a hello == hello + echo 0 0 + set +x 0
:是一個特殊的命令,稱為空命令 ,該命令不做任何事,但 Exit Status總是真。此外 ,也可以執 行
/bin/true或 /bin/false得到真或假的 Exit Status。
檔名替換
這些用於匹配的字元稱為萬用字元 (Wildcard),具體如下 :
萬用字元 * : 匹配 0個或多個 任意字元
? : 匹配 一個任意 字元
[若干字元 ] : 匹配 方括號中任意一個字元的一次出現
執行: [[email protected] 1_shell]$ ls * 2 3 sh_1.sh sh_2.sh [[email protected] 1_shell]$ ls sh_?.sh sh_1.sh sh_2.sh [[email protected] 1_shell]$ ls [s]h* sh_1.sh sh_2.sh
注意, Globbing 所匹配的檔名是由 Shell展開的 ,也就是說在引數還沒傳給程式之前已經展開
了 ,不是ls展開的
命令代換:
由反引號``括起來的也是一條命令 ,Shell先執行該命令 ,然後將輸出結果立刻代換到當前命令列
中。
[[email protected] 1_shell]$ DATE='date' [[email protected] 1_shell]$ echo $DATE date [[email protected] 1_shell]$ DATE=`date` [[email protected] 1_shell]$ echo $DATE 2016年 08月 21日 星期日 11:05:13 CST
例如定義一個變數存放 date命令的輸出 :
命令代換也可以用 $()表示 : $ DATE=$(date)
[[email protected] 1_shell]$ DATE=$(date) [[email protected] 1_shell]$ echo $DATE 2016年 08月 21日 星期日 11:05:56 CST
算術代換 :$(())
用於算術計算 ,$(())中的 Shell變數取值將轉換成整數 ,例如 :
[[email protected] 1_shell]$ v=3 [[email protected] 1_shell]$ echo $((v+3)) 6
$(())中只能用+-*/ 和()運算子 ,並且只能做整數運算。
(( )) 中間支援c語言的寫法
[[email protected] 1_shell]$ i=1;(( i++));echo $i 2 [[email protected] 1_shell]$ i=1;(( i+=5));echo $i 6 [[email protected] 1_shell]$ i=1;(( i>0));echo $? 0 [[email protected] 1_shell]$ i=1;(( i<0));echo $? 1
shell進度條小程式
程式碼:
#!/bin/bash function proc() { i=0; str='' arr=('|' '/' '-' '\\') index=0 while [ $i -le 100 ] #while ((i <= 100)) do printf "[%-100s][%d%%][%c]\r" "$str" "$i" "${arr[$index]}" #這裡不用像c語言一樣fflush重新整理輸出緩衝區 因為 printf是子程序執行 # 子程序退出自動重新整理 str=${str}'#' sleep 0.1 let i++ let index++ let index%=4 #((index%=4)) done printf "\n" } function main() { proc } main
執行:
相關推薦
shell 指令碼-符號-基礎語法
為了便於識別 建議 以.sh 結尾shell指令碼 可以放上所有的命令列的指令(源於bash)shell指令碼 是 解釋型語言 c/c++ 是編譯型語言下面用到的 shell程式碼sh_1.sh#!/bin/bash cd ../ ls pwd解釋型指令碼的執行過
[shell指令碼筆記]基礎/變數
一些基礎用法 #! /bin/bash 宣告使用的shell名稱 exit 0正常退出,exit 1錯誤退出 shell指令碼內增加一行set -x,在執行shell指令碼時($sh -x run.sh),會打印出每一行命令的返回值,從而便於進行除錯。 變數 例子:用於判斷上一步的結果執行正確再執行下
Linux-Shell指令碼程式設計基礎(1)
1. 我們一般在使用Linux系統的時候,都活接觸到shell指令碼的使用,例如我們經常在linux系統中使用的ls命令、cd命令等,都是衣蛾簡單而又基本的shell命令,在 linux系統中我們一般的使用如下的格式來進行shell指令碼的編寫: (1)格式 #!bin/bash e
shell指令碼之基礎
Linux之shell指令碼 Shell就是一個命令列直譯器,它的作用就是遵循一定的語法將輸入的命令加以解釋並傳給系統。開啟文字編輯器(可以使用vi/vim命令來建立檔案),新建一個檔案test.sh,副檔名為sh(sh代表shell)。
如何在 Shell 指令碼中執行語法檢查除錯模式【轉】
我們開啟了 Shell 指令碼除錯系列文章,先是解釋了不同的除錯選項,下面介紹如何啟用 Shell 除錯模式。 寫完指令碼後,建議在執行指令碼之前先檢查指令碼中的語法,而不是檢視它們的輸出以確認它們是否正常工作。 在本系列的這一部分,我們將瞭解如何使用語法檢查除錯模式
Centos7.5-shell指令碼的基礎
本節所講內容: 19.1 shell 基本語法 19.2 SHELL變數及運用 19.3 數學運算 19.4 實戰-升級系統中的java版本到1.8版本-為後期安裝Hadoop叢集做準備 19.1 shell 基本語法 19.1.1 什麼是she
Linux思維導圖之shell指令碼程式設計基礎、習題
思維導圖百度雲分享:連結:https://pan.baidu.com/s/1UMvudlv-xEG_pFtOPdCWhg密碼:x6oa 路徑: 外部命令指令碼執行需在路下,cp到路徑某個路徑下或將外部命令路徑加到路徑裡在其他任何地方均可執行;或絕對路徑相對路徑都可以
一文學會Linux-shell指令碼程式設計基礎
終於到shell 指令碼這章了,在以前筆者賣了好多關子說shell指令碼怎麼怎麼重要,確實shell指令碼在linux系統管理員的運維工作中非常非常重要。下面筆者就帶你正式進入shell指令碼的世界吧。 到現在為止,你明白什麼是shell指令碼嗎?如果明白最好了,不明白
shell基礎語法以及監控進程不存在重新啟動
linux 進程 tail shell detail span () 使用 run 標準輸入 轉碼# dos2unix ./test.sh權限# chmod a+x ./test.sh語法變量var="111"echo $varecho ${var}
Shell基礎語法(二)
-s pac nbsp num mil etc nor 不能 rep if語句基礎格式格式1:if 條件 ; then 語句; fi格式2:if 條件; then 語句; else 語句; fi格式3:if …; then … ;elif …; then …; else …
Shell基礎語法(三)
數組 head p地址 abcd 地址 bcd input seq 網卡ip for語句基本格式:for 變量名 in 條件; do …; done樣例:遍歷目錄或文件#!/bin/bash cd /etc/ ##腳本中如果查詢的目錄在多級目
Linux基礎:Shell指令碼入門
Shell 指令碼(shell script),是一種為 shell 編寫的指令碼程式,業界所說的 shell 通常都是指 shell 指令碼。(區分於shell,shell 和 shell script 是兩個不同的概念。Shell 是一個用 C 語言編寫的程式,它是使用者使用 Lin
shell指令碼語法學習
以下內容僅為個人學習使用,如有錯誤,歡迎指出 持續更新............... 1.首先建立.sh檔案,開啟並在檔案的第一行輸入#!/bin/sh 2.變數的寫法,及用法 test='我是變數'echo "$test"或者echo $test
【shell指令碼】 變數基礎學習整理
1.linux系統環境 echo 'echo /etc/profile ' >> /etc/profile echo 'echo /etc/bashrc' >> /etc/bashrc echo 'echo /root/.bashrc ' >> /root/.bas
Java基礎-----從Excel中獲取資料生成shell指令碼
前言 java讀取Excel的驅動包: 連結:https://pan.baidu.com/s/1ejCR9sS2OUmttFYpQnJkKQ 提取碼:58rm 實現1: 從Excel中讀取表名,由於每個欄位會對應一個表名,故讀取的某列會有若干個連續的表名出現,所以用set集合
批處理指令碼——基礎語法
建立批處理指令碼 批處理指令碼的字尾名是.bat或者.cmd。在批處理指令碼——基礎中已經介紹過一個簡單的指令碼: @echo "Hello world" @PAUSE 並且這個指令碼已經能夠正常執行: 通常可以在執行完指令碼之後返回一個值,來表示這個函式執行狀態: @
Linux Shell基礎 Shell指令碼格式及執行方式
概述 在 Linux 的指令碼中,只要是基於 Bash語法寫的Shell指令碼第一行必須是"#!/bin/bash",用來宣告此檔案是一個指令碼。 執行方式 Shell 指令碼的執行主要有以下兩種方法: 賦予執行許可權,直接執行 這種方法是最常用的 Shell 指令碼執行方法,也最為直接簡單。就是賦
Shell 指令碼 基礎知識點、入門必備
命名:Shell指令碼以 .sh為字尾 shell 是使用 c語言編寫的程式。 #! 告訴系統其後路徑所指定的程式即是解釋此指令碼檔案的 Shell 程式。 / :指的是根目錄 ./: 值得是當前目錄 $# :表示傳入指令碼的引數的個數 shell 數值比較 可以通過這種方
shell指令碼的一些基本入門語法
$#:代表命令列引數個數 $*:代表所有引數 $n:第n個引數 $?:代表最後一個命令返回值 $$:代表當前shell的程序號PID $是變數的引用符 = 是最基本的賦值 := 是覆蓋之前的值 ?= 是如果沒有被賦值過就賦予等號後面的值 += 是
Linux基礎--shell指令碼(1)
shell程式設計: 主要指令碼維護,用於偵聽使用者輸入指令,接受到這些指令,執行相應操作。 指令可以執行,靠的是shell環境變數 設定環境變數 &nbs