Shell基礎之四 變量與運算


shell變量與運算

變量存在於內存中。假設變量str,設置或修改變量屬性時,不帶$號,只有引用變量的時才使用$號。也就是說在內存中,標記變量的變量名稱是str,而不是$str。

變量數據的存儲方式本身是有類型之分的,分為數據(整數、浮點型)和字符,在java等一些語言中,需要提前聲明變量是哪種類型。但是,在bash中變量比較寬松,不需要這么做。
即,變量可以這么分為:

  • 強類型:變量不經過強制轉換,它永遠是這個數據類型,不允許隱式的類型轉換。一般定義變量時必須指定類型、參與運算必須符合類型要求;調用未聲明變量會產生錯誤。如java,c#
  • 弱類型:語言的運行時會隱式做數據類型轉換。無須指定類型,默認均為字符型;參與運算會自動進行隱式類型轉換;變量無須事先定義可直接調用。
    如:bash 不支持浮點數,php

變量命名法則:
1、不能使程序中的保留字:例如if, for
2、只能使用數字、字母及下划線,且不能以數字開頭
3、見名知義
4、統一命名規則:駝峰命名法

駝峰命名法:將變量名首字母大寫,可以全部單詞的首字母大寫,也可以部分單詞的首字母大寫,方便識別。如:StudentName。

一、變量類型

1.1 本地變量

生效范圍為當前shell進程;對當前shell之外的其它shell進程,包括當前shell的子shell進程均無效。

查看進程編號:

echo $$     # 當前進程的進程編號

echo $PPID  #父進程的進程編號

也可以通過
pstree -p  # 查看父子進程樹

 

如:NAME=songtai,這個變量只對當前的shell有用,子shell或父shell無法使用。退出當前shell用exit命令

1、變量賦值:name=‘value’ 。
注意:注意等號左右沒有空格。如果有空格就是進行比較運算符的比較運算了。要想保留空格作為一個整體字符串,用“”括起來。如:STR=“test space”。

注意:變量賦值也可以直接引用變量或命令:

1.直接引用字符串:name=“root"
2.變量引用:name="$USER"
3.命令引用:name=`COMMAND` 或 name=$(COMMAND)

2、變量引用::${name} 或$name
如:

[root@CentOS6 ~]#NAME="hello world"    

[root@CentOS6 ~]#echo "we will say $NAME"   
we will say hello world
"" :弱引用,其中的變量引用會被替換為變量值 '' 強引用,其中的變量引用不會被替換為變量值,而保存原字符串

 

3、釋放變量unset name ,注意變量名前不加前綴$。
    一般賦值完一個變量后,如果后邊不在使用該變量的話,直接釋放該變量。

4、查看所有的變量:不接任何參數的set或者declare命令,輸出結果中包含了普通變量和環境變量。

 

 

5、臨時將普通變量升級為環境(全局)變量:

    export name 或者賦值時 export name="value" ,這樣$name就可以在當前shell和子shell中使用,但是退出腳本或者重新登錄shell都會取消export效果。

6、定義只讀變量:

     readonly name 。這時將無法修改變量值也無法unset變量,只有重新登錄shell才能繼續使用只讀變量。

1.2環境變量(全局變量)

生效范圍為當前shell進程及其子進程。常用大寫字母

env   export  printenv可以查看當前用戶的環境變量。
  常見的環境變量:HOSTNAME、SHELL、HISTSIZE、USER、PATH、PWD、LANG、HOME、LOGNAME、OLD、PS1。

變量聲明、賦值:

export  name=VALUE   
declare  -x  name=VALUE

 

注意:局部變量通過export升級為全局變量,並且對子shell產生影響,但是對父shell不產生影響,父shell仍是原來的賦值。

set查看全部變量,包括局部變量、全局變量。

1.3只讀變量

只能聲明,但不能修改和刪除
聲明只讀變量:

  • readonly  name
  • declare  -r  name
  • unset name不能被撤銷

查看只讀變量:

  • readonly -p

     1.4 補充:()、{ }的用處

  • ( list ):一次性執行執行(相當於開了個子進程bash,執行后又回到父進程
[root@CentOS7 ~]#( umask 666;touch /data/f1 )   #相當於開了一個子shell,umask改為666后創建了一個文件f1,然后再返回到父shell
[root@CentOS7 ~]#ll -d /data/f1
----------. 1 root root 0 Nov 29 14:49 /data/f1

[root@CentOS7 ~]#( name=songtai;echo $name )
songtai

 

{ list }:大括號直接作用於當前shell

[root@CentOS7 ~]#name=songtai
[root@CentOS7 ~]#(  name=sun;echo $name  )
sun
[root@CentOS7 ~]#echo $name
songtai

[root@CentOS7 ~]#{  name=sst;echo $name;  }    # 注意后邊跟;號
sst

  

[root@CentOS7 ~]#x=1;echo $$;( echo $$;echo $x;x=2;echo $x );echo $x
13196
13196    # 注意;兩個子進程號相同,說明()開的子進程與重新開個子shell還是有不同
1
2
1

1.5位置變量和特殊變量

位置變量:在腳本代碼中調用通過命令行傳遞給腳本的參數

$?:上一條代碼執行的回傳指令,回傳0表示標准輸出,即正確執行,否則為標准錯誤輸出。
>> 對於腳本中的回傳指令是0還是其他,看腳本的最后一條命令,如果有標准輸出就是0.否則是其他數值;注意語法錯誤與命令錯誤的區分。
exit [n]:自定義退出狀態碼

$$:當前shell的PID。除了執行bash命令和shell腳本時,$$不會繼承父shell的值,其他類型的子shell都繼承。

$BASHPID:當前shell的PID,這和"$$"是不同的,因為每個shell的$BASHPID是獨立的。而"$$"有時候會繼承父shell的值。

$!:最近一次執行的后台進程PID。

$#:統計參數的個數。

$@:所有單個參數,如"a""b""c""d"。 (個體)

$*:所有參數的整體,如“abcd”。   (整體)

$0:腳本名。 注意:對軟鏈接,$0 顯示的是軟鏈接的名稱

$1……$n:參數位置。

示例:

vim  /bin/args.sh     # 編寫腳本 /bin/args.sh   
#!/bin/bash
echo "1st arg is $1"
echo "2st arg is $2"
echo "3st arg is $3"
echo "4st arg is $4"
echo "all args is  $*"
echo "all args is $@"
echo "the args number is $#"
echo "the script is `basename $0`"

[root@CentOS7 ~]#args.sh   aaa nne  ewd  q
1st arg is aaa
2st arg is nne
3st arg is ewd
4st arg is q
all args is  aaa nne ewd q
all args is aaa nne ewd q
the args numbers is 4
the script is args.sh

 

練習:寫一腳本,通過命令傳遞兩個文本文件路徑給腳本,計算其空白行數之和;

#!/bin/bash

file1_lines=$(grep ^[[:space:]]$  $1 |wc -l)
file2_lines=$(grep ^[[:space:]]$  $2 |wc -l)
echo "the total blank lines: $[$file1_lines+$file2_lines]"

 

shfit 踢出參數 (換位置),默認換一個。
示例:

vim args.sh     # 編輯腳本
#!/bin/bash
echo "1st arg is $1"
echo "2st arg is $2"
echo "3st arg is $3"
echo "4st arg is $4"
echo "all args is  $*"
echo "all args is $@"
echo "the args numbers is $#"
echo "the script is $0"
shift

echo "1st arg is $1"
echo "2st arg is $2"
echo "3st arg is $3"
echo "4st arg is $4"
echo "all args is  $*"
echo "all args is $@"
echo "the args numbers is $#"
echo "the script is $0"
shift

echo "1st arg is $1"
echo "2st arg is $2"
echo "3st arg is $3"
echo "4st arg is $4"
echo "all args is  $*"
echo "all args is $@"
echo "the args numbers is $#"
echo "the script is $0"
shift                                      # 保存退出腳本

 

[root@CentOS7 bin]#args.sh  a b c d       # 執行腳本args.sh  a b c d
1st arg is a
2st arg is b
3st arg is c
4st arg is d
all args is  a b c d
all args is a b c d
the args numbers is 4          # 4個參數           
the script is /root/bin/args.sh
1st arg is b
2st arg is c
3st arg is d
4st arg is 
all args is  b c d
all args is b c d
the args numbers is 3         # 第一個參數去掉,后3個參數依次向前
the script is /root/bin/args.sh
1st arg is c
2st arg is d
3st arg is 
4st arg is 
all args is  c d
all args is c d
the args numbers is 2        # 依上一步的參數,第一個仍然去掉,后2個依次向前
the script is /root/bin/args.sh

 

注意:當參數達到10以上時,用 ${10} 表示第10個參數 ,否則系統會將10都城
字符1和0的組合。

實驗:編寫腳本/root/bin/sumid.sh,計算/etc/passwd文件中的第10個用戶和第20用戶的ID之和。

#!/bin/bash
UID1="`head -n$1 /etc/passwd | cut -d: -f3 |tail -n1`"
UID2="`head -n$2 /etc/passwd | cut -d: -f3 |tail -n1`"
sumid=$[$UID1+$UID2]
echo $sumid

 

此腳本有個問題,直接執行sumid.sh不跟參數的話會報錯。改良如下:

#!/bin/bash
[ $# -ne 2 ] && echo "Args num must be 2" && exit   # 參數數量為2個,則接着運行后邊的命令;參數數量不為2,則運行“Args num must be 2”,然后退出!
UID1="`head -n$1 /etc/passwd | cut -d: -f3 |tail -n1`"
UID2="`head -n$2 /etc/passwd | cut -d: -f3 |tail -n1`"
sumid=$[$UID1+$UID2]
echo $sumid

 

繼續改良:

#!/bin/bash
[ $# -ne 2 ] && echo "Args num must be 2" && exit
[[ ! "$1" =~ ^[0-9]+$ ]] && echo "$1 is not digital" && exit
[[ ! "$2" =~ ^[0-9]+$ ]] && echo "$2 is not digital" && exit
UID1="`head -n$1 /etc/passwd | cut -d: -f3 |tail -n1`"
UID2="`head -n$2 /etc/passwd | cut -d: -f3 |tail -n1`"
sumid=$[$UID1+$UID2]
echo $sumid

 

二、運算

2.1算術預算

bash中的算術運算:help、let
+, -,*, /, %取模(取余), **(乘方)

實現算術運算:

(1) let var=算術表達式   let C=$A+$B

x=10
y=20
let z=x+y  或  let z=\$x+\$y
echo  $z
30

let x++
echo $x  
11

let ++x
echo $x
12

 

(2) var=$[算術表達式]   C=$[$A+$B]

n=8
m=5
sum=$[n+m]   或   sum=$[$n+$m]
echo $sum
13 

 

(3) var=$((算術表達式))     C=$(($A+$B))  推薦使用

(4) var=$(expr arg1 arg2 arg3 ...)
注意:
expr 1 + 2  字符之間有空格
expr 1 \* 2  *需要轉義符

(5) declare –i var = 數值

declare -i x=10
declare -i y=20
echo -i z=x+y
echo $z
30

 

(6) echo ‘算術表達式’ | bc

注意:乘法符號有些場景中需要轉義

(7)bash有內建的隨機數生成器:$RANDOM(0-32767)
echo $[$RANDOM%50] :0-49之間隨機數
示例:

COLOR=$[RANDOM%7+31]  或  COLOR=$((RANDOM%7+31)) 
echo $COLOR  一直是一個數值,除非再執行一次上一條命令,就會換一個數值????
echo -e "\e[1;${COLOR}mcolor\e[0m"

 

COLOR="$[RANDOM%7+31]" ;echo -e "\e[1;${COLOR}mcolor\e[0m" color隨機變色

(8) 賦值
增強型賦值:+=, -=, *=, /=, %=
例如:
let x+=2 表示為x+2后自賦值

自增
let var+=1
let var++ x+1后自賦值

自減
let var-=1
let var--

2.2 邏輯運算

1.真假表示
true : 1
false :0

非:!
!0=1
!1=0

2.&、| 運算

&: and,與運算;有一個假就全假,全是真才為真
0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1

| : or,或運算;全是假才是假,有一個真就是真
0 | 0 = 0
0 | 1 = 1
1 | 0 = 1
1 | 1 = 1

3.&& 短路與;|| 短路或

&& 短路與
0 && 0 = 0
0 && 1 = 0
1 && 0 = 0
1 && 1 = 1

cmd1 && cmd2 :

  • cmd1若為假,那么cmd2就不需要執行,因為最終結果都為假
  • cmd1若為真,那么cmd2需要執行,才能判斷最終結果。

|| 短路或
0 || 0 = 0
0 || 1 = 1
1 || 0 = 1
1 || 1 = 1

cmd1 || cmd2 :

  • cmd1若為假,那么cmd2需要執行,才能判斷最終結果。
  • cmd1若為真,那么cmd2不需要執行,因為最終結果都為真。

cmd1 && cmd2 || cmd3
cmd1為假,那么cmd1&&cmd2 的結果必為假,所以需要執行cmd3,才能判斷最終結果。
cmd1為真,那么要執行cmd2,才能判斷cmd1 && cmd2的結果,若cmd2為真,不執行cmd3,若cmd2為假,執行cmd3.

x=haha;y=xixi;[ $x = $y ] && echo equal || echo qual

 

cmd1 || { cmd2 ; cmd3; } cmd1為假時,運行cmd2和cmd3

^ XOR,抑或:
1 ^ 0 = 1
1 ^ 1 = 0
0 ^ 1 = 1
0 ^ 0 = 0
^異或的兩個值,相同為假,不同為真
^ 的應用示例:兩個數互換

a=4     # 4二進制表示為 100
b=6    #  6二進制表示為 110
let c=a^b
echo  $c
1

a、b的值互換示例:
a=4
b=6
a=$[a^b];b=$[a^b];a=[a^b];echo $a $b    # 第一個分號左側a為a^b的值;第二個分號左側b為第一個a的值與b抑或為4(a);第三個分號的[]中,a為a^b的值,b為4,所以左側的a為6(b)。
6 4

 

2.3 test

  • test EXPRESSION
  • [ EXPRESSION ]
  • [[ EXPRESSION ]]    一個[]是命令,二個[[]]關鍵字
    注意:EXPRESSION前后必須有空白字符

(1)比較字符串

[ “str1” ==“str2” ] : str1是否等於str2
[ “str1” > “str2” ] : str1是否大於str2
[ “str1” < “str2” ] : str1是否小於str2
[ “str1” != “str2” ] : str1是否不等於str2
[ “str1” =~ “str2” ] : str1是否被str2所匹配
[ -z “string”] : 測試字符串或變量是否為空,為空則為真,不空為假
[ -n“string”] : 測試變量是否不為空,不空則為真,空則為假

 

STRING1 =~ STRING2 左側字符串是否能夠被右側的PATTERN模式所匹配,PATTERN可使用擴展正則表達式

    注: 此種表達式一般用於[[ ]] 中

注意: 字符串比較盡量用於[[ ]]中;擴展的正則表達式;字符串盡量加引號引用

Note:用字符串比較時用到的操作數都應該使用引號

str1=aaa
str2=bbb
test $str1  $str2
echo $?
1
注意:
test $str1  $str2
[ $str1 = str2 ]
[[ str1 = str2 ]]    #這個三個表達式的效果相同,注意第二個與第三個里面的空格!

 

實驗:判斷一個字符串是否為空的字符串:

[ -z string ]
[ x"$string" =  "x" ]
[ $string =   ]

 

(2)比較數字

[ a -gt b ] : a是否大於b 
[ a -ge b ] : a是否大於等b 
[ a -eq b ] : a是否等於b 
[ a -ne b ] : 是否不等於b 
[ a -lt b ] : a是否小於b 
[ a -le b ] : a是否小於等於b

實驗:寫腳本,磁盤利用率大於80報警;

#!/bin/bash
DF_USER="`df | grep  "dev/sd" | tr -s " " % | cut -d% -f5 |sort -nr | head -n1`"
[ "$DF_USER" -ge 80 ] && echo warmming!!   # 注意:[] 內的變量要用“”引起來!!

 

(3) 文件比較

存在性測試:
  -a FILE : True if file exists.
  -e FILE : True if file exists. 文件存在為真

是否存在及類型測試:
  -b FILE : 文件是否存在且為塊設備文件
  -c FILE : 是否存在且為字符設備文件
  -d FILE :測試指定路徑是否存在且為目錄
  -f FILE : 是否存在且為普通文件
  -p FILE : 是否存在且為管道文件
  -h FILE 或 -L FILE : 是否存在且為符號鏈接文件
  -S FILE : 是否存在且為套接字

文件權限測試:
  -r FILE : True if file is readable by you.
  -w FILE : True if the file is writable by you. 是否有寫權限
  -x FILE : True if the file is executable by you.

特殊權限測試:
  -u FILE:是否存在並且 擁有suid權限
  -g FILE:是否存在並且 擁有sgid權限;
  -k FILE:是否存在並且 擁有sticky權限;

文件是否有內容:
  -s FILE : 是否存在且非空

時間戳:
  -N FILE:文件自從上一次讀操作后是否被修改過;

從屬關系測試:
  -O FILE:True if the file is effectively owned by you.當前用戶是否為文件的屬主;
  -G FILE:rue if the file is effectively owned by your group.當前用戶是否屬於文件的屬組;

雙目測試:
  FILE1 -ef FILE2:True if file1 is a hard link to file2;FILE1與FILE2是否指向同一個文件系統的相同inode的硬鏈接;
  FILE1 -nt FILE2:True if file1 is newer than file2 (according to modification date);FILE1是否新於FILE2;
  FILE1 -ot FILE2: True if file1 is older than file2;FILE1是否舊於FILE2;

是否被打開:
  -t FD: True if FD is opened on a terminal.文件描述符是否在某終端已經打開

實驗:創建用戶,如果該用戶存在則不創建,如果不存在創建之,並將“magedu”作為其密碼。

#1/bin/bash
[ $# -ne 1 ] &&  echo "your args is wrong" && exit
id $1 &> /dev/null && echo "$1 is exist" && exit  || useradd $1 && echo "magedu" | passwd --stdin  $1
或

#!/bin/bash
id $1 &> /dev/null
[ $? -eq 0 ] && echo "$1 is exist" && exit
useradd $1 && echo magedu | passwd --stdin $1

 

# 文件存在且當前用戶可讀
[ -e FILE ] && [ -r FILE ]
# 主機名不存在或為“localhost.localdomain”時,將其修改為“wybaron.com”
[root@wybaron_host1015 ~]# [ -z "$hostName" -o "$hostName"=="localhost.localdomain" ] && hostname wybaron.com
# 如果/bin/cat存在且為普通文件且是一個當前用戶擁有可執行權限的文件,那么就打印出/etc/fstab的內容
[root@wybaron_host1015 ~]# [ -f /bin/cat -a -x /bin/cat ] && cat /etc/fstab

 

注:摩根定律

  對某個文件即不可獨也不可寫 (對條件取反提出來的時候,需要把里面的條件改為或)

![  -r /etc/fstab -o -w /etc/fstab ]

 

普通用戶下測試:

 

 

(4) bash的組合測試文件
第一種方式:

COMMAND1 && COMMAND2 並且
COMMAND1 || COMMAND2 或者
! COMMAND 非

如:[[ -r FILE ]] && [[ -w FILE ]]

第二種方式:

EXPRESSION1 -a EXPRESSION2 並且
EXPRESSION1 -o EXPRESSION2 或者
! EXPRESSION


必須使用測試命令進行
示例:

[ -z “$HOSTNAME” -o $HOSTNAME "=="localhost.localdomain" ] && hostname www.magedu.com [ -f /bin/cat -a -x /bin/cat ] && cat /etc/fstab

補充:腳本的狀態返回值:

  • 默認是腳本中執行的最后一條件命令的狀態返回值
  • 自定義狀態退出狀態碼:
    exit [n]:n為自己指定的狀態碼;

注意:   腳本中一旦遇到exit命令時,腳本會立即終止;終止退出狀態取決於exit命令后面的數字,因此,整個腳本執行即為結束;

    如果未給腳本指定退出狀態碼,整個腳本的退出狀態碼取決於腳本中執行的最后一條命令的轉態碼

 

三、$-  變量

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 個歷史命令

四、練習題

1、編寫腳本/root/bin/systeminfo.sh,顯示當前主機系統信息,包括主機名,IPv4地址,操作系統版本,內核版本,CPU型號,內存大小,硬盤大小

#!/bin/bash
echo -e "\e[1;35mThis computer is hosted by: \e[0m"
hostname
echo "    "
echo -e  "\e[1;35mMy ip addr is:\e[0m"
ifconfig  | sed -n '2p'|sed -r  's@.*inet (.*) net.*@\1@'
echo "     "
#
echo -e  "\e[1;35mMy OS version is:\e[0m"
cat /etc/centos-release

echo "  "


echo -e "\e[1;35mMy CPU is: \e[0m"
lscpu

echo "   "

echo -e "\e[1;35mMy memory is: \e[0m"
free -m
echo " "

echo -e "\e[1;35mMy disk is: \e[0m"
lsblk | sed -n  '2p'

 

2、編寫腳本/root/bin/backup.sh,可實現每日將/etc/目錄備份到/root/etcYYYY-mm-dd中

#!/bin/bash
echo -e "\e[1;35mbackup ing.... \e[0m"
sleep 3
cp -av  /etc/  /data/etc`date +%F`
echo -e  "\e[1;35mbackup is done \e[0m"

 

3、編寫腳本/root/bin/disk.sh,顯示當前硬盤分區中空間利用率最大的值

#!/bin/bash
echo -e "\e[1;35mThe biggst ratio of your disk's space is \e[0m"
df | grep "/dev/sd"  | tr -s " " %   | cut -d% -f5 | sort -nr |   head -n1

 

4、編寫腳本/root/bin/links.sh,顯示正連接本主機的每個遠程主機的IPv4地址和連接數,並按連接數從大到小排序



5、編寫腳本/root/bin/sumid.sh,計算/etc/passwd文件中的第10個用戶和第20用戶的ID之和

#!/bin/bash
[ $# -ne 2 ] && echo "Args num must be 2" && exit
[[ ! "$1" =~ ^[0-9]+$ ]] && echo "$1 is not digital" && exit
[[ ! "$2" =~ ^[0-9]+$ ]] && echo "$2 is not digital" && exit
UID1="`head -n$1 /etc/passwd | cut -d: -f3 |tail -n1`"
UID2="`head -n$2 /etc/passwd | cut -d: -f3 |tail -n1`"
sumid=$[$UID1+$UID2]
echo $sumid

6、編寫腳本/root/bin/sumspace.sh,傳遞兩個文件路徑作為參數給腳本,計算這兩個文件中所有空白行之和

#!/bin/bash
echo -e "\e[1;35mThe files's blankline is : \e[0m"
grep ^$ $1 $2 | wc -l

 

7、編寫腳本/root/bin/sumfile.sh,統計/etc, /var, /usr目錄中共有多少個一級子目錄和文件

#!/bin/bash
echo -e "\e[1;35mThe number of /etc /var /usr is : \e[0m"
a="`find /etc -maxdepth 1 |wc -l`"
b="`find /usr -maxdepth 1 |wc -l`"
c="`find /var -maxdepth 1 |wc -l`"
sum=$[a+b+c]
echo $sum

 



8、編寫腳本/root/bin/argsnum.sh,接受一個文件路徑作為參數;如果參數個數小於1,則提示用戶“至少應該給一個參數”,並立即退出;如果參數個數不小於1,則顯示第一個參數所指向的文件中的空白行數

#!/bin/bash
[ $# -lt 1 ] && echo -e "\e[1;33m至少應該有一個參數 \e[0m"  && exit
[ $# -ge 1 ] && grep ^$ $1 $2 $3 |wc -l

 

9、編寫腳本/root/bin/hostping.sh,接受一個主機的IPv4地址做為參數,測試是否可連通。如果能ping通,則提示用戶“該IP地址可訪問”;如果不可ping通,則提示用戶“該IP地址不可訪問”

10、編寫腳本/root/bin/checkdisk.sh,檢查磁盤分區空間和inode使用率,如果超過80%,就發廣播警告空間將滿

#!/bin/bash
a="`df | grep "/dev/sd.*" | tr -s " " % |cut -d% -f5 | sort -nr | head -n1`"
b="`df -i | grep "/dev/sd.*" | tr -s " " % |cut -d% -f5 | sort -nr | head -n1`"
[ $a -ge 80 ] && echo -e "\e[1;35mYour disk space is warmming!! \e[0m"
[ $b -ge 80 ] && echo -e "\e[1;35mYour inode numbers is warmming!! \e[0m"

 

11、編寫腳本/bin/per.sh,判斷當前用戶對指定的參數文件,是否不可讀並且不可寫

#!/bin/bash
[ -r $1 -a -w $1 ] ||  echo -e "\e[1;35m您對此文件無讀寫權限 \e[0m"

 

12、編寫腳本/root/bin/excute.sh ,判斷參數文件是否為sh后綴的普通文件,如果是,添加所有人可執行權限,否則提示用戶非腳本文件

#!/bin/bash
[[ $1 =~  \.sh$   ]] && [[ -f $1 ]] || { echo -e "\e[1;35m該文件非腳本文件 \e[0m" ; exit;  }
chmod +x $1
echo -e "\e[1;35m該文件已添加X權限 \e[0m"

 

13、編寫腳本/root/bin/nologin.sh和login.sh,實現禁止和充許普通用戶登錄系統

nologin.sh

#!/bin/bash
echo -e "\e[1;35mYOU WILL OPEN NOLOGIN,PLEASE WAIT \e[0m"
[ -a /etc/nologin ] && exit  || touch /etc/nologin
echo -e "\e[1;35mdone!!!\e[0m"


login.sh #!/bin/bash [ -e /etc/nologin ] && `rm -f /etc/nologin` || echo -e "\e[1;35mnow,you can login \e[0m"

 

14.通過命令行參數給定兩個數字,輸出其中較大的數值;

#!/bin/bash
# which num is the max of two
if [ $# -ne 2 ] ;then
    echo "please input two num"
    exit
fi

if [ $1 -gt $2 ] ;then
    echo "the max num is $1"
else
    echo "the max num is $2"
fi


# 或者

#!/bin/bash
if [ $# -lt 2 ]; then
    echo "Two integers."
    exit 2
fi

declare -i max=$1

if [ $1 -lt $2 ]; then
    max=$2
fi

echo "Max number: $max."

 

15.通過命令行參數給定一個用戶名,判斷其ID號是偶數還是奇數;

#!/bin/bash
if [ $# -ne 1 ] ;then
    echo "please input one args"
    exit
fi

if ! id $1 &>/dev/dull ;then
    useradd $1
fi

idnum=$(id -u $1)
idnum_yu=$[idnum%2]

if [ "$idnum_yu" -eq 1 ];then
    echo "用戶$1的id是奇數"
else
    echo "用戶$1的id是偶數"
fi

 

16.通過命令行參數給定兩個文本文件名,如果某文件不存在,則結束腳本執行;都存在時返回每個文件的行數,並說明其中行數較多的文件;

#!/bin/bash
#
if [ $# -ne 2 ] ;then
    echo "please input two fileadd"
    exit
fi

if [ -a $1 -a -a $2 ];then
    echo "the two files are exits "
else
    echo "the file $1 or $2 is not exits;please input again"
    exit
fi

file1_lines=$(cat $1 |wc -l)
file2_lines=$(cat $2 |wc -l)

if [ "$file1_lines" -gt "$file2_lines" ];then
    echo "the $1's lines is more then $2"
else
    echo "the $2's lines is more then $1"
fi

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM