溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

3、輸入輸出重定向、bash算術(shù)、正則表達式 學(xué)習(xí)筆記

發(fā)布時間:2020-06-14 08:17:26 來源:網(wǎng)絡(luò) 閱讀:479 作者:開源殿堂 欄目:網(wǎng)絡(luò)安全

輸入輸出重定向和管道

INPUT: 標(biāo)準輸入stdin

OUPUT: 標(biāo)準輸出stdout1

標(biāo)準錯誤stderr2


I/O重定向

輸入重定向:<, <<

<: 輸入重定向

<< EOF: 此處創(chuàng)建文件, Here Document

常用于在腳本中創(chuàng)建文件或生成菜單;

顯示如下菜單

c:show cpu info

d:show disk inf

m:show men info


腳本實現(xiàn)

#!/bin/bash

cat << EOF

c:show cpu info

d:show disk info

m:show men info

EOF


輸出重定向:>, >>

>: 覆蓋輸出

>>: 追加輸出

set -C:禁止使用覆蓋重定向至已經(jīng)存在的文件;

set +C: 關(guān)閉上述特性;

>|:在-C特性下,強制使用覆蓋重定向;


/dev/null: bit bucket,位桶


錯誤重定向:2>, 2>>

2>: 覆蓋

2>>: 追加


同時重定標(biāo)準輸出和錯誤輸出:

COMMAND > /path/to/outfile 2> /path/to/errfile

COMMAND &> /path/to/somefile

COMMAND > /path/to/somefile 2>&1  


管道:

COMMAND1 | COMMAND2 | COMMAND3 | ...       

bash中的算術(shù)運算

declare

-i: 整型變量

-x: 環(huán)境變量, 類似于export


let varName=算術(shù)表達式

varName=$[算術(shù)表達式]

varName=$((算術(shù)表達式))

varName=`expr $num1 + $num2`


如果計算結(jié)果中存在小數(shù),將會被圓整:


操作符:+, -, *, /, %

+=, -=, *=, /=, %=


練習(xí):計算100以內(nèi)所有正整數(shù)之和;

#!/bin/bash

#

declare -i sum=0

for i in {1..100}; do

  let sum=$sum+$i

done


echo "The sum is: $sum."


知識點:bash的單步執(zhí)行:

bash -x /path/to/script


練習(xí):分別計算100以內(nèi)所有偶數(shù)之和和奇數(shù)之和;

#!/bin/bash

declare -i oddSum=0,evenSum=0


for i in `seq 1 2 100`; do

  oddSum=$[$oddSum+$i]

done


for j in `seq 2 2 100`; do

evenSum=$[$evenSum+$j]

done


echo "The Even Sum is: $evenSum, the odd sum is: $oddSum"


練習(xí):計算當(dāng)前系統(tǒng)所有用戶的ID之和;


#!/bin/bash

declare -i uidSum=0

for i in `cut -d: -f3 /etc/passwd`; do

uidSum=$[$uidSum+$i]

done


echo "The UIDSum is: $uidSum."


練習(xí):計算/etc/rc.d/rc.sysinit、/etc/init.d/functions和/etc/issue三個文件的字符數(shù)之和;

#!/bin/bash

#

declare -i bytesCount=0

for file in /etc/rc.d/rc.sysinit /etc/init.d/functions /etc/issue; do

let bytesCount=$bytesCount+`wc -c $file | cut -d' ' -f1`

done


echo $bytesCount


練習(xí):新建用戶tmpuser1-tmpuser10,并計算他們的id之和;

#!/bin/bash

#

declare -i uidSum=0

for i in {1..10}; do

 useradd tmpuser$i 

 let uidSum=$uidSum+`id -u tmpuser$i`

done


知識點:位置參數(shù)

位置參數(shù):

/tmp/test.sh 3 89 

$0: 腳本自身

$1: 腳本的第一個參數(shù)

$2

...


特殊變量:

$#: 位置參數(shù)的個數(shù);

$*,$@: 引用所有的位置參數(shù);


知識點:交互式腳本

read

-t指定輸入超時時間

-p可以輸入提示語


知識點:給變量以默認值

varName=${varName:-value}

如果varName不空,則返回varName的值;否則,則返回value;

如果varName不空,則其值不變;否則,varName會使用value作為其值;


練習(xí):通過鍵盤給定一個目錄路徑,默認為/,來判斷目錄下文件內(nèi)容的類型;


#!/bin/bash


read -t 5 -p "Please input a dirPath:" dirPath

dirPath=${dirPath:-"/"}

echo "The dirPath what you input is: $dirPath"


for filename in "$dirPath/*"

do

        file $filename

done



文本處理工具之grep、egrep和fgrep:


grep: (global search regular expression(RE) and print out the line


文本搜索工具,根據(jù)用戶指定的文本模式對目標(biāo)文件進行逐行搜索,顯示能夠被模式所匹配到的行


格式:grep [options] 'PATTERN' file,...


grep 常用選項:

-v反向,顯示不能被模式所匹配到的行;

-o僅顯示被模式匹配到的字串,而非整行;

-i不區(qū)分字符大小寫, ignore-case

-E支持擴展的正則表達式

-A #顯示匹配行后面的#行

-B #顯示匹配行前面的#行

-C #顯示匹配行前后的#行

--color=auto                         顏色顯示匹配到的字符


正則表達式:是一類字符所書寫出的模式(pattern)

元字符:不表示字符本身的意義,用于額外功能性的描述


基本正則表式的元字符:grep -E

字符匹配:

.匹配任意單個字符

[]匹配指定范圍內(nèi)的任意單個字符

[^]匹配指定范圍外的任意單個字符

[0-9], [[:digit:]]                 匹配數(shù)字0-9

[a-z], [[:lower:]]                 匹配小寫字母a-z

[A-Z], [[:upper:]]                 匹配大寫字母A-Z

[[:alpha:]]匹配所有字母a-zA-Z

[[:alnum:]]匹配所有字母數(shù)字0-9a-zA-Z

[[:space:]]匹配所有空白字符

[[:punct:]]匹配所有標(biāo)點符號


次數(shù)匹配:用來指定匹配其前面的字符的次數(shù)

*匹配任意次,可以是0次或多次

.*匹配任意長度的任意字符

\?匹配0次或1次

\{m\}匹配m次

\{m,n\}最少匹配m次,最多匹配n次

\{m,\}最少匹配m次

\{0,n\}最多匹配n次;

位置錨定:用于指定字符出現(xiàn)的位置

^錨定行首(^char)

$錨定行尾(char$)

^$空白行

\<錨定詞首也可以用(\<char或\bchar)

\>錨定詞尾也可以用(char\>char\b)

分組:

\(\)

引用:

\1后向引用,引用前面的第一個左括號以及與之對應(yīng)的右括號中的模式所匹配到的內(nèi)容

\2

...


He like his lover.

She love her liker.

He love his lover.

She like her liker.


grep "\(l..e\).*\1" test.txt 

    He love his lover.

    She like her liker.


練習(xí):

1、顯示/proc/meminfo文件中以大小寫s開頭的行;

# grep "^[sS]" /proc/meminfo

# grep -i "^s" /proc/meminfo

2、取出默認shell為非bash的用戶;

# grep -v "bash$" /etc/passwd | cut -d: -f1

3、取出默認shell為bash的且其ID號最大的用戶;

# grep "bash$" /etc/passwd | sort -n -t: -k3 | tail -1 | cut -d: -f1

4、顯示/etc/rc.d/rc.sysinit文件中,以#開頭,后面跟至少一個空白字符,而后又有至少一個非空白字符的行;

# grep "^#[[:space:]]\{1,\}[^[:space:]]\{1,\}" /etc/rc.d/rc.sysinit

5、顯示/boot/grub/grub.conf中以至少一個空白字符開頭的行;

# grep "^[[:space:]]\{1,\}[^[:space:]]\{1,\}" /boot/grub/grub.conf 

6、找出/etc/passwd文件中一位數(shù)或兩位數(shù);

# grep --color=auto "\<[0-9]\{1,2\}\>" /etc/passwd

7、找出ifconfig命令結(jié)果中的1到255之間的整數(shù);

# ifconfig | grep -E --color=auto "\<([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>"

8、查看當(dāng)前系統(tǒng)上root用戶的所有信息;

# grep "^root\>" /etc/passwd

9、添加用戶bash和testbash、basher,而后找出當(dāng)前系統(tǒng)上其用戶名和默認shell相同的用戶;

# grep --color=auto "^\([[:alnum:]]\{1,\}\)\>.*\1$" /etc/passwd

10、找出netstat -tan命令執(zhí)行的結(jié)果中以“LISTEN”或“ESTABLISHED”結(jié)尾的行;

# netstat -tan | egrep "(LISTEN|ESTABLISHED)[[:space:]]+"

11、取出當(dāng)前系統(tǒng)上所有用戶的shell,要求:每種shell只顯示一次,且按升序顯示;

# cut -d: -f7 /etc/passwd | sort -u

挑戰(zhàn)題:寫一個模式,能匹配真正意義上的IP地址;(1.0.0.1--223.255.255.254)



egrep: 使用擴展正則表達來構(gòu)建模式,相當(dāng)于grep -E 

字符匹配:

.匹配任意單個字符               

[]匹配指定范圍內(nèi)的任意單個字符   

[^]匹配指定范圍外的任意單個字符   

次數(shù)匹配: 

*匹配任意次,可以是0次或多次                        .*匹配任意長度的任意字符                             ?匹配0次或1次

        +匹配其前面的字符至少1次                            {m}匹配m次                                          {m,n}最少匹配m次,最多匹配n次                         {m,}最少匹配m次                                      {0,n}最多匹配n次;                                    

錨定:

^錨定行首(^char)               

$錨定行尾(char$)               

^$空白行                          

\<錨定詞首也可以用(\<char或\bchar

\>錨定詞尾也可以用(char\>char\b)

分組:

()分組

|        conC|cat的結(jié)果為conC或cat;con(C|c)at的結(jié)果為conCat或concat


引用:                                                                                   

\1向引用,引用前面的第一個左括號以及與之對應(yīng)的右括號中的模式所匹配到的內(nèi)容       \2                                                                                     ...                                                                                    

練習(xí):寫一個腳本,分別統(tǒng)計/etc/rc.d/rc.sysinit、/etc/init.d/functions和/etc/fstab文件中各自以#開頭的行的行數(shù),以及空白行的行數(shù);

#!/bin/bash


for fileName in /etc/rc.d/rc.sysinit /etc/init.d/functions /etc/fstab

do

        line1=`egrep "^#" $fileName | wc -l`

        line2=`egrep "^$" $fileName | wc -l`

        echo "$fileName #:$line1 space:$line2"

done



練習(xí):寫一個腳本,分別復(fù)制/etc/rc.d/rc.sysinit、/etc/init.d/functions和/etc/fstab文件至/tmp目錄中,文件名為原名后跟上當(dāng)前的日期組成;

例如第一個文件復(fù)制后的名稱為/tmp/rc.sysinit-2014-02-16;


#!/bin/bash


for fileName in /etc/rc.d/rc.sysinit /etc/init.d/functions /etc/fstab

do

        cp $fileName /tmp/`basename $fileName`-`date "+%F"`

done

      


練習(xí):寫一個腳本

顯示當(dāng)前系統(tǒng)上所有默認shell為bash的用戶的用戶名、UID以及其在/etc/passwd文件中的行號;


#!/bin/bash

for userName in `grep "bash$" /etc/passwd | cut -d: -f1`

do

        lineNum=`cat -n /etc/passwd | egrep "[[:space:]]+$userName" | egrep -o "[0-9]+[[:space:]]+"`

        userId=`egrep "^$userName" /etc/passwd | cut -d: -f3`

        echo "$lineNum $userName $userId"

done


bash編程之條件判斷:判定后續(xù)操作的前提條件是否滿足。


條件判斷的常用測試類型:

整數(shù)測試

字符測試

文件測試


bash中如何做測試:

test EXPRESSION

[ EXPRESSION ]

` EXPRESSION `


bash中條件判斷使用if:

單分支:

if 條件; then

分支1; 

fi


雙分支:

if 條件; then

分支1;

else

分支2;

fi


多分支:

if 條件1; then

分支1;

elif 條件2; then

分支2;

elif 條件3; then

分支3;

...

else

分支n;

fi


如果文件有空白行,就顯示空白行數(shù);否則,就說明文件無空白行;

#!/bin/bash

#

read -p "Enter a file path: " fileName


if grep "^$" $fileName &> /dev/null; then

        linesCount=`grep "^$" $fileName | wc -l`

        echo "$fileName has $linesCount space lines."

else

    echo "$fileName hava no space line."

fi



bash編程之:整數(shù)測試

二元測試:

num1 OPRAND num2

-gt: 大于[ $num1 -gt $num2 ]

-lt: 小于

-ge:大于等于

-le: 小于等于

-ne: 不等于

-eq: 等于


bash知識點之腳本自定義退出:

exit [n]


練習(xí):判定兩個數(shù)孰大孰小,整數(shù)是通過命令行參數(shù)傳遞而來。


#!/bin/bash

#

if [ $# -lt 2 ]; then

        echo "Stupid..."

        echo "Usage: `basename $0` argu1 argu2"

        exit 4

fi


if [ $1 -gt $2 ]; then

        echo "The max num is $1."

else

    echo "The max num is $2."

fi


bash知識點:只要命令用作條件,就表示引用是其狀態(tài)結(jié)果(即執(zhí)行成功與否),而非命令的輸出結(jié)果,因此,不能使用命令替換符;


grep "^root\>" /etc/passwd

id root


練習(xí):寫一腳本,實現(xiàn)如下功能:

1、讓用戶通過鍵盤輸入一個用戶名

2、如果用戶存在,就顯示其用戶名和UID;

3、否則,就顯示用戶不存在;


#!/bin/bash

read -t 10 -p "Enter a username: " userName

# userName=${userName:-root}

if id $userName &> /dev/null; then

userID=`id -u $userName`

echo "$userName: $userID"

else

echo "$userName not exist."

fi



練習(xí):寫一腳本,實現(xiàn)如下功能:

1、讓用戶通過鍵盤輸入一個用戶名,如果用戶不存在就退出;

2、如果用戶的UID大于等于500,就說明它是普通用戶;

3、否則,就說明這是管理員或系統(tǒng)用戶;


#!/bin/bash



# exit 6 -- 

read -t 10 -p "Enter a username: " userName

if ! id $userName &> /dev/null; then

echo "$userName not exist."

exit 6

fi


userID=`id -u $userName`


if [ $userID -ge 500 ]; then

echo "A common user."

else

echo "Admin or System user."

fi



bash的知識點:

組合條件測試:對條件做邏輯運算

與:條件1 && 條件2

條件1為假,則最終結(jié)果一定為假,因此,條件2將不執(zhí)行;

條件1為真,則最終結(jié)果決于后面條件,因此,條件2必須執(zhí)行; 

或:條件1 || 條件2

條件1為真,則最終結(jié)果一定為真,因此,條件2將不再執(zhí)行;

條件1為假,則最終結(jié)果決于后面條件,因此,條件2必須執(zhí)行; 

非: ! 條件



練習(xí):寫一腳本,實現(xiàn)如下功能:

1、讓用戶通過鍵盤輸入一個用戶名,如果用戶不存在就退出;

2、如果其UID等于其GID,就說它是個"good guy"

3、否則,就說它是個“bad guy”;


#!/bin/bash

# exit 6 -- 

read -t 10 -p "Enter a username: " userName

if ! id $userName &> /dev/null; then

echo "$userName not exist."

exit 6

fi


if [ `id -u $userName` -eq `id -g $userName` ]; then

echo "Good guy."

else

echo "Bad guy."

fi


擴展:判斷當(dāng)前系統(tǒng)上的所有用戶是Good guy還是Bad guy.


for userName in `cut -d: -f1 /etc/passwd`; do

done



練習(xí):寫一個腳本,實現(xiàn)如下功能:

1、添加10個用戶stu1-stu10;但要先判斷用戶是否存在;

2、如果存在,就用紅色顯示其已經(jīng)存在

3、否則,就添加此用戶;并綠色顯示;

4、最后顯示一共添加了幾個用戶;


#!/bin/bash

#

declare -i userCount=0

for i in {1..10}; do

if id stu$i &> /dev/null; then

echo -e "\033[31mstu$i\033[0m exists."

else

useradd stu$i && echo -e "add \033[32mstu$i\033[0m finished."

let userCount++

fi

done


echo "Add $userCount users."



練習(xí):求200以內(nèi)所有3的整數(shù)倍的正整數(shù)的和;

#!/bin/bash

declare -i sum=0

for i in {1..200}; do

if [ $[$i%3] -eq 0 ]; then

let sum+=$i

fi

done


echo "The sum is: $sum."


grep [optinos] "pattern" file...

基本:

    字符匹配:.,[][^]

    次數(shù)匹配:*,\?,\{m\},\{m,n\}

    位置錨定:\<,\b,\>,^,$

    分組:\(\)

    前向引用:\1,\2

擴展:

    字符匹配:.,[][^]

    次數(shù)匹配:*,?,{m},{m,n},+

    位置錨定:\<,\b,\>,^,$

    分組:()

    前向引用:\1,\2

    或a|b

條件判斷

   if condition;then

      statement1

      ....

    fi

    if condition;then

      分支1;

      else

        分支2;

     fi

    if condition;then

      分支1;

    elif condition;then

        分支2;

    ...

    else

        分支n;

     fi

條件測試:

  bash :每個命令,執(zhí)行狀態(tài)都有返回值

       成功:0

       失敗:非0

       $?

       腳本的狀態(tài)返回值:腳本執(zhí)行的最后一條命令:

       自定義腳本狀態(tài)返回值:exit[n]

       引用命令的執(zhí)行結(jié)果:使用`command`或$(command)

       引用命令執(zhí)行成功與否的狀態(tài)結(jié)果:一定是直接執(zhí)行命令。此時,通常需要將執(zhí)行結(jié)果重定向至/dev/null

 條件測試:

    test 測試表達式

    [ 測試表達式 ]

    [[]]:bash中的關(guān)鍵字

 bash的知識點:

      組合條件測試:對條件做邏輯運算

      與:條件1 &&條件2

             條件1為假,則最終結(jié)果一定為假,因此,條件2不予執(zhí)行

             條件1為真,則最終條件結(jié)果決于后面條件,因此,條件2必須執(zhí)行

      或:

             條件1為真,則最終結(jié)果一定為真,因此,條件2不予執(zhí)行

             條件1為假,則最終條件結(jié)果決于后面條件,因此,條件2必須執(zhí)行

      非: 

             與的優(yōu)先級大于或,或的優(yōu)先級大于非

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI