輸入輸出重定向和管道
站在用戶(hù)的角度思考問(wèn)題,與客戶(hù)深入溝通,找到扎賚諾爾網(wǎng)站設(shè)計(jì)與扎賚諾爾網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶(hù)體驗(yàn)好的作品,建站類(lèi)型包括:網(wǎng)站設(shè)計(jì)、成都網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、空間域名、雅安服務(wù)器托管、企業(yè)郵箱。業(yè)務(wù)覆蓋扎賚諾爾地區(qū)。
INPUT: 標(biāo)準(zhǔn)輸入stdin0
OUPUT: 標(biāo)準(zhǔn)輸出stdout1
標(biāo)準(zhǔn)錯(cuò)誤stderr2
I/O重定向
輸入重定向:<, <<
<: 輸入重定向
<< EOF: 此處創(chuàng)建文件, Here Document
常用于在腳本中創(chuàng)建文件或生成菜單;
顯示如下菜單
c:show cpu info
d:show disk inf
m:show men info
腳本實(shí)現(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特性下,強(qiáng)制使用覆蓋重定向;
/dev/null: bit bucket,位桶
錯(cuò)誤重定向:2>, 2>>
2>: 覆蓋
2>>: 追加
同時(shí)重定標(biāo)準(zhǔn)輸出和錯(cuò)誤輸出:
COMMAND > /path/to/outfile 2> /path/to/errfile
COMMAND &> /path/to/somefile
COMMAND > /path/to/somefile 2>&1
管道:
COMMAND1 | COMMAND2 | COMMAND3 | ...
bash中的算術(shù)運(yùn)算
declare
-i: 整型變量
-x: 環(huán)境變量, 類(lèi)似于export
let varName=算術(shù)表達(dá)式
varName=$[算術(shù)表達(dá)式]
varName=$((算術(shù)表達(dá)式))
varName=`expr $num1 + $num2`
如果計(jì)算結(jié)果中存在小數(shù),將會(huì)被圓整:
操作符:+, -, *, /, %
+=, -=, *=, /=, %=
練習(xí):計(jì)算100以?xún)?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."
知識(shí)點(diǎn):bash的單步執(zhí)行:
bash -x /path/to/script
練習(xí):分別計(jì)算100以?xún)?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í):計(jì)算當(dāng)前系統(tǒng)所有用戶(hù)的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í):計(jì)算/etc/rc.d/rc.sysinit、/etc/init.d/functions和/etc/issue三個(gè)文件的字符數(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í):新建用戶(hù)tmpuser1-tmpuser10,并計(jì)算他們的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í)點(diǎn):位置參數(shù)
位置參數(shù):
/tmp/test.sh 3 89
$0: 腳本自身
$1: 腳本的第一個(gè)參數(shù)
$2
...
特殊變量:
$#: 位置參數(shù)的個(gè)數(shù);
$*,$@: 引用所有的位置參數(shù);
知識(shí)點(diǎn):交互式腳本
read
-t指定輸入超時(shí)時(shí)間
-p可以輸入提示語(yǔ)
知識(shí)點(diǎn):給變量以默認(rèn)值
varName=${varName:-value}
如果varName不空,則返回varName的值;否則,則返回value;
如果varName不空,則其值不變;否則,varName會(huì)使用value作為其值;
練習(xí):通過(guò)鍵盤(pán)給定一個(gè)目錄路徑,默認(rèn)為/,來(lái)判斷目錄下文件內(nèi)容的類(lè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ù)用戶(hù)指定的文本模式對(duì)目標(biāo)文件進(jìn)行逐行搜索,顯示能夠被模式所匹配到的行
格式:grep [options] 'PATTERN' file,...
grep 常用選項(xiàng):
-v反向,顯示不能被模式所匹配到的行;
-o僅顯示被模式匹配到的字串,而非整行;
-i不區(qū)分字符大小寫(xiě), ignore-case
-E支持?jǐn)U展的正則表達(dá)式
-A #顯示匹配行后面的#行
-B #顯示匹配行前面的#行
-C #顯示匹配行前后的#行
--color=auto 顏色顯示匹配到的字符
正則表達(dá)式:是一類(lèi)字符所書(shū)寫(xiě)出的模式(pattern)
元字符:不表示字符本身的意義,用于額外功能性的描述
基本正則表式的元字符:grep -E
字符匹配:
.匹配任意單個(gè)字符
[]匹配指定范圍內(nèi)的任意單個(gè)字符
[^]匹配指定范圍外的任意單個(gè)字符
[0-9], [[:digit:]] 匹配數(shù)字0-9
[a-z], [[:lower:]] 匹配小寫(xiě)字母a-z
[A-Z], [[:upper:]] 匹配大寫(xiě)字母A-Z
[[:alpha:]]匹配所有字母a-zA-Z
[[:alnum:]]匹配所有字母數(shù)字0-9a-zA-Z
[[:space:]]匹配所有空白字符
[[:punct:]]匹配所有標(biāo)點(diǎn)符號(hào)
次數(shù)匹配:用來(lái)指定匹配其前面的字符的次數(shù)
*匹配任意次,可以是0次或多次
.*匹配任意長(zhǎng)度的任意字符
\?匹配0次或1次
\{m\}匹配m次
\{m,n\}最少匹配m次,最多匹配n次
\{m,\}最少匹配m次
\{0,n\}最多匹配n次;
位置錨定:用于指定字符出現(xiàn)的位置
^錨定行首(^char)
$錨定行尾(char$)
^$空白行
\<錨定詞首也可以用(\ \>錨定詞尾也可以用(char\>char\b) 分組: \(\) 引用: \1后向引用,引用前面的第一個(gè)左括號(hào)以及與之對(duì)應(yīng)的右括號(hào)中的模式所匹配到的內(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文件中以大小寫(xiě)s開(kāi)頭的行; # grep "^[sS]" /proc/meminfo # grep -i "^s" /proc/meminfo 2、取出默認(rèn)shell為非bash的用戶(hù); # grep -v "bash$" /etc/passwd | cut -d: -f1 3、取出默認(rèn)shell為bash的且其ID號(hào)最大的用戶(hù); # grep "bash$" /etc/passwd | sort -n -t: -k3 | tail -1 | cut -d: -f1 4、顯示/etc/rc.d/rc.sysinit文件中,以#開(kāi)頭,后面跟至少一個(gè)空白字符,而后又有至少一個(gè)非空白字符的行; # grep "^#[[:space:]]\{1,\}[^[:space:]]\{1,\}" /etc/rc.d/rc.sysinit 5、顯示/boot/grub/grub.conf中以至少一個(gè)空白字符開(kāi)頭的行; # 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用戶(hù)的所有信息; # grep "^root\>" /etc/passwd 9、添加用戶(hù)bash和testbash、basher,而后找出當(dāng)前系統(tǒng)上其用戶(hù)名和默認(rèn)shell相同的用戶(hù); # 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)上所有用戶(hù)的shell,要求:每種shell只顯示一次,且按升序顯示; # cut -d: -f7 /etc/passwd | sort -u 挑戰(zhàn)題:寫(xiě)一個(gè)模式,能匹配真正意義上的IP地址;(1.0.0.1--223.255.255.254) egrep: 使用擴(kuò)展正則表達(dá)來(lái)構(gòu)建模式,相當(dāng)于grep -E 字符匹配: .匹配任意單個(gè)字符 []匹配指定范圍內(nèi)的任意單個(gè)字符 [^]匹配指定范圍外的任意單個(gè)字符 次數(shù)匹配: *匹配任意次,可以是0次或多次 .*匹配任意長(zhǎng)度的任意字符 ?匹配0次或1次 +匹配其前面的字符至少1次 {m}匹配m次 {m,n}最少匹配m次,最多匹配n次 {m,}最少匹配m次 {0,n}最多匹配n次; 錨定: ^錨定行首(^char) $錨定行尾(char$) ^$空白行 \<錨定詞首也可以用(\ \>錨定詞尾也可以用(char\>char\b) 分組: ()分組 | conC|cat的結(jié)果為conC或cat;con(C|c)at的結(jié)果為conCat或concat 引用: \1向引用,引用前面的第一個(gè)左括號(hào)以及與之對(duì)應(yīng)的右括號(hào)中的模式所匹配到的內(nèi)容 \2 ... 練習(xí):寫(xiě)一個(gè)腳本,分別統(tǒng)計(jì)/etc/rc.d/rc.sysinit、/etc/init.d/functions和/etc/fstab文件中各自以#開(kāi)頭的行的行數(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í):寫(xiě)一個(gè)腳本,分別復(fù)制/etc/rc.d/rc.sysinit、/etc/init.d/functions和/etc/fstab文件至/tmp目錄中,文件名為原名后跟上當(dāng)前的日期組成; 例如第一個(gè)文件復(fù)制后的名稱(chēng)為/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í):寫(xiě)一個(gè)腳本 顯示當(dāng)前系統(tǒng)上所有默認(rèn)shell為bash的用戶(hù)的用戶(hù)名、UID以及其在/etc/passwd文件中的行號(hào); #!/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ù)操作的前提條件是否滿足。 條件判斷的常用測(cè)試類(lèi)型: 整數(shù)測(cè)試 字符測(cè)試 文件測(cè)試 bash中如何做測(cè)試: 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ù);否則,就說(shuō)明文件無(wú)空白行; #!/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ù)測(cè)試 二元測(cè)試: num1 OPRAND num2 -gt: 大于[ $num1 -gt $num2 ] -lt: 小于 -ge:大于等于 -le: 小于等于 -ne: 不等于 -eq: 等于 bash知識(shí)點(diǎn)之腳本自定義退出: exit [n] 練習(xí):判定兩個(gè)數(shù)孰大孰小,整數(shù)是通過(guò)命令行參數(shù)傳遞而來(lái)。 #!/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知識(shí)點(diǎn):只要命令用作條件,就表示引用是其狀態(tài)結(jié)果(即執(zhí)行成功與否),而非命令的輸出結(jié)果,因此,不能使用命令替換符; grep "^root\>" /etc/passwd id root 練習(xí):寫(xiě)一腳本,實(shí)現(xiàn)如下功能: 1、讓用戶(hù)通過(guò)鍵盤(pán)輸入一個(gè)用戶(hù)名 2、如果用戶(hù)存在,就顯示其用戶(hù)名和UID; 3、否則,就顯示用戶(hù)不存在; #!/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ě)一腳本,實(shí)現(xiàn)如下功能: 1、讓用戶(hù)通過(guò)鍵盤(pán)輸入一個(gè)用戶(hù)名,如果用戶(hù)不存在就退出; 2、如果用戶(hù)的UID大于等于500,就說(shuō)明它是普通用戶(hù); 3、否則,就說(shuō)明這是管理員或系統(tǒng)用戶(hù); #!/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的知識(shí)點(diǎn): 組合條件測(cè)試:對(duì)條件做邏輯運(yùn)算 與:條件1 && 條件2 條件1為假,則最終結(jié)果一定為假,因此,條件2將不執(zhí)行; 條件1為真,則最終結(jié)果決于后面條件,因此,條件2必須執(zhí)行; 或:條件1 || 條件2 條件1為真,則最終結(jié)果一定為真,因此,條件2將不再執(zhí)行; 條件1為假,則最終結(jié)果決于后面條件,因此,條件2必須執(zhí)行; 非: ! 條件 練習(xí):寫(xiě)一腳本,實(shí)現(xiàn)如下功能: 1、讓用戶(hù)通過(guò)鍵盤(pán)輸入一個(gè)用戶(hù)名,如果用戶(hù)不存在就退出; 2、如果其UID等于其GID,就說(shuō)它是個(gè)"good guy" 3、否則,就說(shuō)它是個(gè)“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 擴(kuò)展:判斷當(dāng)前系統(tǒng)上的所有用戶(hù)是Good guy還是Bad guy. for userName in `cut -d: -f1 /etc/passwd`; do done 練習(xí):寫(xiě)一個(gè)腳本,實(shí)現(xiàn)如下功能: 1、添加10個(gè)用戶(hù)stu1-stu10;但要先判斷用戶(hù)是否存在; 2、如果存在,就用紅色顯示其已經(jīng)存在 3、否則,就添加此用戶(hù);并綠色顯示; 4、最后顯示一共添加了幾個(gè)用戶(hù); #!/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以?xún)?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 擴(kuò)展: 字符匹配:.,[][^] 次數(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 條件測(cè)試: bash :每個(gè)命令,執(zhí)行狀態(tài)都有返回值 成功:0 失敗:非0 $? 腳本的狀態(tài)返回值:腳本執(zhí)行的最后一條命令: 自定義腳本狀態(tài)返回值:exit[n] 引用命令的執(zhí)行結(jié)果:使用`command`或$(command) 引用命令執(zhí)行成功與否的狀態(tài)結(jié)果:一定是直接執(zhí)行命令。此時(shí),通常需要將執(zhí)行結(jié)果重定向至/dev/null 條件測(cè)試: test 測(cè)試表達(dá)式 [ 測(cè)試表達(dá)式 ] [[]]:bash中的關(guān)鍵字 bash的知識(shí)點(diǎn): 組合條件測(cè)試:對(duì)條件做邏輯運(yùn)算 與:條件1 &&條件2 條件1為假,則最終結(jié)果一定為假,因此,條件2不予執(zhí)行 條件1為真,則最終條件結(jié)果決于后面條件,因此,條件2必須執(zhí)行 或: 條件1為真,則最終結(jié)果一定為真,因此,條件2不予執(zhí)行 條件1為假,則最終條件結(jié)果決于后面條件,因此,條件2必須執(zhí)行 非: 與的優(yōu)先級(jí)大于或,或的優(yōu)先級(jí)大于非
網(wǎng)站標(biāo)題:3、輸入輸出重定向、bash算術(shù)、正則表達(dá)式學(xué)習(xí)筆記
本文URL:http://weahome.cn/article/gcedep.html