1. 程式人生 > >在案例中學習shell編程

在案例中學習shell編程

但是 cpuinfo release 方法 個數 情況 logs head 出現

1. 編寫腳本/root/bin/systeminfo.sh, 顯示當前主機系統信息,包括主機名,IPv4 地址,

操作系統版本,內核版本,CPU 型號,內存大小,硬盤大小。

分析:

技術分享

解釋:

此題是一堆命令的堆疊,首先我們很容易在命令行通過命令知道題目中的一些結果。

主機名:hostname命令就可以了。
IPV4地址:ifconfig命令是用來查看ip地址的,只是有很多多余內容,那麽我們可以通過正則表達式,

以及cut命令即可截取。

操作系統版本:使用cat /etc/redhat-relase即可查得。
內核版本:uname -r 可以了。
CPU型號:有一個文件是關於cpu的即/proc/cpuinfo,這裏是要cpu的型號,我們使用grep

結合正則截取含有mode的就很容易得到想要的結果。

內存大小:也有一個文件關於內存的即/proc/meminfo接下來就是截取的問題了。
硬盤大小:使用命令 fdisk -l ,可以查看到詳細信息,接下來使用grep和cut得到想要的列。

在這裏我們需要知道如何調用一個命令可以使用 $(命令)或·命令·這兩種方式 。

得到內存的大小,還可以使用free -m ,計算內存的大小時,如果需要轉換單位,那就得

知道如何進行變量之間的運算了,後面會提到 。

看似簡單的題,更讓我們學會:

1.寫腳本規範很重要

2.使用變量可以讓腳本變得比較有調理

3.熟練使用正則可以讓我們事半功倍

答:

#!/bin/bash
#------------------------
#Filename:systeminfo.sh
#Revision:1.0
#Date:2017-08-08
#Description:systeminfo
#------------------------
Ipv4=`ifconfig eth0 |grep "\<inet\>"|tr -s ‘ ‘ :|cut -d : -f 4`
Sysmode=`cat /etc/redhat-release`
Kermode=`uname -r`
CPU=`lscpu|grep "Model name"|cut -d : -f 2|tr -s ‘ ‘`
Ferr=$[$(cat /proc/meminfo |head -1|grep -o "[[:digit:]]\+")/1024]
Fdisk=`fdisk -l|head -n 2|tail -1 |cut -d , -f 1 |cut -d: -f2`
echo "系統基本信息"
echo "主機名:$(hostname)"
echo "IPV4地址:$Ipv4"
echo "系統版本:$Sysmode"
echo "內核版本:$Kermode"
echo "CPU型號:$CPU"
echo "內存大小:${Ferr}MB"
echo "硬盤大小:$Fdisk"
unset Ipv4 Sysmode Kermode CPU Ferr Fdisk

#########################################################

最後講一下關於變量之間的計算的,在這裏只講三種方法:

方法一 :let var=算數表達式 eg. let count=2+4 echo $count 就變成6了,推薦使用此發

方法二:var=$[算數表達式 ] eg. count=$[2*3] echo $count 變成6了

方法三:var=((算數表達式))和上例差不多。

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

分析:

技術分享

解釋:

既然是計算UID之和,那麽我們首先必須知道如何得出UID,方法並不難,使用cut以冒號為分隔符,就可以得到我

們想要的UID,剩下的事情就是如何計算兩個數的和,在上一題中我們也教大家方法了,這次我們來詳細討論如

何計算兩個變量之和,還有我們需要註意的是,本題中是第10個用戶和第20個用戶UID之和,如何使該題的通用

性增強呢,也就是說,當我們輸入數字(代表第幾個用戶),就能計算之和,這是後我們就需要考慮使用位置

變量,當然也會涉及正則表達式的內容。舉個例子,加入我們輸入的不是10和20,而是一個未知數,只能用

$1和$2替代,得想辦法篩選出$1行和$2行的UID並計算,我們可以使用cat -n 顯示行號,然後利用正則篩選,

用cut截取,下面我們來看看具體實現方法。

答:

#!/bin/bash
#--------------------
#Filename:sumid.sh
#Revision:2.0
#Description:UID sum
#--------------------
read -p "please you input two arg:" number1 number2
root1=$(cat /etc/passwd | head -n $number1 |tail -1 | cut -d: -f3)
root2=$(cat /etc/passwd | head -n $number2 |tail -1 | cut -d: -f3)
let sumid=root1+root2
echo "第$number1個用戶和第$number2個用戶UID之和為:$sumid"
unset number1 number2 root1 root2

----------------------------------------------------------------------------------------------

3. 編寫腳本/root/bin/argsnumsh,接受一個文件路徑作為參數;如果參數個數小於1,則提示用戶

“至少應該給一個參數”,並立即退出;如果參數個數不小於1,則顯示第一個參數所指向的文件中的空白行數。

分析 :

技術分享

解釋:

首先我們知道位置變量有一個是計算參數個數的,即$#,下面我們只要利用好此變量就可以做判斷。
為了考慮全面一點,我們需要可以考慮文件是否存在的情況,最後一個難點是如何計算空白的數量。
^$我們知道是空白行,不要忘記考慮裏面有空格的情況,所以最後結果為“^[[:space:]]*$”.

答:

#!/bin/bash
#--------------------------
#Filename:argsnumsh
#Revision:3.0
#Date:2017-08-10
#Description:determine args
#--------------------------
[ $# -lt 1 ]&&echo "至少應該給一個參數"&&exit 1
[ -f $1 ]||(echo "please you input exist file";exit 1)||exit 1
Space=`grep "^[[:space:]]*$" $1|wc -l `
[ $# -ge 1 ]&&echo "第一個參數文件的空白行為:${Space}行"&&exit 0
unset Space

4.編寫一個腳本/root/bin/createuser.sh,腳本的執行語法必須是:createuser.sh -u username -m password,

選項與參數間可支持多空格,但不能順序顛倒。當未指定正確的選項或參數時,以錯誤輸出方式提示

“createuser.sh -u username -m password ”後退出腳本。用戶名必須以字母開頭,可包括數字和_。

否則不合法。以錯誤輸出提示用戶"用戶名僅包含字母數據和下劃線",當用戶名檢測合法後,判斷用戶名

是否已存在,若存在,再判斷用戶是否已設置過密碼,若設置過密碼,直接退出,未設置,則將密碼設置

為所指定的密碼後以正確輸出方式顯示“username 密碼已更新後退出”當用戶名不存在,則創建用戶,

並為該用戶設置所指定的密碼後以正確輸出方式顯示“用戶username已創建並更新密碼”要求腳本執行

過程中不能有非要求的其他輸出結果出現。腳本在非正確方式退出時應反回給?參數非0值。

分析:

技術分享

解釋:

這道題相對上面幾道題是有一定難度的,但是細細分析還是有思路可循。首先是確定格式,可以想到會使用

位置變量,$1,$2,$3.. 可以確定的有$1為 -u,$3為-m $2 和$4無法確定,但是可以確定參數個數,即$#為4,

這時,我們使用簡單的判斷句是可以解決的。下面進行下一個任務,判斷用戶名是否合法,也就是對$2的判斷,

題目中要求用戶名必須以字母開頭,可包括數字和_,可以使用正則表達式,寫出要求,這應該不難即

“^[[:alpha:]]\([[:alnum:]]\|_\)*”這裏使用的是標準正則表達式,使用此條件去匹配用戶提供的用戶名,

不合符提示題目中的語句。接下來判斷用戶名是否存在,使用的方法當然是使用id命令,若返回值為正確,

那麽接下來是判斷密碼的存在性,使用的方法是看/etc/shadow文件,觀察密碼位的情況,

若用戶不存在時就創建用戶,並設置密碼,這比較簡單,下面解答。

答:

方法一:

#!/bin/bash
#-----------------------
#Filename:createuser.sh
#Revision:7.0
#Date:2017-08-11
#Description:create user
#-----------------------
#判斷用戶名是否規範,並且給出返回值
decide=`echo $2|grep "^[[:alpha:]]\([[:alnum:]]\|_\)*$" &>/dev/null;echo $?`
#判斷用戶是否存在,並給出返回值
id=`id $2 &>/dev/null;echo $?`
#截取用戶密碼位
mima=`getent shadow $2 |cut -d: -f 2`
#判斷第一個參數
if [ "$1" != "-u" ];then
echo "createuser.sh -u username -m password"
exit 1
fi

#判斷第三個參數
if [ "$3" != "-m" ];then
echo "createuser.sh -u username -m password"
exit 1
fi
#判斷參數個數
if [ $# -ne 4 ];then
echo " createuser.sh -u username -m password"
exit 1
fi
#判斷第二個參數
if [ $decide -ne 0 ];then
echo "用戶僅包含字母數字和下劃線"
exit 1
else
if [ $id -eq 0 ];then
if [ "$mima" == "!!" -o "$mima" == "" ];then
echo "$4" |passwd --stdin $2 &>/dev/null
echo "$2密碼已更新"
exit 1
else
exit 1
fi
else

`useradd $2`
`echo $4 |passwd --stdin $2 &>/dev/null`
echo "用戶$2已創建並更新密碼"

fi
fi

unset decide id mima

方法二:

[ $1 = "-u" -a $3 = "-m" -a $# -eq 4 ] &>/dev/null ||(echo createuser.sh -u username -m password 1>&2 && exit

1)&&(echo$2|egrep "\<^[[:alpha:]]([[:digit:]]|_|[[:alpha:]])*$\>" &>/dev/null ||(echo 用戶名僅包含字母數>

據和下劃線 1>&2 ;exit 1 ) &&( `id $2 &>/dev/null` ||(`useradd $2` ;echo $4 |passwd --stdin $2 &>/dev/null &&

echo 用戶${2}已創建並更新密碼;exit 1

) &&(getent shadow $2 |egrep ‘\$‘[[:digit:]]‘\$‘ &>/dev/null &&(echo 密碼已存>

在 1>&2 ;exit 0

)||(

echo $4 |passwd --stdin $2 &>/dev/null &&echo 用戶${2}密碼已更新;exit 1

)||exit 1)||exit 1)||exit 1) ||exit 1

總結:方法一更容易理解一點 ,方法二邏輯思維比較強,各有各的好處 。

在案例中學習shell編程