




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
.74/74高級Bash腳本編程指南:從一個簡單的script出發(fā)成于堅持,敗于止步開始shell腳本編程學(xué)習(xí),路途遍布荊棘啊,O<∩_∩>O~,開始吧,這是"高級Bash腳本編程指南"為我們量身打造的"HelloWorld",其實也不算,因為這個只是我們無比熟悉的命令的堆疊嘛!O<∩_∩>O清除/var/log下的log文件[html]viewplaincopy#
清除,當(dāng)然要使用root身份來運行這個腳本.
cd
/var/log
cat
/dev/null
>
messages
cat
/dev/null
>
wtmp
echo
"Logs
cleaned
up."
像分析helloworld一樣,我們也說下這個shell腳本吧!這根本就沒什么稀奇的,只不過是命令的堆積,來讓從console或者xterm中一個一個的輸入命令更方便一些.好處就是把所有命令都放在一個腳本中,不用每次都敲它們.這樣的話,這個腳本就成為了一個工具,對于特定的應(yīng)用來說,這個腳本就很容易被修改或定制.其中,第一條#后面帶一句話,你該猜到了,沒錯,這是注釋,將來你會經(jīng)常和他打交道,先見下面吧cd/var/log這簡單,我天天在用,我就別廢話了cat/dev/null>messages這個前面簡單我也天天用,不過后面是什么,有可能就像"仝"這個字,上下分開,一年級小學(xué)生都會,可是這樣拼在一起,就不一定了,具體是什么字自己去查哈,這里告訴這條語句的作用是把cat/dev/null得到的內(nèi)容保存到messages中,先混個臉熟吧下一句你該樂了,該學(xué)了一招嘛但是這里我還是決定多花點時間說說這里的這個/dev/null,因為也許你還不知道為什么要保存到messages和wtmp中,而且cat的為什么是/dev/null在Linux操作系統(tǒng)中/dev/null和/dev/zero是兩個相似卻又很特殊的文件,特別是在shell腳本開發(fā)和系統(tǒng)運維過程中會經(jīng)常用這兩個文件,因此作為Linux系統(tǒng)工程師,你必須了解這兩個文件的區(qū)別和用法。一、/dev/null的用法:我們可以把/dev/null文件看作"黑洞",它非常等價于一個只寫文件,所有寫入/dev/null文件的內(nèi)容都會丟失,而從/dev/null文件中也讀取不到任何內(nèi)容。然而,也正因為這些特點,在shell腳本開發(fā)和命令行維護(hù)時,/dev/null文件就可大展身手,顯得非常的有用。1.禁止標(biāo)準(zhǔn)輸出例如:cat查看$filename文件,其回顯信息將為空[html]viewplaincopy#
cat
$filename
>
/dev/null
2.禁止標(biāo)準(zhǔn)錯誤例如:rm刪除文件時,若$badname文件不存在,那么如下的方式則會過濾回顯的錯誤信息[html]viewplaincopy#
rm
$badname
2>
/dev/null
3.禁止標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯誤的輸例如:cat查看$filename文件[html]viewplaincopy#
cat
$filename
2>/dev/null
>/dev/null
#如果"$filename"不存在,將不會有任何錯誤信息提示.#如果"$filename"存在,文件的內(nèi)容不會打印到標(biāo)準(zhǔn)輸出.#因此上面的代碼根本不會輸出任何信息.4.清除日志文件內(nèi)容例如:[html]viewplaincopy#
cat
/dev/null
>
/var/log/wtmp
#
cat
/dev/null
>
/var/log/messages
#:>/var/log/messages有同樣的效果,但不會產(chǎn)生新的進(jìn)程.〔因為:是內(nèi)建的這里你還要知道怎么就會清空了wtmp和messages這兩個文件呢?因為你cat/dev/null的結(jié)果為空啊,然后你又把空內(nèi)容保存到這兩個文件中,不就相當(dāng)于清空嘛5./dev/null的特殊用法,程序打印的日志將不再記錄,避免系統(tǒng)空間被不需要的日志所占用稍微高級一點的,例如:[html]viewplaincopy#
ln
-s
/dev/null
~/.netscape/cookies
將該cookie的日志文件鏈接到/dev/null,那么往該文件中寫入的內(nèi)容都將被拋棄二、/dev/zero的用法:/dev/zero和/dev/null一樣,也是一個偽文件,但/dev/zero實際上能產(chǎn)生連續(xù)不斷的null的流〔二進(jìn)制的零流,而不是ASCII型的,寫入/dev/zero的輸出會丟失不見,而從/dev/zero讀出一連串的null也比較困難,雖然這也能通過dd或一個十六進(jìn)制編輯器來做到,/dev/zero主要的用處是用來創(chuàng)建一個指定長度用于初始化的空文件,它通常都是配合dd命令一起使用的。1.用/dev/zero創(chuàng)建一個指定大小的臨時文件例如:結(jié)合dd命令可創(chuàng)建一個大小為1024*1000bit的文件/swap,當(dāng)然這個文件的大小可通過bs和count參數(shù)去調(diào)整[html]viewplaincopy#
dd
if=/dev/zero
of=/swap
bs=1024count=10002.通過/dev/zero將零填充到一個指定大小的文件,以使用某些特殊需求例如:把RAM設(shè)備的內(nèi)容用零填充,從而實現(xiàn)格式化RAM的目的[html]viewplaincopy#
dd
if=/dev/zero
of=$DEVICE
count=$SIZE
bs=$BLOCKSIZE
綜上所述,/dev/null和/dev/zero文件的區(qū)別和用法如下:/dev/null文件是空設(shè)備,也稱為位桶〔bitbucket,它主要是用于"被寫入",任何寫入它的輸出都會被拋棄。如果不想讓消息以標(biāo)準(zhǔn)輸出顯示或?qū)懭胛募?那么可以將消息重定向到/dev/null。因此凡是向/dev/null輸入的任何數(shù)據(jù),它通吃,并且不會撐著!/dev/zero文件主要是用作一個標(biāo)準(zhǔn)的"0"輸入設(shè)備,它可無窮盡地提供0,可以使用/dev/zero來初始化文件。清除:一個改良的清除腳本[html]viewplaincopy#!/bin/bash
LOG_DIR=/var/log
cd
$LOG_DIR
cat
/dev/null
>
messages
cat
/dev/null
>
wtmp
echo
"Logs
cleaned
up."
exit
#這個命令是一種正確并且合適的退出腳本的方法,算是比較標(biāo)準(zhǔn)的"helloworld"現(xiàn)在,讓我們看一下一個真正意義的腳本,而且我們可以走得更遠(yuǎn),這里只是將上面的單條命令匯總到一個bash文件中一并處理,俗稱"批處理"清除:一個增強(qiáng)的和廣義的刪除logfile的腳本[html]viewplaincopy#!/bin/bash
LOG_DIR=/var/log
ROOT_UID=0LINES=10E_XCD=66E_NOTROOT=67if
[
"$UID"
-ne
"$ROOT_UID"
]
then
echo
"Must
be
root
ro
run
this
script!"
exit
$E_NOTROOT
fi
#if
[
-n
"$1"
]
#then
#
lines=$1
#else
#
lines=$LINES
#fi
E_WORNGPARAM=65case
"$1"
in
""
>
lines=10;;
*[!0-9]*>
echo
"Usage:
wong
param!";exit
$E_WRONGPARAM;;
*
>
lines=$1;;
esac
#cd
$LOG_DIR
#if
[
"$PWD"
!=
"$LOG_DIR"
]
#then
#
echo
"Can't
change
to
$LOG_DIR"
#
exit
$E_XCD
#fi
cd
/var/log
||
{
echo
"Can't
change
to
necessary
directory."
>&2
exit
$E_XCD
}
tail
-$lines
messages
>
mesg.tmp
mv
mesg.tmp
messages
cat
/dev/null
>
messages
cat
/dev/null
>
wtmp
echo
"Logs
cleaned
up!"
exit
0
因為你可能希望將系統(tǒng)log全部消滅,這個版本留下了log消息最后的部分.你將不斷地找到新的方法來完善這個腳本,并提高效率.要注意,在每個腳本的開頭都使用sha-bang<#!>,這意味著告訴你的系統(tǒng)這個文件的執(zhí)行需要指定一個解釋器.#!實際上是一個2字節(jié)的魔法數(shù)字,這是指定一個文件類型的特殊標(biāo)記,換句話說,在這種情況下,指的就是一個可執(zhí)行的腳本<鍵入manmagic來獲得關(guān)于這個迷人話題的更多詳細(xì)信息>.在sha-bang之后接著是一個路徑名.這個路徑名就是解釋腳本中命令的解釋程序所在的路徑,可能是一個shell,也可能是一個程序語言,也可能是一個工具包中的命令程序.這個解釋程序從頭開始解釋并且執(zhí)行腳本中的命令<從sha-bang行下邊的一行開始>,忽略注釋.這里強(qiáng)調(diào)文件中的第一個sha-bang才有意義,并且必須在開頭,之后如果再次出現(xiàn)sha-bang不會解析為sha-bang,舉例說明如下:[html]viewplaincopy#!/bin/bash
echo
"Part
1
of
script."
a=1#!/bin/bash
#這將不會啟動一個新腳本.
echo
"Part
2
of
script."
echo
$a
每一個腳本頭的行都指定了一個不同的命令解釋器,如果是/bin/sh,那么就是默認(rèn)shell<在Linux系統(tǒng)上默認(rèn)就是bash>,否則的話就是其他解釋器.舉例說明如下:[html]viewplaincopy#!/bin/rm
#
自刪除腳本.作為rm命令,直接刪除自己,more命令顯示自己的內(nèi)容
#
當(dāng)你運行這個腳本時,
基本上什么都不會發(fā)生.
.
.
當(dāng)然這個文件消失不見了.
WHATEVER=65echo
"This
line
will
never
<betcha!>."
exit
$WHATEVER
#
不要緊,
腳本是不會在這退出的.
使用#!/bin/sh,因為大多數(shù)的商業(yè)UNIX系統(tǒng)上都是以Bourneshell作為默認(rèn)shell,這樣可以使腳本移植到non-Linux的機(jī)器上,雖然這將會犧牲Bash一些獨特的特征.但是腳本將與POSIX的sh標(biāo)準(zhǔn)相一致.注意"sha-bang"后邊給出的路徑名必須是正確的,否則將會出現(xiàn)一個錯誤消息--通常是"Commandnotfound"--這將是你運行這個腳本時所得到的唯一結(jié)果.當(dāng)然#!也可以被忽略,不過這樣你的腳本文件就只能是一些命令的集合,不能夠使用shell內(nèi)建的指令了.上邊第二個例子必須以#!開頭,是因為分配變量了,lines=50,這就使用了一個shell特有的用法.再次提醒你#!/bin/sh將會調(diào)用默認(rèn)的shell解釋器,在Linux機(jī)器上默認(rèn)是/bin/bash.這里對上面的腳本做以下分析:1.定義變量2.檢查腳本是否獲取到root權(quán)限,采用兩種方式,一種便于理解,一種更加專業(yè)一點的做法3.檢查輸入?yún)?shù),采用兩種方式,一種便于理解,一種更加專業(yè)一點的做法4.檢查是否進(jìn)入/var/log目錄,采用兩種方式,一種便于理解,一種更加專業(yè)一點的做法5.執(zhí)行cleanup動作最后鼓勵你使用模塊化的方式來編寫腳本.平時也要多注意收集一些比較有代表性的"模版"代碼,這些零碎的代碼可能用在你將來編寫的腳本中.最后你就能生成一個很好的可擴(kuò)展的例程庫.以下邊這個腳本為例,這個腳本用來測試腳本被調(diào)用的參數(shù)數(shù)量是否正確.大多數(shù)情況下,你需要編寫一個腳本來執(zhí)行一個特定的任務(wù),在本章中第一個腳本就是一個這樣的例子,然后你會修改它來完成一個不同的,但比較相似的任務(wù).使用變量來代替寫死<"硬編碼<hard-wired>">的常量,就是一個很好的習(xí)慣,將重復(fù)的代碼放到一個函數(shù)中,也是一種好習(xí)慣.高級Bash腳本編程指南<2>:Shell特殊字符成于堅持,敗于止步#注釋1.表示注釋2.在引號中間和\#等表示#本身3.echo${PATH#*:}#參數(shù)替換,不是一個注釋4.echo$<<2#101011>>#數(shù)制轉(zhuǎn)換,不是一個注釋;分隔1.命令分隔,在一行中寫多個命令echo"aa";echo"bb"2.在條件中的if和then如果放在同一行,也用;分隔;;case條件的結(jié)束1.命令分隔,在一行中寫多個命令echo"aa";echo"bb"2.在條件中的if和then如果放在同一行,也用;分隔[html]viewplaincopyecho
hello;
echo
there
if
[
-x
"$filename"
];
then
#
注意:
"if"和"then"需要分隔.
echo
"File
$filename
exists.";
cp
$filename
$filename.bak
else
echo
"File
$filename
not
found.";
touch
$filename
fi;
echo
"File
test
complete."
.命令相當(dāng)于1.命令:source2.文件名的前綴,隱藏文件3.目錄:.當(dāng)前目錄,..父目錄4.正則表達(dá)式:匹配任意單個字符首先,先舉例說明一下"."作為source使用的實例[html]viewplaincopy#!/bin/bash
.
data-file
#
加載一個數(shù)據(jù)文件.
#
與"source
data-file"效果相同,
但是更具可移植性.
#
文件"data-file"必須存在于當(dāng)前工作目錄,
因為這個文件是使用'basename'來引用的.
echo
"variable1
=
$variable1"
echo
"variable3
=
$variable3"
let
"sum
=
$variable2
+
$variable4"
echo
"sum
=
$sum"
exit
0
上面是編寫的data_file腳本,通過.data-file引入,相當(dāng)于c語言中的includedata-file,我們看看data-file的內(nèi)容[html]viewplaincopy#
這是需要被腳本加載的數(shù)據(jù)文件.
#
這種文件可以包含變量,
函數(shù),
等等.
#
在腳本中可以通過'source'或者'.'命令來加載.
#
讓我們初始化一些變量.
variable1=22variable2=474variable3=5variable4=97message1="Hello,
how
are
you?"message2="Enough
for
now.
Goodbye."接下來我們看看腳本的執(zhí)行結(jié)果:[html]viewplaincopyroot@ubuntu:~/resource/study/shell_study#
chmod
777
include_file
root@ubuntu:~/resource/study/shell_study#
ls
clear_log
data-file
include_file
show_self
root@ubuntu:~/resource/study/shell_study#
./include_file
variable1
=
22variable3
=
5sum
=
571上面的結(jié)果已經(jīng)很有力的說明了我們想要的結(jié)論.作為隱藏文件時,建立隱藏文件的方法:touch.data-file.作為匹配字符說明如下:ab.可以表示ab+任意字符,處理換行,并且必須是一個字符ab.不能表示ab""部分引用支持通配符擴(kuò)展"STRING"將會阻止<解釋>STRING中大部分特殊的字符'‘全引用,不進(jìn)行通配符擴(kuò)展'STRING'將會阻止STRING中所有特殊字符的解釋.這是一種比使用"更強(qiáng)烈的形式\轉(zhuǎn)義\X將會"轉(zhuǎn)義"字符X.這等價于"X",也等價于'X'.\通常用來轉(zhuǎn)義"和',這樣雙引號和單引號就不會被解釋成特殊含義了./目錄分隔符分隔文件名不同的部分<比如/home/bozo/projects/Makefile>.也可以用來作為除法算術(shù)操作符.,多個命令都被執(zhí)行,但返回最后一個逗號操作符鏈接了一系列的算術(shù)操作.雖然里邊所有的內(nèi)容都被運行了,但只有最后一項被返回.[html]viewplaincopylet
"t2
=
<<a
=
9,
15
/
3>>"
#
Set
"a
=
9"
and
"t2
=
15
/
3"
逗號之前會運算,但是只有最后一項被返回`后置引用`command`結(jié)構(gòu)可以將命令的輸出賦值到一個變量中去.[html]viewplaincopycd
$LOG_DIR
if
[
`pwd`
!=
"$LOG_DIR"
]
then
echo
"Can't
change
to
$LOG_DIR"
exit
$E_XCD
fi
這里例子是最有力的的說明,在上一章中只不過沒有到這個方法,這里pwd命令會返回當(dāng)前路徑,然后與LOG_DIR進(jìn)行比較,同樣你可以定義一個變量保存pwd返回的內(nèi)容,比如:path=`pwd`:操作符1.空操作,等價于"NOP"<noop,一個什么也不干的命令>.
2.死循環(huán):while:,可以被認(rèn)為與shell的內(nèi)建命令,與true作用相同.[html]viewplaincopywhile
:
do
operation-1
operation-2
...
operation-n
done
#與下邊相同:[html]viewplaincopy#
while
true
#
do
#
...
#
done
3.在if/then中表示什么都不做,引出分支[html]viewplaincopyif
condition
then
:
#
什么都不做,引出分支.
else
take-some-action
fi
4.設(shè)置默認(rèn)參數(shù):${username=`whoami`}[html]viewplaincopy:
${username=`whoami`}
#
${username=`whoami`}
如果沒有開頭的":"的話,
將會給出一個錯誤,
除非"username"是一個命令或者內(nèi)建命令
5.變量替換:${HOSTNAME?}${USER?}${MAIL?}[html]viewplaincopy:
${HOSTNAME?}
${USER?}
${MAIL?}
#
如果一個或多個必要的環(huán)境變量沒被設(shè)置的話,
就打印錯誤信息.
6.在和><重定向操作符>結(jié)合使用時,把一個文件截斷到0長度,沒有修改它的權(quán)限;如果文件在之前并不存在,那么就創(chuàng)建它.如:
:>data.xxx#文件"data.xxx"現(xiàn)在被清空了.與cat/dev/null>data.xxx的作用相同然而,這不會產(chǎn)生一個新的進(jìn)程,因為":"是一個內(nèi)建命令.7.可能用來作為注釋行,雖然我們不推薦這么做.使用#來注釋的話,將關(guān)閉剩余行的錯誤檢查,所以可以在注釋行中寫任何東西.然而,使用:的話將不會這樣.:Thisisacommentthatgeneratesanerror,<if[$x-eq3]>.8.":"還用來在/etc/passwd和$PATH變量中做分隔符.[html]viewplaincopybash$
echo
$PATH
/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/sbin:/usr/sbin:/usr/games
*匹配0個或多個字符;數(shù)學(xué)乘法;**冪運算[html]viewplaincopyroot@ubuntu:~/resource/study/shell_study#
ls
clear_log
data-file
include_file
show_self
root@ubuntu:~/resource/study/shell_study#
echo
*
clear_log
data-file
include_file
show_self
?匹配任意一個字符;但在<<a>b?a:b>>表示c語言中的三目運算<<t=a<45?7:11>>#C語言風(fēng)格的三元操作.$字符1.取變量的值echo$PATH[html]viewplaincopyvar1=5var2=23skidooecho
$var1
#
5
echo
$var2
#
23skidoo
2.正則表達(dá)式中表示行的結(jié)尾在正則表達(dá)式中,"$"表示行結(jié)束符,先分析一下下面的例子吧[html]viewplaincopyroot@ubuntu:~/resource/study/shell_study#
echo
slfjalj$fdjgl
slfjalj
3.${}參數(shù)替換${PAHT}[html]viewplaincopy#!/bin/bash
#
param-sub.sh
#
一個變量是否被聲明或設(shè)置,
#+
將會影響這個變量是否使用默認(rèn)值,
#+
即使這個變量值為空<null>.
username0=
echo
"username0
has
been
declared,
but
is
set
to
null."
echo
"username0
=
${username0-`whoami`}"這里定義了username0且初始化是null,所以這里不會有輸出,這里的"-"相當(dāng)于"="
#
不會有輸出.
echo
echo
username1
has
not
been
declared.
echo
"username1
=
${username1-`whoami`}"這里username1在上面沒有定義并初始化為null,所以會顯示
#
將會輸出默認(rèn)值.
username2=
echo
"username2
has
been
declared,
but
is
set
to
null."
echo
"username2
=
${username2:-`whoami`}"這里上面初始化了username2并初始化為null,但是這里有個":"
#
^
#
會輸出,
因為:-會比-多一個條件測試.
#
可以與上邊的例子比較一下.
#
再來一個:
variable=
#
變量已經(jīng)被聲明,
但是設(shè)為空值.
echo
"${variable-0}"
#
<沒有輸出>
echo
"${variable:-1}"
#
1
#
^
unset
variable
echo
"${variable-2}"
#
2
echo
"${variable:-3}"
#
3
exit
0
我們也看看他的執(zhí)行結(jié)果:[html]viewplaincopyroot@ubuntu:~/resource/study/shell_study#
chmod
777
para_sub
root@ubuntu:~/resource/study/shell_study#
ls
clear_log
data-file
include_file
para_sub
show_self
root@ubuntu:~/resource/study/shell_study#
./para_sub
username0
has
been
declared,
but
is
set
to
null.
username0
=
username1
has
not
been
declared.
username1
=
rootusername2
has
been
declared,
but
is
set
to
null.
username2
=
root
^
1
2
3
4.$*所有參數(shù)5.$#參數(shù)個數(shù)6.$$進(jìn)程的ID7.$?進(jìn)程的返回狀態(tài)<>字符1.命令組,在一個子Shell中運行<a=3;echo$a>其中定義的變量在后面不可用在括號中的變量,由于是在子shell中,所以對于腳本剩下的部分是不可用的.父進(jìn)程,也就是腳本本身,將不能夠讀取在子進(jìn)程中創(chuàng)建的變量,也就是在子shell中創(chuàng)建的變量.[html]viewplaincopya=123<
a=321;
>
echo
"a
=
$a"
#
a
=
123#
在圓括號中a變量,
更像是一個局部變量.
2.數(shù)組初始化:array=<a,b,c>{}大括號擴(kuò)展[html]viewplaincopycat
{file1,file2,file3}
>
combined_file
#
把file1,
file2,
file3連接在一起,
并且重定向到combined_file中.
cp
file22.{txt,backup}
#
拷貝"file22.txt"到"file22.b
{}代碼塊,即一個匿名函數(shù),但其中定義的變量在后面依然可用[html]viewplaincopy#!/bin/bash
#
從/etc/fstab中讀行.
File=/etc/fstab
{
read
line1
read
line2
read
line3
}
<
$File
echo
"First
line
in
$File
is:"
echo
"$line1"
echo
echo
"Second
line
in
$File
is:"
echo
"$line2"
echo
echo
"third
line
in
$File
is:"
echo
"$line3"
exit
0
執(zhí)行結(jié)果:[html]viewplaincopyroot@ubuntu:~/resource/study/shell_study#
./test1
First
line
in
/etc/fstab
is:
#
/etc/fstab:
static
file
system
information.
Second
line
in
/etc/fstab
is:
#
third
line
in
/etc/fstab
is:
#
Use
'blkid
-o
value
-s
UUID'
to
the
universally
unique
identifier
接下來看一個例子:[html]viewplaincopy#!/bin/bash
{
echo
"Just
for
a
test:"
echo
`pwd`
echo
"Test
end"
}
>
"test-context"
#
把代碼塊中的所有輸出都重定向到文件中.
echo
"Results
of
rpm
test
in
test-context"
exit
0
看看運行結(jié)果:[html]viewplaincopyroot@ubuntu:~/resource/study/shell_study#
chmod
777
test2
root@ubuntu:~/resource/study/shell_study#
./test2
Results
of
rpm
test
in
test-context
root@ubuntu:~/resource/study/shell_study#
ls
clear_log
include_file
show_self
test2
data-file
para_sub
test1
test-context
root@ubuntu:~/resource/study/shell_study#
cat
test-context
Just
for
a
test:
/root/resource/study/shell_study
Test
end
{}\;用在find的-exec中$find-name*.txt-execcat{}\;[]字符1.測試[-z$1]2.數(shù)組元素a[1]='test'3.[[]]表示測試使用[[...]]條件判斷結(jié)構(gòu),而不是[...],能夠防止腳本中的許多邏輯錯誤.比如,&&,||,<,和>操作符能夠正常存在于[[]]條件判斷結(jié)構(gòu)中,但是如果出現(xiàn)在[]結(jié)構(gòu)中的話,會報錯.4.<<>>數(shù)學(xué)運算5.在正則表達(dá)式中表示范圍[a-z]<<<>重定向和進(jìn)程替換ls-al>a.txtscriptname>filename重定向scriptname的輸出到文件filename中.如果filename存在的話,那么將會被覆蓋.command&>filename重定向command的stdout和stderr到filename中.command>&2重定向command的stdout到stderr中.scriptname>>filename把scriptname的輸出追加到文件filename中.如果filename不存在的話,將會被創(chuàng)建.[i]<>filename打開文件filename用來讀寫,并且分配文件描述符i給這個文件.如果filename不存在,這個文件將會被創(chuàng)建.><還用在ASCII比較if[["$veg1"<"$veg2"]]\<,\>正則表達(dá)式中的單詞邊界.如:bash$grep'\<the\>'textfile|管道分析前邊命令的輸出,并將輸出作為后邊命令的輸入.這是一種產(chǎn)生命令鏈的好方法.echols-l|sh#傳遞"echols-l"的輸出到shell中,與一個簡單的"ls-l"結(jié)果相同.cat*.lst|sort|uniq#合并和排序所有的".lst"文件,然后刪除所有重復(fù)的行.
管道是進(jìn)程間通訊的一個典型辦法,將一個進(jìn)程的stdout放到另一個進(jìn)程的stdin中.標(biāo)準(zhǔn)的方法是將一個一般命令的輸出,比如cat或者echo,傳遞到一個"過濾命令"<在這個過濾命令中將處理輸入>中,然后得到結(jié)果.cat$filename1$filename2|grep$search_word當(dāng)然輸出的命令也可以傳遞到腳本中.[html]viewplaincopy#!/bin/bash
#
uppercase.sh
:
修改輸入,
全部轉(zhuǎn)換為大寫.
tr
'a-z'
'A-Z'
#
字符范圍必須被""引用起來來阻止產(chǎn)生單字符的文件名.
exit
0
現(xiàn)在讓我們輸送ls-l的輸出到一個腳本中.[html]viewplaincopybash$
ls
-l
|
./uppercase.sh
-RW-RW-R--
1
BOZO
BOZO
109
APR
7
19:49
1.TXT
-RW-RW-R--
1
BOZO
BOZO
109
APR
14
16:48
2.TXT
-RW-R--R--
1
BOZO
BOZO
725
APR
20
20:56
DATA-FILE
管道中的每個進(jìn)程的stdout比須被下一個進(jìn)程作為stdin來讀入.否則,數(shù)據(jù)流會阻塞,并且管道將產(chǎn)生一些非預(yù)期的行為.catfile1file2|ls-l|sort#從"catfile1file2"中的輸出并沒出現(xiàn).作為子進(jìn)程的運行的管道,不能夠改變腳本的變量.variable="initial_value"echo"new_value"|readvariableecho"variable=$variable"#variable=initial_value如果管道中的某個命令產(chǎn)生了一個異常,并中途失敗,那么這個管道將過早的終止.這種行為被叫做brokenpipe,并且這種狀態(tài)下將發(fā)送一個SIGPIPE信號.>|強(qiáng)制重定向<即使設(shè)置了noclobber選項--就是-C選項>.這將強(qiáng)制的覆蓋一個現(xiàn)存文件.||邏輯或操作;用在兩個命令之間的時候,表示在前一個命令結(jié)束時,若返回值為false,繼續(xù)執(zhí)行下一個命令&&邏輯與;用在兩個命令之間的時候,表示在前一個命令結(jié)束時,若返回值為true,繼續(xù)執(zhí)行下一個命令&后臺運行看一個例子[html]viewplaincopy#!/bin/bash
#
background-loop.sh
for
i
in
1
2
3
4
5
6
7
8
9
10
#
第一個循環(huán).
do
echo
echo
-n
"$i
"
done
&
#
在后臺運行這個循環(huán).
#
在第2個循環(huán)之后,
將在某些時候執(zhí)行.
echo
#
這個'echo'某些時候?qū)⒉粫@示.
for
i
in
11
12
13
14
15
16
17
18
19
20
#
第二個循環(huán).
do
echo
-n
"$i
"
done
echo
#
這個'echo'某些時候?qū)⒉粫@示.
exit
0
看一下結(jié)果:[html]viewplaincopyroot@ubuntu:~/resource/study/shell_study#
./for_test
11
12
13
14
15
16
17
18
19
20
root@ubuntu:~/resource/study/shell_study#
1
2
3
4
5
6
7
8
9
10
-在所有的命令內(nèi)如果想使用選項參數(shù)的話,前邊都要加上"-".1.參數(shù)選項2.減號3.重定向stdin和stdout:cd/source/directory&&tarcf-.>|<cd/dest/directory&&tarxpvf->4.先前的工作目錄cd-5.注:使用-開頭的文件名和變量名可能會出現(xiàn)一些問題+一個命令或者過濾器的選項標(biāo)記.~home目錄~+當(dāng)前工作目錄~-先前工作目錄^正則表達(dá)式中表示行首其中命令的很多細(xì)節(jié)并沒有研究的很徹底,好多好碎,以后見到用到具體的命令再具體分析吧高級Bash腳本編程指南<3>:變量和參數(shù)的介紹成于堅持,敗于止步變量替換變量的名字就是變量保存值的地方.引用變量的值就叫做變量替換."$"這個符號就好像是一種標(biāo)志讓我們仔細(xì)的區(qū)別變量的名字和變量的值.如果variable是一個變量的名字,那么$variable就是引用這變量的值,即這邊變量所包含的數(shù)據(jù).[html]viewplaincopyroot@ubuntu:~#
variable=12root@ubuntu:~#
echo
variable
variable
root@ubuntu:~#
echo
$variable
12
當(dāng)變量沒有$前綴的時候,那么變量可能存在如下幾種情況.1.變量被聲明或被賦值,2.變量被unset,3.變量被exporte,4.變量處在一種特殊的情況,變量代表一種信號變量賦值可以使用=<比如var1=27>,也可以在read命令中或者循環(huán)頭進(jìn)行賦值<forvar2in123>.被一對雙引號<"">括起來的變量替換是不會被阻止的.所以雙引號被稱為部分引用,有時候又被稱為"弱引用".但是如果使用單引號的話<''>,那么變量替換就會被禁止了,變量名只會被解釋成字面的意思,不會發(fā)生變量替換.所以單引號被稱為全引用,有時候也被稱為"強(qiáng)引用".注意$variable事實上只是${variable}的簡寫形式.在某些上下文中$variable可能會引起錯誤,這時候你就需要用${variable}了下面以一個例子做說明[html]viewplaincopy#!/bin/bash
#
變量賦值和替換
a=375
#這里沒有$說明是聲明并且賦值了
hello=$a
#$a表示使用變量a的值,把這個值賦值給hello這個變量
#
#
強(qiáng)烈注意,
在賦值的的時候,
等號前后一定不要有空格.
#
如果出現(xiàn)空格會怎么樣?
#
"VARIABLE
=value"
#
腳本將嘗試運行一個"VARIABLE"的命令,
帶著一個"=value"參數(shù).
#
"VARIABLE=
value"
#
腳本將嘗試運行一個"value"的命令,
并且?guī)е粋€被賦值成""的環(huán)境變量"VARIABLE".
#
echo
hello
#沒有$這里打印hello變量的名字
echo
$hello
#打印hello變量的值
echo
${hello}
#同樣是打印hello變量的值
echo
"$hello"
echo
"${hello}"
hello="A
B
C
D"
#重新賦值
echo
$hello
#
A
B
C
D
引用一個變量將保留其中的空白,
當(dāng)然,
如果是變量替換就不會保留了.
echo
"$hello"
#
A
B
C
D
echo
'$hello'
hello=
echo
"\$hello
<null
value>
=
$hello"
V3=23var1=21var2=22var3=$V3
echo
"var1=$var1
var2=$var2
var3=$var3"
numbers="one
two
three"other_numbers="1
2
3"echo
"numbers
=
$numbers"
echo
"other_numbers
=
$other_numbers"
mixed_bag=2\
\
Whatever
echo
"$mixed_bag"
echo
"uninitialized_variable
=
$uninitialized_variable"
uninitialized_variable=
echo
"uninitialized_variable
=
$uninitialized_variable"
uninitialized_variable=23unset
uninitialized_variable
echo
"uninitialized_variable
=
$uninitialized_variable"
exit
0
看看這個腳本的執(zhí)行結(jié)果:[html]viewplaincopyroot@ubuntu:~/resource/study/shell_study#
./value-test
hello
375
375
375
375
A
B
C
D
A
B
C
D
$hello
$hello
<null
value>
=
var1=21var2=22var3=23numbers
=
one
two
three
other_numbers
=
1
2
3
2
Whatever
uninitialized_variable
=
uninitialized_variable
=
uninitialized_variable
=
一個未初始化的變量將會是"null"值-就是未賦值<但并不是代表值是0!>.在給變量賦值之前就使用這個變量通常都會引起問題.但是在執(zhí)行算術(shù)操作的時候,仍然有可能使用未初始化過的變量[html]viewplaincopyroot@ubuntu:~/resource/study/shell_study#
echo
"$data"
root@ubuntu:~/resource/study/shell_study#
let
"data
+=5"
root@ubuntu:~/resource/study/shell_study#
echo
"$data"
5
結(jié)論:一個未初始化的變量是沒有值的,但是在做算術(shù)操作的時候,這個未初始化的變量看起來值為0.這是一個未文檔化<并且可能不具可移植性>的行為.
賦值操作<前后都不能有空白>因為=和-eq都可以用做條件測試操作,所以不要與這里的賦值操作相混淆.注意:=既可以用做條件測試操作,也可以用于賦值操作,這需要視具體的上下文而定.簡單的賦值操作舉例:[html]viewplaincopy#!/bin/bash
#
賦值
a=879echo
"The
value
of
\"a\"
is
$a."
#
使用'let'賦值
let
a=16+5
echo
"The
value
of
\"a\"
is
now
$a."
#
在'for'循環(huán)中<事實上,
這是一種偽賦值>:
echo
-n
"Values
of
\"a\"
in
the
loop
are:
"
#這里加上-n表示忽略string最后的換行操作,否則會換行
for
a
in
7
8
9
11
do
echo
-n
"$a
"
done
echo
#
使用'read'命令進(jìn)行賦值<這也是一種賦值的類型>:
echo
-n
"Enter
\"a\":
"
read
a
#讀取輸入的值
echo
"The
value
of
\"a\"
is
now
$a."
exit
0
實驗結(jié)果:[html]viewplaincopyroot@ubuntu:~/resource/study/shell_study#
./value-test1
The
value
of
"a"
is
879.
The
value
of
"a"
is
now
21.
Values
of
"a"
in
the
loop
are:
7
8
9
11
Enter
"a":
121212
The
value
of
"a"
is
now
121212.
再看一個稍微復(fù)雜一點的例子:[html]viewplaincopy#!/bin/bash
a=23
#
簡單的賦值
echo
$a
b=$a
echo
$b
#
現(xiàn)在讓我們來點小變化<命令替換>.
a=`echo
Hello!`
#
把'echo'命令的結(jié)果傳給變量'a'
echo
$a
a=`ls
-l`
#
把'ls
-l'的結(jié)果賦值給'a'
echo
$a
#
然而,
如果沒有引號的話將會刪除ls結(jié)果中多余的tab和換行符.
echo
echo
"$a"
#
如果加上引號的話,
那么就會保留ls結(jié)果中的空白符.
exit
0
看一看實驗結(jié)果:[html]viewplaincopyroot@ubuntu:~/resource/study/shell_study#
chmod
777
value-test2
root@ubuntu:~/resource/study/shell_study#
./value-test2
23
23
Hello!
total
48
-rwxrwxrwx
1
root
root
663
2013-04-22
03:34
clear_log
-rw-r--r--
1
root
root
354
2013-04-22
03:15
data-file
-rwxrwxrwx
1
root
root
404
2013-04-22
05:05
for_test
-rwxrwxrwx
1
root
root
345
2013-04-22
03:16
include_file
-rwxrwxrwx
1
root
root
831
2013-04-22
04:08
para_sub
-rwxrwxrwx
1
root
root
253
2013-04-22
00:35
show_self
-rwxrwxrwx
1
root
root
256
2013-04-22
04:41
test1
-rwxrwxrwx
1
root
root
204
2013-04-22
04:50
test2
-rw-r--r--
1
root
root
59
2013-04-22
04:50
test-context
-rwxrwxrwx
1
root
root
1221
2013-04-23
22:33
value-test
-rwxrwxrwx
1
root
root
415
2013-04-23
22:51
value-test1
-rwxrwxrwx
1
root
root
439
2013-04-23
22:57
value-test2
total
48
-rwxrwxrwx
1
root
root
663
2013-04-22
03:34
clear_log
-rw-r--r--
1
root
root
354
2013-04-22
03:15
data-file
-rwxrwxrwx
1
root
root
404
2013-04-22
05:05
for_test
-rwxrwxrwx
1
root
root
345
2013-04-22
03:16
include_file
-rwxrwxrwx
1
root
root
831
2013-04-22
04:08
para_sub
-rwxrwxrwx
1
root
root
253
2013-04-22
00:35
show_self
-rwxrwxrwx
1
root
root
256
2013-04-22
04:41
test1
-rwxrwxrwx
1
root
root
204
2013-04-22
04:50
test2
-rw-r--r--
1
root
root
59
2013-04-22
04:50
test-context
-rwxrwxrwx
1
root
root
1221
2013-04-23
22:33
value-test
-rwxrwxrwx
1
root
root
415
2013-04-23
22:51
value-test1
-rwxrwxrwx
1
root
root
439
2013-04-23
22:57
value-test2
Bash變量是不區(qū)分類型的不像其他程序語言一樣,Bash并不對變量區(qū)分"類型".本質(zhì)上,Bash變量都是字符串.但是依賴于具體的上下文,Bash也允許比較操作和整數(shù)操作.其中的關(guān)鍵因素就是,變量中的值是否只有數(shù)字.下面看一下一個實例;[html]viewplaincopy#!/bin/bash
a=2334
#
整型.
let
"a
+=
1"
echo
"a
=
$a
"
#
a
=
2335b=${a/23/BB}
#
將"23"替換成"BB".
echo
"b
=
$b"
#
b
=
BB35declare
-i
b
#
即使使用declare命令也不會對此有任何幫助.
echo
"b
=
$b"
#
b
=
BB35let
"b
+=
1"
#
BB35
+
1
=
echo
"b
=
$b"
#
b
=
1c=BB34echo
"c
=
$c"
#
c
=
BB34d=${c/BB/23}
#
將"BB"替換成"23".
#
這使得變量$d變?yōu)橐粋€整形.
echo
"d
=
$d"
#
d
=
2334let
"d
+=
1"
#
2334
+
1
=
echo
"d
=
$d"
#
d
=
2335#
null變量會如何呢?
e=""echo
"e
=
$e"
#
e
=
let
"e
+=
1"
#
算術(shù)操作允許一個null變量?
echo
"e
=
$e"
#
e
=
1#
如果沒有聲明變量會怎樣?
echo
"f
=
$f"
#
f
=
let
"f
+=
1"
#
算術(shù)操作能通過么?
echo
"f
=
$f"
#
f
=
1#
所以說Bash中的變量都是不區(qū)分類型的.
exit
0
看一看他是執(zhí)行結(jié)果:[html]viewplaincopyroot@ubuntu:~/resource/study/shell_study#
./int-char
a
=
2335b
=
BB35b
=
BB35b
=
1c
=
BB34d
=
2334d
=
2335e
=
e
=
1
f
=
f
=
1
不區(qū)分變量的類型既是幸運的事情也是悲慘的事情.它允許你在編寫腳本的時候更加的靈活<但是也足夠把你搞暈!>,并且可以讓你能夠更容易的編寫代碼.然而,這也很容易產(chǎn)生錯誤,并且讓你養(yǎng)成糟糕的編程習(xí)慣.這樣的話,程序員就承擔(dān)了區(qū)分腳本中變量類型的責(zé)任.Bash是不會為你區(qū)分變量類型的.特殊的變量類型局部變量這種變量只有在代碼塊或者函數(shù)中<參見函數(shù)中的局部變量>才可見.環(huán)境變量這種變量將影響用戶接口和shell的行為在通常情況下,每個進(jìn)程都有自己的"環(huán)境",這個環(huán)境是由一組變量組成的,這些變量中存有進(jìn)程可能需要引用的信息.在這種情況下,shell與一個一般的進(jìn)程沒什么區(qū)別.每次當(dāng)一個shell啟動時,它都將創(chuàng)建適合于自己環(huán)境變量的shell變量.更新或者添加一個新的環(huán)境變量的話,這個shell都會立刻更新它自己的環(huán)境<譯者注:換句話說,更改或增加的變量會立即生效>,并且所有的shell子進(jìn)程<即這個shell所執(zhí)行的命令>都會繼承這個環(huán)境.<譯者注:準(zhǔn)確地說,應(yīng)該是后繼生成的子進(jìn)程才會繼承Shell的新環(huán)境變量,已經(jīng)運行的子進(jìn)程并不會得到它的新環(huán)境變量>.分配給環(huán)境變量的空間是有限的.創(chuàng)建太多環(huán)境變量,或者給一個環(huán)境變量分配太多的空間都會引起錯誤.如果一個腳本要設(shè)置一個環(huán)境變量,那么需要將這些變量"export"出來,也就是需要通知到腳本本地的環(huán)境.這是export命令的功能.
一個腳本只能夠export變量到這個腳本所產(chǎn)生的子進(jìn)程,也就是說只能夠?qū)@個腳本所產(chǎn)生的命令和進(jìn)程起作用.如果腳本是從命令行中調(diào)用的,那么這個腳本所export的變量是不能影響命令行環(huán)境的.也就是說,子進(jìn)程是不能夠export變量來影響產(chǎn)生自己的父進(jìn)程的環(huán)境的.位置參數(shù)從命令行傳遞到腳本的參數(shù):$0,$1,$2,$3...
$0就是腳本文件自身的名字,$1是第一個參數(shù),$2是第二個參數(shù),$3是第三個參數(shù),然后是第四個.
$9之后的位置參數(shù)就必須用大括號括起來了,比如,${10},${11},${12}.
兩個比較特殊的變量$*和$@表示所有的位置參數(shù).還是看一個實例吧[html]viewplaincopy#!/bin/bash
#
作為用例,
調(diào)用這個腳本至少需要10個參數(shù),
比如:
#
./scriptname
1
2
3
4
5
6
7
8
9
10
MINPARAMS=10echo
"The
name
of
this
script
is
\"$0\"."
echo
"The
name
of
this
script
is
\"`basename
$0`\"."
if
[
-n
"$1"
]
#
測試變量被引用.
then
echo
"Parameter
#1
is
$1"
#
需要引用才能夠轉(zhuǎn)義"#"
fi
if
[
-n
"$2"
]
then
echo
"Parameter
#2
is
$2"
fi
if
[
-n
"$3"
]
then
echo
"Parameter
#3
is
$3"
fi
if
[
-n
"${10}"
]
#
大于$9的參數(shù)必須用{}括起來.
then
echo
"Parameter
#10
is
${10}"
fi
echo
""
echo
"All
the
command-line
parameters
are:
"$*""
if
[
$#
-lt
"$MINPARAMS"
]
then
echo
"This
script
needs
at
least
$MINPARAMS
command-line
arguments!"
fi
exit
0
看看實驗結(jié)果:[html]viewplaincopyroot@ubuntu:~/resource/study/shell_study#
./args
1
2
3
The
name
of
this
script
is
"./args".
The
name
of
this
script
is
"args".
Parameter
#1
is
1
Parameter
#2
is
2
Parameter
#3
is
3
All
the
command-line
parameters
are:
1
2
3
This
script
needs
at
least
10
command-line
arguments!
root@ubuntu:~/resource/study/shell_study#
./args
1
2
3
4
5
6
7
8
9
10
11
The
name
of
this
script
is
"./args".
The
name
of
this
script
is
"args".
Parameter
#1
is
1
Parameter
#2
is
2
Parameter
#3
is
3
Parameter
#10
is
10
All
the
command-line
parameters
are:
1
2
3
4
5
6
7
8
9
10
11
{}標(biāo)記法提供了一種提取從命令行傳遞到腳本的最后一個位置參數(shù)的簡單辦法一些腳本可能會依賴于使用不同的調(diào)用名字,來表現(xiàn)出不同的行為.如果想要達(dá)到這種目的,一般都需要在腳本中檢查$0.因為腳本只能夠有一個真正的文件名,如果要產(chǎn)生多個名字,必須使用符號鏈接.
看一下shift命令的使用實例:[html]viewplaincopy#!/bin/bash
#
使用'shift'來逐步存取所有的位置參數(shù).
給腳本命個名,
比如shft,然后給腳本傳遞一些位置參數(shù),
比如:
./shft
a
b
c
def
23
skidoo
until
[
-z
"$1"
]
#
直到所有的位置參數(shù)都被存取完...
do
echo
-n
"$1
"
shift
done
echo
exit
0
查看實驗結(jié)果:[html]viewplaincopyroot@ubuntu:~/resource/study/shell_study#
./shift
d
df
lsjf
sldjf
d
df
lsjf
sldjf
先到這里了,O<∩_∩>O~高級Bash腳本編程指南<4>:shell中的引用成于堅持,敗于止步引用的字面意思就是將字符串用雙引號括起來.它的作用就是保護(hù)字符串中的特殊字符不被shell或者shell腳本重新解釋,或者擴(kuò)展.<我們這里所說的"特殊"指的是一些字符在shell中具有的特殊意義,而不是字符的字面意思,比如通配符--*.>在日常的演講和寫作中,當(dāng)我們"引用"一個短語的時候,這意味著這個短語被區(qū)分以示它有特別的含義.但是在Bash腳本中,當(dāng)我們引用一個字符串的時候,我們區(qū)分這個字符串是為了保護(hù)它的字面含義.某些程序和工具能夠重新解釋或者擴(kuò)展被引用的特殊字符.引用的一個重要作用就是保護(hù)命令行參數(shù)不被shell解釋,但是還是能夠讓正在調(diào)用的程序來擴(kuò)展它.[html]viewplaincopyroot@ubuntu:~/resource/study/shell_study/txt-folder#
grep
[Tt]his
*.txt
file1.txt:this
is
the
first
file
file2.txt:This
the
second
file
root@ubuntu:~/resource/study/shell_study/txt-folder#
grep
'[Tt]his'
*.txt
file1.txt:this
is
the
first
file
file2.txt:This
the
second
file
這在我的bash下都是可以實現(xiàn)的引用還可以改掉echo's不換行的"毛病".[html]viewplaincopyroot@ubuntu:~/resource/study/shell_study/txt-folder#
echo
$<ls
-l>
total
8
-rw-r--r--
1
root
root
23
2013-04-23
23:34
file1.txt
-rw-r--r--
1
root
root
21
2013-04-23
23:34
file2.txt
root@ubuntu:~/resource/study/shell_study/txt-folder#
echo
'$<ls
-l>'
$<ls
-l>
root@ubuntu:~/resource/study/shell_study/txt-folder#
echo
"$<ls
-l>"
total
8
-rw-r--r--
1
root
root
23
2013-04-23
23:34
file1.txt
-rw-r--r--
1
root
root
21
2013-04-23
23:34
file2.txt
在一個雙引號中通過直接使用變量名的方法來引用變量,一般情況下都是沒問題的.這么做將阻止所有在引號中的特殊字符被重新解釋--包括變量名,但是$,`<后置引用>,和\<轉(zhuǎn)義符>除外.
保留$作為特殊字符的意義是為了能夠在雙引號中也能夠正常的引用變量<"$variable">,也就是說,這個變量將被它的值所取代使用雙引號還能夠阻止單詞分割<wordsplitting>.如果一個參數(shù)被雙引號擴(kuò)起來的話,那么這個參數(shù)將認(rèn)為是一個單元,即使這個參數(shù)包含有空白,那里面的單詞也不會被分隔開.[html]viewplaincopy#!/bin/bash
var="'<]\\{}\$\""
echo
$var
#
'<]\{}$"
echo
"$var"
#
'<]\{}$"
和上一句沒什么區(qū)別.Doesn't
make
a
difference.
echo
IFS='\'echo
$var
#
'<]
{}$"
\
字符被空白符替換了,
為什么?
echo
"$var"
#
'<]\{}$"
exit
0
我們看看上面這個腳本的執(zhí)行結(jié)果:[html]viewplaincopyroot@ubuntu:~/resource/study/shell_study#
./echo-strange
'<]\{}$"
'<]\{}$"
'<]
{}$"
'<]\{}$"
針對IFS的用法以后再研究吧當(dāng)在命令行中使用時,如果在雙引號中包含"!"的話,那么會產(chǎn)生一個錯誤<譯者注:比如,echo"hello!">.這是因為感嘆號被解釋成歷史命令了.但是如果在腳本中,就不會存在這個問題,因為在腳本中Bash歷史機(jī)制是被禁用的.在雙引號中使用"\"也可能會出現(xiàn)一些不一致的行為[html]viewplaincopyroot@ubuntu:~/resource/study/shell_study#
echo
"hello!"
bash:
!":
event
not
found
root@ubuntu:~/resource/study/shell_study#
echo
hello!
hello!
root@ubuntu:~/resource/study/shell_study#
echo
hello\!
hello!
root@ubuntu:~/resource/study/shell_study#
echo
"hello\!"
hello\!
root@ubuntu:~/resource/study/shell_study#
echo
ni\thao
nithao
root@ubuntu:~/resource/study/shell_study#
echo
"ni\thao"
ni\thao
root@ubuntu:~/resource/study/shell_study#
echo
-e
ni\thao
nithao
root@ubuntu:~/resource/study/shell_study#
echo
-e
"ni\thao"
ni
hao
單引號<''>操作與雙引號基本一樣,但是不允許引用變量,因為$的特殊意義被關(guān)閉了.在單引號中,任何特殊字符都按照字面的意思進(jìn)行解釋,除了'.所以說單引號<"全引用">是一種比雙引號<"部分引用">更嚴(yán)格的引用方法.因為即使是轉(zhuǎn)義符<\>在單引號中也是按照字面意思解釋的,所以如果想在一對單引號中顯示一個單引號是不行的下面這個例子:[html]viewplaincopyroot@ubuntu:~/resource/study/shell_study#
echo
"I'm
a
good
person"
I'm
a
good
person
root@ubuntu:~/resource/study/shell_study#
echo
'I'm
a
good
person'
>
^C
root@ubuntu:~/resource/study/shell_study#
echo
'I'\''m
a
good
person'
I'm
a
good
person
root@ubuntu:~/resource/study/shell_study#
echo
'I'"'"'m
a
good
person'
I'm
a
good
person
轉(zhuǎn)義是一種引用單個字符的方法.一個前面放上轉(zhuǎn)義符<\>的字符就是告訴shell這個字符按照字面的意思進(jìn)行解釋,換句話說,就是這個字符失去了它的特殊含義.在某些特定的命令和工具中,比如echo和sed,轉(zhuǎn)義符往往會起到相反效果-它反倒可能會引發(fā)出這個字符的特殊含義.特定的轉(zhuǎn)義符的特殊的含義echo和sed命令中使用\n表示新的一\r表示回車\t表示水平制表符\v表示垂直制表符\b表示后退符\a表示"alert"<蜂鳴或者閃爍>\0xx轉(zhuǎn)換為八進(jìn)制的ASCII碼,等價于0xx[html]viewplaincopy#!/bin/bash
echo
"\v\v\v\v"
#
逐字的打印\v\v\v\v.
#
使用-e選項的'echo'命令來打印轉(zhuǎn)義符.
echo
"==============="
echo
-e
"\v\v\v\v"
#
打印4個垂直制表符.
echo
"==============="
echo
-e
"\042"
#
打印"
<引號,
8進(jìn)制的ASCII
碼就是42>.
echo
"==============="
#
如果使用$'\X'結(jié)構(gòu),那-e選項就不必要了.
echo
$'\n
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 公司與流動餐車合同范本
- 公寓衣柜采購合同范本
- 農(nóng)村因修路占地合同范本
- 請工人簡易合同范本
- 印刷行業(yè)定制合同范本
- 公司項目投資入股合同范本
- 2025年常溫遠(yuǎn)紅外陶瓷及制品項目合作計劃書
- 農(nóng)業(yè)托管驗收合同范本
- 2025年FS-L系列柔軟劑項目建議書
- 合作共建樓房合同范本
- 2024年鄭州市公安機(jī)關(guān)招聘警務(wù)輔助人員筆試真題
- 2025年黑龍江農(nóng)墾職業(yè)學(xué)院單招職業(yè)傾向性測試題庫匯編
- 2.3品味美好情感 課 件 -2024-2025學(xué)年統(tǒng)編版道德與法治七年級下冊
- 2025年01月明光市司法局司法協(xié)理員7人筆試歷年典型考題(歷年真題考點)解題思路附帶答案詳解
- 整體施工勞務(wù)服務(wù)方案
- XX小學(xué)學(xué)生心理健康檔案(一生一案)
- 集團(tuán)權(quán)屬公司管理制度
- 普通中專畢業(yè)生登記表格模板(共4頁)
- 五金沖壓件作業(yè)指導(dǎo)書
- 汽車吊車吊裝施工方案
- 倉內(nèi)運營方案
評論
0/150
提交評論