shell的特性之十:輸入輸出重定向和管道
文件描述符(句柄)file descriptor ,FD
是內核用來追蹤現在文件的
INPUT:標準輸入,stdin,0
OUTPUT:標準輸出,stdout,1
標準錯誤輸出:stderr,2
I/O重定向:
<,<<:輸入重定向
<:輸入重定向
<<:此處創建文件,常用於在腳本中創建文件或生成菜單
<< EOF EOF 此處生成文件
>,>>:輸出重定向 !
>:覆蓋輸出,
>>:追加輸出
set -C:禁止覆蓋重定向至已經存在的文件
set +C:關閉上述特性:
>|:在-C 特性下,強制使用覆蓋重定向
/dev/null:bit bucket 位桶
錯誤重定向:2>,2>>,會輸出正確信息
2>:覆蓋
2>>:追加
同時重定標準輸出和錯誤輸出:
命令 > /path/to/outfile 2>/path/to/errfile
命令 &> /path/to/somefile
命令 > /path/to/somefile 2>&1
管道:
Linux:
使用目的單一的小程序
組合小程序完成複雜的任務
command1 | commadn2 | command3
分叉輸出:tee,命令不會處理,會送到下一個管道
bash中的算術運算:
declare
-i:整形變量
-x: 環境變量,類似於export
let:
let varName=算術表達式
varName=$[算術表達式]
varName=$((算術表達式))
varName=`expr 變量1 + 變量2 `
除法運算有餘數被省略(圓整)
操作符:+,—,*,/,%(餘數)
+=,-=,*=,/=,%=
let totalWeight+=2
totalWeight= $[$totalWeight+2]
id++,id--,每次都+1
***bash的單步執行:
bash -x /path/to/script***
知識點:位置參數
$0:腳本自身
$1:腳本的第一個參數
$2:
....
特殊變量:
$#:顯示所有位置參數的個數
$*,$@:引用所有的位置參數
交互式腳本
read -p 交互
給變量以默認值
varName=${varName:-value}
如果varName不空,則返回varName的值;否側,則返回value
如果varName不空,則其值不變;否則,varName會使用value作爲其值
文本處理工具之grep egrep 和fgrep
文本搜索工具,根據用戶指定的文本模式對目標文件進行逐行搜索,顯示能夠模式所匹配到的行
格式:
grep [options]’PATTERN’ file,…
--color=auto
-v:反向匹配,顯示不能被模式匹配到的行
-o:僅匹配被模式匹配到的字串,而非整行
-i:不區分大小寫,ignore-case
-E:支持擴展
-A #:還顯示模式下面的一行
-B #:還顯示模式上面的一行
-C #:前後各顯示一行
egrep:
使用擴展正則表達式來構建模式,相當於 grep -E
元字符:
字符匹配:
.:任意單個字符
[]:指定範圍內的任意單個字符
[^]:指定範圍外的任意單個字符
次數匹配
*:匹配器前面的字符任意次
?:匹配器前面的字符0或1次
+:匹配其前面字符至少一次
{m}:匹配其前面字符m次
{m,n}:至少m次,至多n次
{m,}:至少m次
{0,n}:只讀n次
分組:
():分組
|:或者,ac|bc ac或者bc
fgrep:fast
不解析正則表達式
正則表達式:是一類字符所書寫出的模式
元字符:
不表示字符本身的意義,用於額外功能性的秒速
基本正則表達式和擴展正則表達式
基本正則表達式的元字符:
grep -E
字符匹配:
. : 任意單個字符
次數匹配:用來指定匹配其前面的字符的次數
*:任意次
.*:匹配任意長度的任意字符
\?:前面字符出現0次或者1次的
\{m\}:匹配m次
\{m,n\}:至少m次,至多n次
\{m,\}:至少m次
\{0,n}:至多n次
貪婪模式:儘可能的長的去匹配字符
位置錨定:用於指定字符出現的位置
^:錨定行首
^Char
$:錨定行尾
grepchar$
^$:空白行
單詞的位置錨定
\<char :錨定詞首,\b
char\> : 錨定詞尾,char\b
分組:
n\(\)
\(ab\)*xy
引用:
\1:後向引用,引用前面的第一個左括號以及與之對應的右括號中的模式匹配到的內容,意思是說前面出現一次,在\1這也要出現一次
bash編程之條件判斷
目的:判定後續操作的前提條件是否滿足
條件判斷的常用判斷類型:
整數測試:比較兩個數誰大誰小
字符測試:比較兩個字符是否相等
文件測試:判斷文件的存在和文件類型
$?: 執行狀態碼
0:正確
1-255:錯誤
布爾值:
真 假
邏輯運算:
與運算:
真 && 真 = 真(0)
真 && 假 = 假
假 && 真 = 假
假 && 假 = 假
或運算:
真 || 真 = 真(0)
真 || 假 = 真
假 || 真 = 真
假 || 假 = 假
非運算:
!真 = 假
!假 = 真
bash中如何做測試
test 表達式
[ 測試表達式 ]
[[ 測試表達式 ]]
bash中條件判斷使用if:
單分支:
if 條件; then
分支1;
fi
雙分支:
if 條件; then
分支1;
else
分支2;
fi
多分支:
if 條件; then
分支1;
elif 條件2; then
分支2;
elif 條件3; then
分支3;
...
else
分支n;
fi
只要命令用作條件,就表示引用的是其狀態結果(即執行成功與否),而非命令的輸出結果,因此,不能使用命令替換符.
bash編程之:整數測試
二元測試:
num1 操作符 num2
-eq 等於
-ne 不等於
-le:小於等於
-ge:大於等於
-lt:小於
-gt:大於
練習
1、顯示/proc/meminfo文件中的以大小寫s的開頭的行
grep -i "^s" /proc/meminfo
2、取出默認shell爲非bash的用戶
grep -v "bash$" /etc/passwd | cut -d: -f1
3、取出默認shell爲bash的且其ID號最大的用戶
grep "bash$" /etc/passwd |cut -d: -f1|sort -n -t: -k3|tail -1
4、顯示/etc/rc.d/rc.sysinit文件中,以#開頭,後面跟至少一個空白字符,而後又有至少一個非空白字符的行
grep "^#[[:space:]]\{1,\}[^[:space:]]\{1,\}" /etc/rc.d/rc.sysinit
5、顯示/boot/grub/grub.conf中以至少一個空白字符的行
grep "^[[:space:]]\{1,\}" /boot/grub/grub.conf
6、查出/etc/passwd中一位數或兩位數
grep --color=auto "\<[0-9]\{1,2\}\>" /etc/passwd
7、找出ifconfig命令結果中的1到255之間的整數
ifconfig |grep -E --color=auto "\<([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>"
8、查看當前系統上root用戶的所有信息
grep “\<root\>”/etc/passwd
9、找出netstat -tan命令執行的結果中以“LISTEN”或“ESTABLISHEN”結尾的行
netstat -tan |grep -E “(LISETN|ESTABLISHED)[[:space:]]*"
netstat -tan | grep -E "LISTEN|ESTABLISHED\>"
10、取出當前系統上所有用戶的shell,要求:每種shell中顯示一次,且升序排序顯示
cut -d: -f7 /etc/passwd|sort -u
挑戰題: 寫一個模式,能夠匹配真正意義上的IP地址: (1.0.0.1–223.255.255.254)
ifconfig | grep -E --color=auto "\<([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>\.){3}"
第一篇博客:將清楚grep和egrep的使用
bash腳本練習
讓用戶指定一個文件,判斷如果文件有空白行,就顯示空白行數,否則,就說明文件無空白行
#!/bin/bash
#
read -p "Enter a file path: " filename
if grep "^$" $filename &> /dev/null; then
Count=` grep "^$" $filename | wc -l `
echo "$filename has $Count space lines"
else
echo "no space line"
fi
練習:寫一腳本,實現如下功能:
1、讓用戶通過鍵盤輸入一個用戶名
2、如果用戶存在,就顯示其用戶名和UID;
3、否則,就顯示用戶不存在;
#!/bin/bash
read -p "please input userName :" userName
if grep "^$userName\>" /etc/passwd &>/dev/null ; then
echo "$userName :`id -u $userName` ";
else
echo "no $userName";
fi
練習:寫一腳本,實現如下功能:
1、讓用戶通過鍵盤輸入一個用戶名,如果用戶不存在就退出;
2、如果用戶的UID大於等於500,就說明它是普通用戶;
3、否則,就說明這是管理員或系統用戶;
#!/bin/bash
read -p "please input userName: " userName
if grep "^$userName\>" /etc/passwd & > /dev/null;then
id=`id -u $userName`
if [ $id -ge 500 ];then
echo "then $userName is putong user"
else
echo "The $userName is root root"
fi
else
echo "$userName is not OK !!";
fi
練習:寫一腳本,實現如下功能:
1、讓用戶通過鍵盤輸入一個用戶名,如果用戶不存在就退出;
2、如果其UID等於其GID,就說它是個”good guy”
3、否則,就說它是個“bad guy”;
#!/bin/bash
read -p "please input userName: " userName
if grep "^$userName\>" /etc/passwd & > /dev/null;then
id=`id -u $userName`
g=`id -g $userName`
if [ $id -eq $g ];then
echo "$userName is good guy";
else
echo "$userName is bed guy";
fi
else
exit 6
fi
練習:寫一個腳本,實現如下功能:
1、添加10個用戶stu1-stu10;但要先判斷用戶是否存在;
2、如果存在,就用紅色顯示其已經存大在
3、否則,就添加此用戶;並綠色顯示;
4、最後顯示一共添加了幾個用戶;
#!/bin/bash
for i in {1..10};do
if grep "^stu$i>" /etc/passwd &> /dev/null;then
echo -e "\033[31m stu$i \033[0m is sunflly"
else
useradd stu$i&&echo -e "useradd \033[32m stu$i \033[0m is suefully"
fi
done