什么是shell?shell常見種類的介紹

1、簡介
2、read
3、運(yùn)算工具
4、if/then結(jié)構(gòu)
5、while循環(huán)
6、for循環(huán)
?
一、簡介
1、什么是shell
shell是用戶與系統(tǒng)交互作用的界面。shell是一種命令解釋程序,同時(shí)也是一種高級程序設(shè)計(jì)語言
2、shell常見種類
Bourne Shell(/usr/bin/sh或/bin/sh)
Bourne Again Shell(/bin/bash)
C Shell(/usr/bin/csh)
K Shell(/usr/bin/ksh)
Shell for Root(/sbin/sh)
其中:Bash在日常工作中被廣泛使用;同時(shí),Bash也是大多數(shù)Linux系統(tǒng)默認(rèn)的Shell;
3、shell局限性
1.1、需要耗費(fèi)大量資源的任務(wù),特別是對執(zhí)行速度要求較高的場合
1.2、涉及大量的數(shù)學(xué)計(jì)算
1.3.、關(guān)鍵性應(yīng)用(數(shù)據(jù)庫,網(wǎng)站等)
1.4.、設(shè)計(jì)圖形或者GUI的應(yīng)用
1.5.、需要直接訪問硬件
1.6.、開發(fā)閉源的應(yīng)用(相對于開源)
4、基礎(chǔ)
文件系統(tǒng):Linux 的文件系統(tǒng)是一個(gè)包含了目錄和文件的分層的組織結(jié)構(gòu),位于最頂端的叫做根目錄(root directory),用斜杠/ 來表示
目錄: 是一種包含目錄項(xiàng)的文件,每個(gè)目錄項(xiàng)中都包含了文件名
文件名: 目錄的內(nèi)容稱為目錄項(xiàng),目錄項(xiàng)包含了文件名,只有兩種字符不允許出現(xiàn)在文件名中:斜杠,空字符(ASCII 值為0),斜杠用于分隔路徑中的文件名,空字符用來表示路徑的結(jié)尾。文件名的長度通常可以達(dá)到255個(gè)字符
路徑: 一系列文件名連起來,用斜杠分隔,就叫做路徑,路徑用于表示文件的位置;以斜杠開頭的路徑叫做絕對路徑,否則為相對路徑,相對路徑相對于當(dāng)前工作目錄
返回碼:所有命令都有一個(gè)返回值,用0-255之間的整數(shù)來表示;腳本就是一個(gè)命令,它也有返回值,另外,腳本里面的函數(shù)也有返回值
退出腳本的正規(guī)方法是明確地用命令exit [code]來退出,如:exit 0;exit $?
?
二、read
1、定義
read是一個(gè)buildin命令,主要完成對參數(shù)的賦值,類似C語言中的scanf;
其不僅可以賦值變量,還可以賦值數(shù)組;
其輸入不僅是屏幕,還可以是文件描述符
2、實(shí)操
# read a –輸入字符串,將字符串賦值給變量 a;# echo $a
hello world!!
# read name sex age –同時(shí)分別給三個(gè)變量賦值,輸入分隔符默認(rèn)為 空格符
zhangsan male 50
# unset name sex age –刪除變量
# IFS=’;’ –將 read 的輸入分隔符改為 ‘;’
# vim test.sh
#!/bin/bash
prompt=”Please enter your name:”
read -p “$prompt” name
echo “Greetings $name”
?
三、運(yùn)算工具
1、簡單數(shù)學(xué)運(yùn)算
# echo $((1+2**2-3*4/5%6)) –輸出計(jì)算結(jié)果到屏幕
# a=$((1+2**2-3*4/5%6)) –把計(jì)算結(jié)果賦給變量a
# ((a=1+2**2-3*4/5%6)) –同上
# echo “scale=3;10/3” | bc –bc計(jì)算器;保留小數(shù)點(diǎn)后三位
# echo “2^10” | bc –bc計(jì)算器;計(jì)算2的10次方
# awk ‘BEGIN{print 1/3}’ –awk計(jì)算
2、獲取隨機(jī)數(shù)
# od -N4 -tu4 /dev/urandom | sed -n ‘1s/.* //p’ –獲取一個(gè)7位數(shù)的號碼
# od -Ad -w24 -tu4 /dev/urandom –獲取隨機(jī)數(shù)
# od -tu8 /dev/urandom –獲取隨機(jī)數(shù)
# od -tu8 /dev/urandom | sed -r ‘s/^[0-9]+s+//’ | sed -r ‘s/s+/n/g’ |cut -b1-8 |sed -r -n ‘/^.{8}$/p’ | sed ‘s/^/186/’ |head -n5000 |vi – –獲取一萬個(gè)電話號碼
# od -N40000 -tu4 /dev/urandom | sed -r ‘s/^[0-9]+(s+)?//’ | sed -r ‘s/s+/n/g’ | grep -vE ‘^s*$’ > 10k_random –生成一萬個(gè)隨機(jī)數(shù)
# sed -r -n ‘/^.{8}$/p’ 10k_random | head -n 100000 | sed ‘s/^/186/’ > phone_num
3、獲取數(shù)字序列
# seq 10 –獲取1到10
# seq 1 2 10 –獲取1到10,步長為2
# seq 10 100 –獲取10到100
# seq 10 -1 1 –倒序,10到1
?
四、if/then實(shí)例
1、判斷字符 “a” 是否等于 “A”
# vim test.sh
#!/bin/bash
if [[ “a” = “A” ]]; then
if [ “a” = “A” ]; then
  echo “a equals A”
else
  echo “a no equals A”
fi
2、判斷/root/test/test.sh是否存在并具有可執(zhí)行權(quán)限
# vim test.sh
#!/bin/bash
if test -x /root/test/test.sh;then
  echo “/root/test/test.sh is executable”
fi
3、判斷系統(tǒng)是否存在 root 用戶
# vim test.sh
#!/bin/bash
if grep -E –color=auto ^root: /etc/passwd; then
  echo “user root exists”
fi
4、判斷文件類型
# vim test.sh
#!/bin/bash
function isSymbolicLink() {
  file=$1
  flag=$(ls -ld $file | cut -b1)
  test “$flag” = “1”
  return $?
}
file=$1
if isSymbolicLink $file; then
  echo “Symbolic Link”
elif test -d $file; then
  echo “Directory file”
elif test -f $file; then
  echo “Regular file”
elif test -b $file; then
  echo “Block special”
elif test -c $file; then
  echo “Character special”
elif test -p $file; then
  echo “Named pipe”
elif test -S $file; then
  echo “Socket”
else
  echo “Unkown”
fi
5、判斷輸入數(shù)字的大小
# vim test.sh
#!/bin/bash
num=$1
if test “$num” -lt 10 ;then
  echo “小數(shù)字”
elif test “$num” -lt 20;then
  echo “中數(shù)字”
elif test “$num” -lt 30;then
  echo “大數(shù)字”
else
  echo “超大數(shù)字”
fi
6、從標(biāo)準(zhǔn)輸入獲取一個(gè)數(shù)字,并根據(jù)其大小輸出指定字符串
# vim test.sh
#!/bin/bash
echo -n “Enter a number: “
read num
if [ “$num” -lt 100 ]; then
echo “小于100”
elif [ “$num” -ge 100 -a “$num” -lt 200 ]; then
echo “大于等于100小于200”
elif [ “$num” -ge 200 -a “$num” -lt 300 ]; then
echo “大于等于200小于300”
else
echo “其它數(shù)字”
fi
?
五、wihle循環(huán)
1、認(rèn)識
測試 while 關(guān)鍵字后面一條命令的返回碼,條件為真時(shí),程序讀入while循環(huán)體中的指令;0為真。循環(huán)體如下:
while [] –while 后面運(yùn)行 [ ] 命令,測試 [ ] 命令的返回碼
cat /filename | while read line       –while 后面運(yùn)行read 命令,測試 read 命令的返回碼
do
……
done
2、循環(huán)控制語句
continue –終止當(dāng)前循環(huán),開始下一個(gè)循環(huán)
break –終止當(dāng)前循環(huán),并退出循環(huán)體
exit –終止當(dāng)前腳本
3、實(shí)例
# vim test.sh –區(qū)分 continue 與 break 的區(qū)別
#!/bin/bash
while true
do
sleep 1
echo test
continue/break
echo
done
# vim test.sh –區(qū)分 break 與 exit 的區(qū)別
#!/bin/bash
while test -e /data/test/test.sh
do
echo “exists”
sleep 1
break/exit
done
echo “loop end”
# vim test.sh –尋找我們給定的路徑,直到尋到為止
#!/bin/bash
if test $# -ne 1;then
echo “wrong paraneter” >&2
exit
fi
path=$1
while test ! -e “$path”
do
sleep 1
echo “don’t found!!!”
done
echo “found”
# vim test.sh –腳本運(yùn)行指定的時(shí)間,時(shí)間一到就退出;單位為 s
#!/bin/bash
if test $# -ne 1;then
echo “Usage: $(basename $0) TIME” >&2
exit 1
fi
timeLength=$1
beginTime=$(date +%s)
endTime=$(( $beginTime + $timeLength ))
———————————————————
while test $(date +%s) -lt “$endTime”
do
echo “processing…..”
sleep 1
done
———————————————————
while true
do
if test $(date +%s) -ge “$endTime”;then
break
fi
echo “processing…..”
sleep 1
done
———————————————————
echo “time out”
# vim test.sh –循環(huán)讀取文件的每一行,并計(jì)算每行的字符個(gè)數(shù)
#!/bin/bash
file=$1
———————————————————
totalLines=$(wc -l

line=1
while test $line -le $totalLines
do
lineData=$(sed -n “${line}p” $file)
len=$(echo -n $lineData | wc -c)
echo “line ${line}: $len”
line=$(( $line + 1 ))
done
———————————————————
line=1
while read lineData
do
len=$(echo $lineData | wc -c)
echo “line ${line}: $len”
line=$(( $line + 1 ))
done
———————————————————
# vim test.sh — 打印出10行hello world;
#!/bin/bash
while read num
do
echo “hello world”
done
———————————————————
n=1
while [ $n -le 10 ]
do
echo “hello world”
n=$((n+1))
done
———————————————————
# vim test.sh –創(chuàng)建一個(gè)不盡的循環(huán),要求循環(huán)運(yùn)行1分鐘后自動終止
#!/bin/bash
start_time=$(date +%s)
while true
do
cur_time=$(date +%s)
test $((cur_time – start_time)) -ge 10 && break
time=$((cur_time – start_time))
echo “time is $time……”
sleep 1
done
# vim test.sh –先用while 循環(huán)創(chuàng)建100個(gè).txt文件;再將所有文件后綴名改為 .html
#!/bin/bash
count=100
———————————————————
seq $count | while read i
do
touch ${i}.txt
done
ls -1 *.txt | while read oldname
do
newname=$(echo $oldname | sed ‘s/.txt$/.html/’)
mv $oldname $newname
done
———————————————————
while read i
do
touch ${i}.txt
done
while read oldname
do
newname=$(echo $oldname | sed ‘s/.txt$/.html/’)
mv $oldname $newname
done
# vim test.sh –計(jì)算出1000 之內(nèi)的偶數(shù)的和;不能使用管道,因?yàn)楣艿罆勺舆M(jìn)程
#!/bin/bash
sum=0
while read num
do
sum=$(( $sum + $num ))
done

echo “sum: $sum “
# vim test.sh –批量添加100個(gè)郵件用戶,用戶名為u1 至u100,密碼為abc,登錄shell 為/sbin/nologin,只屬于email組
#!/bin/bash
password=abc
group=email
grep -Eq “^${group}:” /etc/group || groupadd $group
while read i
do
useradd u${i} -N -g $group -s /sbin/nologin
passwd u${i} –stdin

done

# vim test.sh –批量刪除剛剛創(chuàng)建的100個(gè)郵件用戶
#!/bin/bash
while read i
do
userdel -r u${i}
done

?
六、for 循環(huán)
在一系列由分隔符隔開的字符串中,按順序每次取其中之一,當(dāng)取完之后,循環(huán)結(jié)束
每次取出的字符串會被保存在一個(gè)變量中,可以在循環(huán)體內(nèi)使用該變量
由分隔符隔開的字符串可以通過以下方法提供:
1、手動輸入字符串,用于循環(huán)指定次數(shù)
# vim test.sh
#!/bin/bash
for i in 1 2 3
do
echo $i
don
2、由變量提供字符串
# vim test.sh
#!/bin/bash
FILES=”/bin/bash /bin/ls /bin/cat”
for file in $FILES
do
echo $file
done
3、程序生成的字符串
# vim test.sh
#!/bin/bash
for n in $(seq 11)
do
  echo $n
done
4、由shell 展開而生成,循環(huán)目錄中的文件
# vim test.sh
#!/bin/bash
for f in /etc/init.d/*
do
echo $f
done
# vim test.sh
5、打印出/dev 下面所有以 loop 開頭的文件的文件名
# vim test.sh
#!/bin/bash
for file in /dev/loop*
do
echo $(basename $file)
done
6、計(jì)算出1000 之內(nèi)的偶數(shù)的和
# vim test.sh
#!/bin/bash
sum=0
for number in $(seq 2 2 998)
do
  sum=$(( $sum + $number ))
done
echo “total: $sum”
7、批量添加100個(gè)郵件用戶,用戶名為u1 至u10,密碼為abc,登錄shell 為/sbin/nologin,只屬于email組
# vim test.sh
#!/bin/bash
function checkGid() {
gid=$1
if ! grep -qE “^$gid:” /etc/group; then
groupadd $gid
fi
}
function isRoot() {
id=$(id | awk -F “[=(]” ‘{print $2}’)
if test “$id” -ne 0; then
echo “must be root” >&2
exit 1
fi
}
count=10
namePrefix=u
password=abc
shell=/sbin/nologin
gid=email
isRoot
checkGid $gid
for num in $(seq $count)
do
name=${namePrefix}${num}
useradd $name -s $shell -g $gid &> /dev/null
if test $? -ne 0; then
echo “failed to create $name” >&2
else
echo “created successfully — $name”
echo “$password” | passwd –stdin $name &> /dev/null
if test $? -ne 0; then
echo “failed to change password for $name” >&2
else
echo “password changed successfully — $name”
fi
fi
done
8、獲取局域網(wǎng)內(nèi)所有電腦的IP 和MAC 地址的對應(yīng)表
# vim test.sh
#!/bin/bash
ipPrefix=192.168.1.
startIp=1
endIp=254
for num in $(seq $startIp $endIp)
do
ip=${ipPrefix}$num
ping -W1 -c1 $ip &>/dev/null &
done
wait
arp -n | sed ‘/incomplete/d’ | awk ‘{print $1,$3}’| cat | sort -n -t ‘.’ -k4,4 | column -t
9、打印出九九乘法表
# vim test.sh
#!/bin/bash
for row in $(seq 9)
do
for col in $(seq $row)
do
echo -n “${col}x${row}=$(( $col * $row )) “
done
echo
done | column -t
10、簡陋計(jì)算器
#!/bin/bash
varnum=3
if test “$#” -ne “$varnum”; then
echo “wrong argument” >&2
exit 1
fi
num1=$1
num2=$3
operator=$2
if test “$operator” = “x”;then
operator=”*”
fi
if test “$operator” = “/” -a “$num2” = 0; then
echo “division by 0” >& 2
exit 1
fi
result=$(( $num1 $operator $num2 ))
echo “$result”
注意:乘法的處理;被除數(shù)為0時(shí)的處理
11、把指定目錄下的某些文件復(fù)制到指定的目錄,要求:
#1. 從命令行參數(shù)接收兩個(gè)參數(shù),分別是源目錄和目標(biāo)目錄
#2. 如果源目錄不存在,應(yīng)該報(bào)錯(cuò)
#3. 如果目標(biāo)目錄不存在,就創(chuàng)建一個(gè)
#4. 如果目標(biāo)已經(jīng)存在但不是目錄,就報(bào)錯(cuò)
#5. 只復(fù)制常規(guī)文件,軟鏈接文件
#6. 對于常規(guī)文件,只復(fù)制大小小于1M 的文件
# vim /test.sh
#!/bin/bash
function displayHelp()
{
echo “Usage: $(basename $0) SRCDIR DSTDIR”
}
function getSize()
{
file=$1
size=$(ls -l $file | awk ‘{print $5}’)
echo $size
}
if test $# -ne 2; then
displayHelp >&2
exit 1
fi
srcdir=$1
dstdir=$2
if test ! -d “$srcdir”; then
echo “$srcdir not exists or is not a directory” >&2
exit 1
fi
if test ! -e “$dstdir”; then
mkdir “$dstdir”
fi
if test ! -d “$dstdir”; then
echo “$dstdir is not a directory” >&2
exit 1
fi
for file in $srcdir/*
do
if test -L $file; then
cp -a $file $dstdir/
elif test -f $file; then
—————————————————
size=$(getSize $file)
if test “$size” -lt 1048576; then
cp -a $file $dstdir/
fi
—————————————————
find $file -type f -size -1024k -exec cp -a {} $dstdir/ ;
—————————————————
fi
done

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點(diǎn)贊12 分享