linux中的變量
變量的分類:
本地變量:只對當前用戶的shell有用
聲明方法:變量名(大寫)= “xxxxx” 或 ’ xxxxx’
環境變量:對當前用戶寫的shell和子shell都有效
聲明方法:export 變量名(大寫)= “xxxxx” 或 ’ xxxxx’
查看環境變量:
[root@server55 tmp]# export
DISPLAY:定義是哪個主機,第幾個屏幕顯示
HISTSIZE:定義history中存取歷史記錄的條數
HOME:當前用戶的家目錄
PATH:執行外部命令(非當前shell自帶的命令)就在PATH顯示的路徑中查找
USER:當前用戶名
SHELL:當前使用的shell
其他查看環境變量的方法:printevn和evn
變量的引用:
eg:
[root@server55 ~]#DIR=’/tmp/script’ 定義變量
[root@server55 ~]#cd $DIR 通過$對變量進行引用
[root@server55 ~]#mkdir $DIR
[root@server55 ~]#unset DIR 釋放變量
查看變量內容:
將字符輸出到顯示器使用echo命令
[root@server55 ~]# echo 字符信息
要查看變量中的字符,需要使用 $變量
[root@server55 ~]# echo $變量 即將變量內字符輸出
特殊變量:$?
$?中的值是上一條命令執行的結果(成功:0,失敗1~255)
[root@server55 ~]#cd
[root@server55 ~]# echo $?
0
[root@server55 ~]# cdd
-bash: cdd: command not found
[root@server55 ~]# echo $?
127
位置變量:$1,$2,$3…
作用:將從輸入內容導入腳本
eg:
腳本:
#!/bin/bash
echo $1
echo $2
echo $3
執行腳本:
[root@server55 ~]#腳本名 字符1 字符2 字符3
執行結果:
字符1 字符2 字符3
算術運算:
linux中默認所有變量都是字符,所以要執行算術運算需加[ ]或$(( ))。
eg:
腳本內容:
#!/bin/bash
echo $[$1+$2]
執行腳本:
[root@server55 ~]#/sum.h 4 5
9
alias別名的查看與創建:
[root@server55 ~]#alias 直接輸入alias顯示當前環境中的別名
[root@server55 ~]# alias cdnet="cd /etc/sysconfig/networking" 給命令創建別名
[root@server55 ~]# cdnet 輸入別名後實現與輸入命令相同的作用
[root@server55 networking]#
[root@server55 ~]#unset cdnet 撤銷別名
無論是直接定義的本地變量還是用export聲明的環境變量,在重新登錄或reboot之後都會消失。若想對其進行長久保存,需要在相關的配置文件中進行修改。
相關的配置文檔目錄:
全局相關:
/etc/profile
/etc/profile.d/*
/etc/bashrc
局部相關(即每個用戶有可以設定自己的一套配置)
~/.bash_profile
~/.bashrc
profile類文件:設置環境變量;
設置某些登陸時就要運行的命令。
bashrc類文件:設置別名;
設置本地變量,和只對當前shell有效的命令。
shell按照過程和應用次序可以分爲:非交互式登陸式的shell和交互式登陸式的shell
非交互式登陸式的shell,啓動系統時自動執行。
啓動順序爲:~/.bashrc→/etc/bashrc→/etc/profile.d/*
交互式登陸式的shell,修要登錄用戶進入系統輸入命令。
啓動順序爲:/etc/profile→/etc/profile.d/*→~/.bash_profile→/etc/bashrc
eg:
通過修改配置文件實現用戶登錄進系統時候,屏幕顯示字符串“Hello,you are root(當前用戶的用戶名)。”
由於是對於每個用戶alluser都有相同的配置,所以應該是全局變量/etc/profile,通過編輯器在文本的最後一行加入“ echo "hello,you are $USER." ”即可。
輸入輸出重定向
標準輸入 standard input /dev/stdin → 0
標準輸出 standard output /dev/stdout →1
錯誤輸出 standard error /dev/stderr →2
以上三個文件均爲鏈接文件。分別指向各自對應的標示符。
所謂重定向redirection:就是改變輸入/輸出的source來源/destination目地。例如本應輸出在顯示器終端上來的經過輸出重定向,將內容輸入某個文件;本應由鍵盤輸入的字符信息,經過輸入重定向改爲由某個文件導入。
覆蓋 追加
輸入重定向: < <<
輸出重定向: > >>
錯誤重定向: 2> 2>>
不論輸出正確還是錯誤都進行重定向:&>
eg:
[root@server55 ~]#ls > /tmp/ls.out #將輸出結果從監視器重定向到指定目錄下的文檔
[root@server55 ~]#lss 2> /tmp/lserr.out #lss爲錯誤命令,重定向錯誤提示信息到指定文件
[root@server55 ~]#ls &> /tmp/ignore.out
[root@server55 ~]#lss &> /tmp/ignore.out #不論命令正確與否輸出結果都重定向到指定文件
>>:用法與>相同,>>爲向目的文件中追加新信息,而>則是直接覆蓋。
注意:&>>是不存在的,若要實現類似的功能,則要遵循特定的指令格式:
[root@server55 ~]#ls >> /tmp/ignore.out 2>> /tmp/ignore.err
#即正確輸出重定向到前文件,錯誤輸出重定向到後文件
自定義輸出重定向:
exec 3~9> 文件 #定義n爲自定義的重定向文件
命令輸出 >&3 #輸出到自定義重定向文件中
自定義重定向輸出符:>&
eg:
[root@server55 ~]#exec 3> /tmp/ide.out #聲明自定義重定向爲/tmp/ide.out
[root@server55 ~]#ls >&3 #將輸出結果送入自定義重定向文件
作用:在頻繁使用重定向輸出時,文件會頻繁的進行打開關閉,自定義重定向後自定義文件一直處於打開狀態,直到撤銷。
[root@server55 ~]#exec 3>&- #輸出給 – 表明撤銷
管道
管道由分頁符 | 實現,格式爲 命令1|命令2|命令3,實現的作用爲 將命令1的執行結果送至命令2的參數,執行完成命令2後再將結果送至命令3處供命令3執行,即前一命令的輸出作爲後一命令的輸入。使用管道也可直接向文件導入輸出流,即實現輸出重定向。
eg:
[root@server55 ~]# echo "123456" | passwd hu --stdin
Changing password for user hu.
passwd: all authentication tokens updated successfully.
管道分流的實現 tee
命令1的執行結果同時給命令2和命令3
[root@server55 ~]# ls /etc |tee /tmp/lss.out |less
注意:管道向文件導入輸出流數據。
管道和輸出重定向本質都是改變輸出的方向。
全局搜索正則表達式
[root@server55 ~]# grep 選項 樣式 文件目錄或文本內容
-i 不區分大小寫
-v 與默認動作相反(grep –v “root” 意爲查詢不包含root的內容)
-n 顯示匹配行所在的行號
--color 將匹配字符高亮顯示
樣式
其中"\<" "\>" "\{ , \}" "\( \) \1" 可理解成以轉義字符 \ 反斜槓開頭的符號來記憶;"\( \) \1" 括號內字符與普通字符匹配無區別,其只是將括號內容放入寄存器並進行編號,然後用\1(轉義的1)進行調用。
練習:
1、顯示/proc/meminfo文件中以不區分大小的s開頭的行;
2、顯示/etc/passwd中以nologin結尾的行;
3、顯示/etc/inittab中以#開頭,且後面跟一個或多個空白字符,而後又跟了任意字符的行;
4、顯示/etc/inittab中包含了:一個數字:(即兩個冒號中間一個數字)的行;
5、顯示/boot/grub/grub.conf文件中以一個或多個空白字符開頭的行
6、顯示/etc/inittab文本中以一個數字開頭並以一個與開頭數字相同的數字結尾的行;
7、ifconfig命令可以顯示當前主機的IP地址相關的信息等,如果使用grep等文件處理命令取出本機的各IP地址,要求不包括127.0.0.1;
8、顯示/etc/sysconfig/network-scripts/ifcfg-eth0文件中的包含了類似IP地址點分十進制數字格式的行;
1.[root@server55 tmp]# grep --color ^[sS] /proc/meminfo
SwapCached: 0 kB
SwapTotal: 522104 kB
SwapFree: 522104 kB
Slab: 34588 kB
2.[root@server55 tmp]# grep --color "nologin$" /etc/passwd
3.[root@server55 tmp]# grep --color ^\#" "*.* /etc/inittab
4.[root@server55 tmp]# grep --color :[0-9]: /etc/inittab
[root@server55 tmp]# grep --color ":[[:digit:]]:" /etc/inittab
5. [root@server55 tmp]# grep "^[[:space:]]\{1,\}" /boot/grub/grub.conf
6. [root@server55 tmp]# grep --color "^\([[:digit:]]\).*\1$" /etc/inittab
7. [root@server55 tmp]# ifconfig | grep "inet add" | grep -v "127.0.0.1"| cut -d":" -f2 | cut -d" " -f1
8.[root@server55 tmp]#grep --color "[[:digit:]]\{1,3\}\.[[:digit:]]\{1,3\}\.[[:digit:]]\{1,3\}\.[[:digit:]]\{1,3\}" /etc/sysconfig/network-scripts/ifcfg-eth0
命令的連接
命令1 && 命令2
當命令1成功執行,纔會繼續執行命令2;
命令1 | | 命令2
當命令1執行失敗,纔會執行命令2;
具體實例見最後的shell script。
Shell Script練習
與今天shell script相關的命令:
文本截取命令cut:
[root@server55 ~]# cut 選項 文檔
-d 定義分隔符(由定義分隔符將文本分成若干的段)
-f num 定義截取第幾段(-f1,2,3,5可同時截取多個段)
ping命令:
[root@server55 ~]# ping 選項 ip地址
-c 設置ping向目的ip的次數
-W設置超時等待時間
寫一個腳本:
創建用戶test1~10,將密碼設置爲用戶名。
#!/bin/bash
#
for I in `seq 1 10`;do
useradd "test$I"
echo "test$I" | passwd "test$I" --stdin
done
寫一個腳本:
1、設定變量FILE的值爲/etc/passwd
2、使用循環讀取文件/etc/passwd的第2,4,6,10,13,15行,並顯示其內容;(提示:LINE=`head -2 /etc/passwd | tail -1`可以取得第2行)
3、把這些行保存至/tmp/mypasswd文件中
#!/bin/bash
FILE='/etc/passwd'
for I in 2 4 6 13 15;do
LINE=`head -$I $FILE | tail -1`
echo "$LINE"
echo $LINE>>/tmp/mypasswd
done
使用自定義輸出重定向:
#!/bin/bash
exec 3>> /tmp/passwd
FILE='/etc/passwd'
for I in 2 4 6 13 15;do
LINE=`head -$I $FILE | tail -1`
echo "$LINE"
echo $LINE >&3
done
exec 3>&-
寫一個腳本:
1、設定變量FILE的值爲/etc/passwd
2、依次向/etc/passwd中的每個用戶問好,形如: (提示:LINES=`wc -l /etc/passwd | cut -d" " -f1`)Hello, root.
3、統計一共有多少個用戶
#!/bin/bash
#
let SUM=0
FILE='/etc/passwd'
LINE=`wc -l $FILE | cut -d" " -f1`
for I in `seq 1 $LINE`;do
NAME=`head -$I $FILE | tail -1 |cut -d: -f1`
echo hello,$NAME
SUM=$[$SUM+1]
done
echo $SUM
注意:此時不用{1..$LINE} 由於head命令對{ }中內容不能讀取
寫一個腳本:
添加10個用戶user1到user10,但要求只有用戶不存在的情況下才能添加;
#!/bin/bash
for I in `seq 1 10`;do
grep "user$I" /etc/passwd &> /dev/null || useradd user$I
done
寫一個腳本:
通過ping命令測試192.168.0.151到192.168.0.254之間的所有主機是否在線,
如果在線,就顯示"ip is up."
如果不在線,就顯示"ip is down."
#!/bin/bash
for I in {151..254};do
ping -c1 -W1 192.168.0.$I &> /dev/null && echo "192.168.0.$I is up." || echo "192.168.0.$I is down."
done