單引 雙引 反引用[] [[]]
將命令的輸出讀入一個變量中,可以將它放入雙引號中,即可保留空格和換行符(n)
out=$(cat text.txt)
輸出1 2 3
out="$(cat text.txt)"
輸出:
1
2
3
--------------[]一般用于算術(shù)比較
-gt 大于
-lt 小于
-ge 大于等于
-le 小于等于
邏輯與-a
[ $var1 -eq 0 -a $var2 -gt 2 ]
邏輯或
[ $var1 -eq 0 -o $var2 -gt 2 ]
[ condition ] && action 等價于if...fi
if [ "$LOOK_OUT" -gt "85" ]
if [ -e /home/slynux ]; then
...
fi
-----------------[[]]一般用于字符串比較
if [[ -n $str1 ]] && [[ -z $str2 ]] ;
then
commands;
fi
========================
1、字符串判斷
str1 = str2 當(dāng)兩個串有相同內(nèi)容、長度時為真
str1 != str2 當(dāng)串str1和str2不等時為真
-n str1 當(dāng)串的長度大于0時為真(串非空) if [[ -n $1 ]]
-z str1 當(dāng)串的長度為0時為真(空串)
str1 當(dāng)串str1為非空時為真
2、數(shù)字的判斷
int1 -eq int2 兩數(shù)相等為真
int1 -ne int2 兩數(shù)不等為真
int1 -gt int2 int1大于int2為真
int1 -ge int2 int1大于等于int2為真
int1 -lt int2 int1小于int2為真
int1 -le int2 int1小于等于int2為真
3 目錄文件的判斷(if [ ])
-r file 用戶可讀為真
-w file 用戶可寫為真
-x file 用戶可執(zhí)行為真
-f file 文件為正規(guī)文件為真
-d file 文件為目錄為真
-c file 文件為字符特殊文件為真
-b file 文件為塊特殊文件為真
-s file 文件大小非0時為真
-t file 當(dāng)文件描述符(默認為1)指定的設(shè)備為終端時為真
3、復(fù)雜邏輯判斷
-a 與
-o 或
! 非
下面是一些使用實例:
#!/bin/sh
myPath="/var/log/httpd/"
myFile="/var /log/httpd/access.log"
#這里的-x 參數(shù)判斷$myPath是否存在并且是否具有可執(zhí)行權(quán)限
if [ ! -x "$myPath"]; then
mkdir "$myPath"
fi
#這里的-d 參數(shù)判斷$myPath是否存在
if [ ! -d "$myPath"]; then
mkdir "$myPath"
fi
#這里的-f參數(shù)判斷$myFile是否存在
if [ ! -f "$myFile" ]; then
touch "$myFile"
fi
#其他參數(shù)還有-n,-n是判斷一個變量是否是否有值
if [ ! -n "$myVar" ]; then
echo "$myVar is empty"
exit 0
fi
#兩個變量判斷是否相等
if [ "$var1" == "$var2" ]; then
echo '$var1 eq $var2'
else
echo '$var1 not eq $var2'
fi
-----------------獲取名稱.擴展名
file_jpg="sample.jpg"
name=${file_jpg%.*}
輸出sample
file_jpg="sample.jpg"
extension=${file_jpg#*.}
輸出jpg
------------------ time 計算命令執(zhí)行時間
time command
--------------- 重定向
0 stdin標準輸入
1 stdout標準輸出? ?
2 stderr標準錯誤
文件打開模式:
> 等同于1> 截斷模式
>>等同于1>> 追加模式
<用于從文件中讀取至stdin 只讀模式
ls + 2> out.txt
stdout不會有任何輸出,因為錯誤已經(jīng)重定向到out.txt中了
可以將stderr單獨重定向到一個文件,將stdout重定向到另一個文件:
cmd 2>stderr.txt 1>stdout.txt
將stderr轉(zhuǎn)換成stdout,使得stderr和stdout都被重定向到同一個文件:
cmd 2>&1 output.txt
或者
cmd &> output.txt
將stderr輸出丟棄
some_command 2> /dev/null
將文件重定向到命令
cmd < file
向log文件中寫入頭部數(shù)據(jù)
#!/bin/bash
cat <
LOG FILE HEADER
this is a test log file
EOF
-----------------------/dev/null 2>&1
*/1 * * * * root /usr/local/php/bin/php /var/w.php > /dev/null 2>&1
crontab內(nèi)容:50 18 5-30 * * /script/myscript.sh 1> /dev/null 2>&1
其中 1> /dev/null 2>&1是什么意思??
dev/null 為系統(tǒng)垃圾箱
&為后臺運行
但是 myscript 后面的1 和 /null后面的2 還有 &后面的1是什么意思?
1代表標準輸出,2代表錯誤信息輸出.
1>/dev/null 就是指將標準輸出定向到空設(shè)備,
2>&1,的意思是將錯誤輸出定向到和1一樣的輸出設(shè)備,也同樣是空.
換句話說,就是不顯示該程序執(zhí)行過程中的任何信息
cmd >a 2>a 和 cmd >a 2>&1 為什么不同?
cmd >a 2>a :stdout和stderr都直接送往文件 a ,a文件會被打開兩遍 ,由此導(dǎo)致stdout和stderr互相覆蓋。
cmd >a 2>&1 :stdout直接送往文件a ,stderr是繼承了FD1的管道之后,再被送往文件a 。a文件只被打開一遍,就是FD1將其打開
他們的不同點在于:
cmd >a 2>a 相當(dāng)于使用了FD1、FD2兩個互相競爭使用文件 a 的管道;
而cmd >a 2>&1 只使用了一個管道FD1, 但已經(jīng)包括了stdout和stderr。
從IO效率上來講,cmd >a 2>&1的效率更高。
----------------- 算數(shù)運算 let expr
let 可以直接執(zhí)行基本的算數(shù)操作
no1=4
no2=5
let result=no1+no2
echo $result
let no1++
let no1+=6
操作符[] ,expr 和let命令類似
result=$[ no1 + no2 ]
result=$[ $no1 + $no2 ]
result=`expr 3 + 4`
result=$(expr $no1 + 5)
---------------- 浮點運算 bc
#echo "4 * 0.56" | bc
2.24
-----------------獲得字符串長度
var=123456
echo ${#var}
-----------------環(huán)境變量$PATH和export
echo $PATH
PATH通常定義在/etc/environment或/etc/profile或~/.bashrc中
export命令用來設(shè)置環(huán)境變量;
添加新的路徑:
export PATH="$PATH:/home/user/bin"
或者
PATH="$PATH:/home/user/bin"
export PATH
其它環(huán)境變量:HOME,PWD,USER,UID,SHELL
查看進程相關(guān)的環(huán)境變量:
cat /proc/$PID/environ
----------------- printf 格式化輸出
printf "%-5s %-10s %-4sn" No Name Mark
printf "%-5s %-10s %-4.2fn" 1 James 91.32
輸出為:
No Name Mark
1 James 91.32
%-5s 指明了一個格式為左對齊且寬度為5的字符串替代(- 表示左對齊)
-4.2f 表示對浮點數(shù)的處理格式
-------------- 讀取命令返回值$?
cmd;
echo $?;
-------------------------shell 調(diào)試
#!/bin/bash -xv 不用任何其他選項就可以啟用調(diào)試功能了
sh -n sh16.sh 不執(zhí)行script,僅查詢語法
sh -x sh16.sh 將script執(zhí)行過程全部列出來
需要給變量賦值時,可以這么寫:?
變量名=值?
要取用一個變量的值,只需在變量名前面加一個$
a="hello world"
echo "A is:" $a
//if 注意空格
a=$1
if [[ $a -eq 2 ]] ;then
echo "1"
else
echo "2"
fi
if [[ $a = gjslint ]] ;then
echo "1"
exit 0
else
echo "2"
fi
exit 0
===================== 調(diào)用php的sh
#!/bin/bash
if [[ $0 = /* ]]
then
? curfile="$0"
else?
? curfile="$PWD/${0#./}"
fi
#得到curfile 為/usr/local/shell/automation/autoupdate_host.sh
php_path=`dirname $curfile`
#得到php_path為/usr/local/shell/automation
PHP="/usr/local/php/bin/php -q "
PROGRAM="${php_path}/clear_his.php"
#echo $PHP $PROGRAM &
$PHP $PROGRAM &
====================== [和[[有什么不同
$ type [
[ is a shell builtin
$ type [[
[[ is a shell keyword
也就是說[處理里面的字串是當(dāng)作參數(shù)來處理的,而[[對待其中的字串是當(dāng)作表達式來處理的
那么當(dāng)作參數(shù)和表達式有什么不同呢?
表達式中不會有wordsplitting 或者glob expansion,而參數(shù)處理會有
$ ls
file file 1 #注意是2個文件(file 和file 1)
$ (foo="file 1";[[ -f $foo ]]&&echo "$foo is a file")
file 1 is a file
]$ (foo="file 1";[ -f $foo ]&&echo "$foo is a file") # 這里file 1被分成2個word,所以出錯
bash: [: file: binary operator expected
再來看看glob expansion
$ touch '*'
$ (foo="*";[ -f $foo ]&&echo "$foo is a file") #為什么顯示too many arguments,因為 *被擴展為所有目錄下的文件
bash: [: too many arguments
$ (foo="*";[[ -f $foo ]]&&echo "$foo is a file") # *被當(dāng)成普通字符了
* is a file
參數(shù)傳遞中
================ shell判斷文件是否存在
shell判斷文件,目錄是否存在或者具有權(quán)限
#!/bin/sh
myPath="/var/log/httpd/"
myFile="/var /log/httpd/access.log"
# 這里的-x 參數(shù)判斷$myPath是否存在并且是否具有可執(zhí)行權(quán)限
if [ ! -x "$myPath"]; then
mkdir "$myPath"
fi
# 這里的-d 參數(shù)判斷$myPath是否存在
if [ ! -d "$myPath"]; then
mkdir "$myPath"
fi
# 這里的-f參數(shù)判斷$myFile是否存在
if [ ! -f "$myFile" ]; then
touch "$myFile"
fi
# 其他參數(shù)還有-n,-n是判斷一個變量是否是否有值
if [ ! -n "$myVar" ]; then
echo "$myVar is empty"
exit 0
fi
# 兩個變量判斷是否相等
if [ "$var1" = "$var2" ]; then
echo '$var1 eq $var2'
else
echo '$var1 not eq $var2'
fi
-f 和-e的區(qū)別
Conditional Logic on Files
-a file exists.
-b file exists and is a block special file.
-c file exists and is a character special file.
-d file exists and is a directory.
-e file exists (just the same as -a).
-f file exists and is a regular file.
-g file exists and has its setgid(2) bit set.
-G file exists and has the same group ID as this process.
-k file exists and has its sticky bit set.
-L file exists and is a symbolic link.
-n string length is not zero.
-o Named option is set on.
-O file exists and is owned by the user ID of this process.
-p file exists and is a first in, first out (FIFO) special file or named pipe.
-r file exists and is readable by the current process.
-s file exists and has a size greater than zero.
-S file exists and is a socket.
-t file descriptor number fildes is open and associated with aterminal device.
-u file exists and has its setuid(2) bit set.
-w file exists and is writable by the current process.
-x file exists and is executable by the current process.
-z string length is zero.
==================bash中的特殊符號
* 萬用字符,代表一個或多個字符(或數(shù)字)
? 萬用字符,代表一個字母
# 批注,這個最常被使用在 script 當(dāng)中,視為說明!
跳脫符號,將『特殊字符或萬用字符』還原成一般字符
| 分隔兩個管線命令的界定;
; 連續(xù)性命令的界定(注意!與管線命令并不相同)
~ 使用者的家目錄
$ 亦即是變量之前需要加的變量取代值
& 將指令變成背景下工作
! 邏輯運算意義上的『非』 not 的意思!
/ 路徑分隔的符號
>, >> 輸出導(dǎo)向,分別是『取代』與『累加』
' 單引號,不具有變量置換的功能
" 具有變量置換的功能!
` ` 兩個『 ` 』中間為可以先執(zhí)行的指令!
( ) 在中間為子 shell 的起始與結(jié)束
[ ] 在中間為字符的組合
{ } 在中間為命令區(qū)塊的組合!
exit 1:退出整個程序
--------------------dirname
dirname /home/bin/abc
得到/home/bin
------------------------- 循環(huán)讀取每行 :
all_corp=sql.txt
cat $all_corp | while read line
do
echo $line
done
-----------------------整數(shù)比較
-eq 等于,如:if [ "$a" -eq "$b" ]
-ne 不等于,如:if [ "$a" -ne "$b" ]
-gt 大于,如:if [ "$a" -gt "$b" ]
-ge 大于等于,如:if [ "$a" -ge "$b" ]
-lt 小于,如:if [ "$a" -lt "$b" ]
-le 小于等于,如:if [ "$a" -le "$b" ]
if [ $counter -gt 1 ]; then
...
fi
< 小于(需要雙括號),如:(("$a" < "$b"))
<= 小于等于(需要雙括號),如:(("$a" <= "$b"))
> 大于(需要雙括號),如:(("$a" > "$b"))
>= 大于等于(需要雙括號),如:(("$a" >= "$b"))
---------------------------字符串比較
= 等于,如:if [ "$a" = "$b" ]
== 等于,如:if [ "$a" == "$b" ],與=等價
注意:==的功能在[[]]和[]中的行為是不同的,如下:
1 [[ $a == z* ]] # 如果$a以"z"開頭(模式匹配 )那么將為true
2 [ $a == "z*" ] # 如果$a等于z*(字符匹配 ),那么結(jié)果為true
3
4 [ $a == z* ] # File globbing 和word splitting將會發(fā)生
5 [ "$a" == "z*" ] # 如果$a等于z*(字符匹配),那么結(jié)果為true
一點解釋,關(guān)于File globbing是一種關(guān)于文件的速記法,比如"*.c"就是,再如~也是.
但是file globbing并不是嚴格的正則表達式,雖然絕大多數(shù)情況下結(jié)構(gòu)比較像.
!= 不等于,如:if [ "$a" != "$b" ]
這個操作符將在[[]]結(jié)構(gòu)中使用模式匹配.
< 小于,在ASCII字母順序下.如:
if [[ "$a" < "$b" ]]
if [ "$a" < "$b" ]
注意:在[]結(jié)構(gòu)中"<"需要被轉(zhuǎn)義.
> 大于,在ASCII字母順序下.如:
if [[ "$a" > "$b" ]]
if [ "$a" > "$b" ]
注意:在[]結(jié)構(gòu)中">"需要被轉(zhuǎn)義.
具體參考Example 26-11來查看這個操作符應(yīng)用的例子.
-z 字符串為"null".就是長度為0.
-n 字符串不為"null"
注意:
使用-n在[]結(jié)構(gòu)中測試必須要用""把變量引起來.使用一個未被""的字符串來使用! -z
或者就是未用""引用的字符串本身,放到[]結(jié)構(gòu)中。雖然一般情況下可
以工作,但這是不安全的.習(xí)慣于使用""來測試字符串是一種好習(xí)慣.
awk '{print $2}' class.txt | grep '^[0-9.]' > res
iptables 配置文件目錄 /etc/sysconfig/iptables
1.別名 alias,存放位置 $HOME/.bashrc
alias ll='ls -lh'
2.print=helloworld echo ${print}
3.變量:內(nèi)存中一塊存儲單元
本地變量:登陸登出生命周期內(nèi)有效,只限制于本用戶
變量名=變量值
set 查看
LOCAL="TEST"
echo $LOCAL
設(shè)置變量名為只讀,不能在更改,同是也不能在恢復(fù):readonly 變量名,不能刪除。
環(huán)境變量:系統(tǒng)變量,用于所有用戶,只有環(huán)境變量才能用于所有的子進程中,本地變量不可以。
存放于/etc/profile .bash_profile
export 變量名=變量值
env或者export查看
unset 變量名 刪除
變量替換:用變量的值替換變量的名
print=helloworld
echo ${print}
echo ${file1}+${file2}
--------------------位置變量:$0 $1...$9
$0:腳本的名字
$1:腳本的第一變量
$2:腳本的第二變量
向腳本中使用位置參數(shù):./test.sh a b c
向系統(tǒng)命令傳遞參數(shù)
find /root/ -name $1 -print
./test.sh aa
標準變量:bash默認的,可以在/etc/profile中定義
EXINIT
HOME
IFS:設(shè)置分隔符,默認為空格 IFS=":"SHE
LOGNAME
MAIL 默認郵箱位置
MAILPATH多個郵箱時可以設(shè)置
TERM 顯示終端類型
PS1 當(dāng)前shell目錄格式PS1="WANGJIAN:"
ps2 >
pwd顯示當(dāng)前路徑 SHELL 顯示當(dāng)前shell
MANPATH TERMINFO
----------------------------------------------------------特殊變量
$# 變量的個數(shù) $* 顯示腳本全部參數(shù)(參數(shù)列表)
$$腳本運行的當(dāng)前id號
$?顯示前一個命令的運行狀態(tài)
$!后臺運行的最后一個進程id號
#!/bin/bash
echo "tesh.sh"
echo "this is first variable locate:$1"
echo "this is second variable locate:$2"
echo "this is third variable locate:$3"
shift
echo "count:$#"
echo "all list:$*"
echo "pid:$$"
echo "status:$?"
./tesh.sh a b c
declare :設(shè)置或顯示變量 -f只顯示函數(shù)名
export:創(chuàng)建環(huán)境變量 -p顯示所有環(huán)境變量
readonly:設(shè)置只讀變量,不能修改刪除
unset:取消變量的定義。-f 刪除只讀變量
shift:輸入的位置變量改變位置 shift 表位置上移一個位置,shift 2 表上移動兩個位置
雙引號"":引用字符或字符串除$ `
單引號'':直接引用為字符或字符串
反引號``: 作為系統(tǒng)命令執(zhí)行 echo `echo wangjian` wangjian
反斜桿:轉(zhuǎn)義特殊字符($*?)為普通字符
運算符:~取反 << >>移位 &與(同1為1,否0) |或(有1為1,全0為0) ^異或 邏輯運算符號&& ||
運用運算符:$[]:表示對其中的表達式求值 echo $[2+8] echo $[3&4] $[]等價于(())
[base#n] n(base>n)表示基數(shù)從2到36的任何基數(shù) echo [10#8+1] 結(jié)果為9
let a+=3 a=a+3
表達式優(yōu)先級別[] *= || && | ^ & ==
shell 的輸入與輸出
echo
-e 解析轉(zhuǎn)義字符 echo -e "this is a bag nnn"
-n 回車不換行,默認換行 echo -n "this is a cat"
轉(zhuǎn)義字符(c回車不換行 f禁止 t跳格相當(dāng)tab n回車換行)
read:可以從鍵盤或文件的某一行文本中讀入信息,并將其賦給一個變量。
read varible1 varible2
如果只指定了一個變量,那么read將會把所有的輸入賦給改變量,直至遇到文件結(jié)束或回車。如果多個變量,就依次賦給。shell用空格作為變量之間的分隔符。
echo -n "first name:"
read firstname
echo -n "last name:"
read lastname
echo -e "your first name :${firstname}n"
echo -e "your last name :${lastname}n "
read -t 5 variable 5秒鐘超時
read -p "Please enter your Username: " user -p prompt 提示語
[root@ceshiji ~]#Please enter your Username:
read -s -p "Please enter your Password: " pass -s charaters are not echoed. 字符不回顯示。指輸入之后,不在回顯
cat:顯示文件內(nèi)容,創(chuàng)建文件,還可以用它來顯示控制字符
cat file1 file2 file3 同時顯示
cat file1 file2 file3>myfile
cat -v dos.txt (-v 顯示控制符)
管道|:一個命令的輸出傳給一個命令的輸入
df -k|awk '{print $1}'|grep -v 'Filesystem'
tee:把輸出的一個副本輸送到標準輸出,另一個副本拷貝到相應(yīng)的文件中。
tee files 在看見輸出的同時,也將其存入一個文件。一般用于管道之后。
tee -a files 追加到files中 (-a 表追加)
who|tee who.out
標準輸入 0
標準輸出 1
標準錯誤 2
重定向:改變程序運行的輸入來源和輸出來源。
> >> < <<
command>>filename 2>&1
command
if語句必須以單詞fi終止
if $x=sedsrc;then
echo
then
echo
fi
if [ "10" -lt "12" ]
man test
echo -n "enter your name:"
read NAME
if [ "$NAME" == ""];
then
echo "you did not enter any information"
else
echo "your name is $NAME"
fi
if cp myfile.bak myfile;
then
echo "GOOD COPY"
else
echo "basename $0 :error could not copy the files" >&2
case:多選擇語句。如果匹配成功,執(zhí)行匹配的命令
case 值 in
模式1)
命令1
;;
模式2)
命令2
;;
esac
*表任意字符,?表任意單字符 []表范圍
echo -n "enter a number from 1 to 3;"
read ANS
case $ANS in
1)
echo "you select 1"
;;
2)
echo "you select 2"
;;
3)
echo "you select 3"
;;
*)
echo "basename $0 :this is not between 1 and 3" >&2
;;
esac
case $1 in
get|GET)
create_dir
get_config_file
;;
put|PUT)
put_config_file
;;
stop|STOP)
stop_server
;;
start|START)
start_server
;;
restart|RESTART)
restart_server
;;
*)
echo
echo "$Color_err Useage: ./Configure_squid.sh get|put|stop|start|restart $Color_end"
echo
exit 1
;;
esac
for
for 變量 in 列表
do
命令1
命令2
done
for語句 :提供循環(huán)執(zhí)行
使用格式:
for var in values #var是變量 values是一組值
do
語句 #可以是多條語句
done
注意values的值可以全部列出,也可是通配的方式,也可以是某命令的輸出值(如$(ls))。
values的值可以是:
1.列表 in 1 2 3 4 5 用空格隔開
2.文件 in file1 file2 file3
3.變量 in $a 命令輸出賦值
4.命令 in `ls abc*`
5.字符串表 in "orange red blue gray"
5.特殊: 有時沒有in 此時將命令行參數(shù)傳入
for loop
do
find / -name $loop -print
done
[root@localhost ~]# ./sh match
/root/match
[root@localhost ~]# cat sh
#!/bin/bash
for loop
do
find /root -name $loop -print
done
#!/bin/sh
for ((i = 1; i < 254; i++)) #必須用兩個括號
do
arping -I eth0 60.191.82.$i -c 1
done
arp -a > mac_table
當(dāng)變量值在列表里,for循環(huán)即執(zhí)行一次所有命令,使用變量名訪問列表中的取值。命令可為任何有效的shell命令和語句。變量名為任意單詞。in列表用法是可選的,如果不用它,for循環(huán)使用命令行的位置參數(shù)。in列表可以包含替換、字符串和文件名。
for((i=1;i<=10;i=i+1))
do
touch ar_$i;
touch full_$i;
done;
for i in {1..100}
do
.......
done
#!/bin/sh
for i in `seq 1 100`
do
echo $i
done
for loop in 1 2 3 4
do
echo $loop
done
for loop in "orange red blue grey"
do
echo $loop
done
for i in $(ls); do du -sh $i; done | sort -n 查看當(dāng)前目錄的大小按小--大排列
until 條件
do
命令1
命令2
...
done
條件可為任意測試條件,測試發(fā)生在循環(huán)末尾,因此循環(huán)至少執(zhí)行一次.
read look
until [ "$look" ]
do
echo "full"
done
sleep 1
nohup ./test.sh &
while 命令
do
命令1
命令2
...
done
$ cat "filelist.txt"
name.txt□
txtf
□a□b□c□
$ while read file; do echo "$file"; done < "filelist.txt"
name.txt
txtf
a□b□c
echo "press ctrl+d ,stop"
while echo -n "enter a file for you like:" ; read film
do
echo " Yeah ,${file} is a good film "
done
while read line
do
echo $line
done<name.txt
break [n]:跳出循環(huán),如果是在一個嵌入循環(huán)里,可以指定n來跳出的循環(huán)個數(shù)
continue:跳過循環(huán)步驟(本次循環(huán))
continue只能跳過本次循環(huán)。
while :