來自:linux程序設(shè)計中文第四版
變量
變量引用
shell中,變量不需要提前聲明,默認(rèn)所有變量均被看做為字符串來存儲
引用變量名只需要在變量名添加 $符號
variable=hello
echo $variable
hello
variable=”hello world ”
注意:
- 如果字符串里面包含空格,必須用引號括起來,另外等號兩邊不能有空格!
- 雙引號與單引號的差別,雙引號會發(fā)生變量替換,單引號則不會替換
- 被雙引號包括起來的變量,變量替換不會被阻止的,所以被稱為弱引用
- 被單引號包括起來的變量,變量替換就會完全禁止,因此被稱為全(強(qiáng))引用
”$variable” 會被替換為變量表達(dá)式
‘$variable’ 不會替換為變量表達(dá)式
參數(shù)變量
- $$ shell 本身的PID
- $! shell 最后運(yùn)行的后臺Process 的PID
- $? 最后運(yùn)行命令的結(jié)束代碼(返回值)
- $- 使用set命令設(shè)定的Flag一覽
- $* 所有參數(shù)列表
- $@ $*的一種變體
- $# 添加到shell的參數(shù)個數(shù)
- $0 shell 本身的文件名
- $1-$n 添加到shell的各種參數(shù)值,$1是第一個參數(shù)。。。。。。。
read命令: 用來讀取一個變量
read variable
Hello
echo $variable
Hello
變量運(yùn)算符
條件&測試
test 、[]命令
eg:
if test -f hello.c (; then)
then
…
fi
或者
if [ -f hello.c ]
then
…
fi
test 命令比較主要分三種類型,字符串比較,數(shù)值比較,文件相關(guān)比較
- 字符串比較
- string1 = string2 如果兩個字符串相同為真
- string1 != string2 ….不同…..
- -n string 如果字符串不為空則結(jié)果為真
- -z string 如果字符串為null 則結(jié)果為真
- 算術(shù)比較
- expression1 –eq expression2 如果兩個表達(dá)式相等則結(jié)果為真
- expression1 –ne expression2 不等
- expression1 –gt expression2 如果expression1 大于 expression2 為真
- expression1 –ge expression2 大于等于
- expression1 -lt expression2 小于
- expression1 -le expression2 小于等于
- ! expression 如果表達(dá)式為假則結(jié)果為真
- 文件測試
- -d file 文件是一個目錄為真
- -e file 文件存在則為真,歷史上,-e選項不可移植,通常使用的是-f選項
- -f file 文件是一個普通文件則為真
- -g file 文件得set-group-id位被設(shè)置則結(jié)果為真
- -r file 文件可讀則結(jié)果為真
- -s file 文件大小不為0 為真
- -u file 文件的set-user-id 位被設(shè)置則結(jié)果為真
- -w file 文件可寫則為真
- -x file 文件可執(zhí)行則結(jié)果為真
控制結(jié)構(gòu)
if語句
if condition
then
statements
elif condition1
statements
else
statements
fi
for 語句
for variable in values
do
statements
done
有用的變量 $(commands) for 命令的參數(shù)表來自括在$()中的命令的輸出結(jié)果
eg:
#!/bin/bash
for file in $(ls f*.sh); do
lpr $file
done
exit 0
while語句
while condition do
statements
done
eg:
echo “please input passwd ”
read trythis
while [ “trythis !” = “passwd” ] ; do
echo “sorry ,try again !!”
read trythis
done
exit 0
until 語句
與while相似,只是把條件測試反過來了,循環(huán)將反復(fù)執(zhí)行直到條件為真,而不是在條件為真時反復(fù)執(zhí)行。
until condition
do
statements
done
eg:
#!/bin/bash
until who | grep “$1” >/dev/null
do
sleep 60
done
#now ring the bell and announce the expected user.
echo –e ‘\a’
echo “****$1 has just logged in ****”
exit 0
case 語句
case variable in
pattern [ | pattern ] …) statemetns ;;
pattern [ | pattern ] …) statemetns ;;
esac
****************************************************
#!/bin/sh
echo “Is it morning ? Please answer yes or no “
read timeofday
case “$tineofday” in
yes) echo “Good Morning”;;
no) echo “Good Afternoon”;;
y ) echo “Good Morning “;;
n ) echo “Good Afternoon” ;;
* ) echo “Sorry ,answer not recognized ” ;;
esac
****************************************************
#!/bin/sh
echo “Is it morning ? Please answer yes or no “
read timeofday
case “$tineofday” in
yes|y|YES|Y) echo “Good Morning”;;
no|n|NO|N) echo “Good Afternoon”;;
* ) echo “Sorry ,answer not recognized ” ;;
esac
exit 0
****************************************************
#!/bin/sh
echo “Is it morning ? Please answer yes or no “
read timeofday
case “$tineofday” in
yes|y|YES|Y) echo “Good Morning”
echo “up bright and early this morning”
;;
no|n|NO|N) echo “Good Afternoon”
; ;
* ) echo “Sorry ,answer not recognized ”
echo “Please answer yes or no ”
exit 1 ; ;
esac
命令列表
- AND 列表
從左邊開始順序執(zhí)行每條命令,如果一條命令返回的是true,右邊的下一條命令才能夠執(zhí)行。
statement1 && statement2 && statements3 && …
eg:
#!/bin/bash
touch file_one
rm -f file_two
if [ -f file_one ] && echo “hello” && [-f file_two ] && echo “there”
then
echo “in if”
else
echo “in else”
fi
exit 0
- OR 列表
statement1 || statement2 || statement3 || …
從左邊開始順序執(zhí)行,如果一調(diào)命令返回的是false,它右邊的下一條命令才能夠被執(zhí)行,如此持續(xù)直到有一條命令返回true,或者所有的命令執(zhí)行完畢。
eg:
#!/bin/bash
rm –f file_one
if [ -f file_one ] || echo “hello” ||echo “there”
then
echo “in if”
else
echo “in else”
fi
exit 0
語句塊
如果想在某些只允許使用單個語句的地方使用多條語句,可以使用花括號來構(gòu)造一個語句塊。
eg:
get-confirm && {
grep –v “$cdcattnum” $tracks_file > $temp_file }
函數(shù)
function_name () {
statements
}
所有的函數(shù)定義需要放在函數(shù)調(diào)用之前
eg:
#!/bin/bash
foo() {
echo “fuction foo is executing”
}
echo “script starting “
foo
echo “scripts ended”
exit 0
當(dāng)一個函數(shù)被調(diào)用時,腳本程序的位置參數(shù)$*,$@,$#等會替換為函數(shù)的參數(shù),可以用此方法來讀取傳遞給函數(shù)的參數(shù)。
可以用local 關(guān)鍵字在shell函數(shù)中聲明局部變量,此變量只在函數(shù)的作用范圍內(nèi)有效,如果一個局部變量和一個全局變量的名字相同,前者會覆蓋后者。
eg:
#!/bin/bash
sample_text=”gloabel_variable”
foo() {
local sample_text=”local variable “
echo “Funcition foo is executing “
echo $sample_text
}
echo “script starting “
echo $sample_text
foo
echo “script ended”
echo $sample_text
# !/bin/bash
yes_or_no() {
echo “Is your name $* ? ”
while true
do
echo –n “Enter yes or no :”
read x
case “$x in
y|yes ) return 0;;
n|no) return 1 ;;
* ] echo “Answer yes or no “
esac
done
}
下面是主程序
echo “Original parameters are $* ”
if yes_or_no “$1”
then
echo “Hi $1,nice name “
else
echo “never mind”
fi
exit 0
命令
break命令
用來跳出for,while或者until循環(huán),可以為break提供一個數(shù)值參數(shù)來表示需要跳出的循環(huán)層數(shù),但是會大大降低程序的可讀性。
#!/bin/sh
rm –rf fred*
echo > fred1
echo >fred2
mkdir fred3
echo >fred4
for file in fred*
do
if [ -d “$file” ]; then
break;
fi
done
echo first directory starting fred was $file
rm –rf fred*
exit 0
: 命令
冒號: 是一個空命令,偶爾被用于簡化條件邏輯,相當(dāng)于true的一個別名
#!/bin/bash
rm –f fred
if [-f fred ] ;then
:
else
echo file fred did not exist
fi
exit 0
continue 命令
類似C語言的continue,進(jìn)入下一次循環(huán)繼續(xù)進(jìn)行
#!/bin/bash
rm –rf fred*
echo > fred1
echo >fred2
mkdir fred3
echo > fred4
for file in fred*
do
if [ -d “$file” ] ; then
echo “skipping directory $file”
continue
fi
continue 可以帶一個可選的參數(shù)用來表示希望繼續(xù)執(zhí)行的循環(huán)嵌套層數(shù),也就是說你可以部分的跳出嵌套循環(huán)
eg :
for x in 1 2 3
do
echo before $x
continue 1
echo after $x
done
.命令與source命令
點(diǎn)命令用于在當(dāng)前shell中執(zhí)行命令;
. ./sehll_scrips
與source ,命令相似,用于在當(dāng)前shell 環(huán)境中執(zhí)行腳本
source命令能夠使子shell中的操作改變父shell中的環(huán)境變量,如果直接運(yùn)行則不能改變父shell中的環(huán)境變量
載入環(huán)境變量
echo 命令
echo –n “string to output ”
echo –e ‘\a’
eval命令 很有用????
允許對參數(shù)進(jìn)行求值,
foo =10
x=foo
y=’$’$X
echo $y
輸出為$foo
foo=10
x=foo
eval y=’$’$x
echo $y
輸出為10
so,eval命令像一個額外的$,給出一個變量的值的值
exec命令
exec有兩種不同的用法,典型用法是將當(dāng)前shell替換為一個不同的程序
- exec wall “Thanks for all the fiwsh”
腳本程序中會用wall替換當(dāng)前的shell程序,exec命令后的代碼都不會執(zhí)行,因?yàn)閳?zhí)行這個腳本的shell已經(jīng)不存在了
exec的各種方法是修改當(dāng)前文件描述符
exec 3 <afile 這種用法很少見。
exit n命令
exit命令使用腳本程序以退出碼結(jié)束運(yùn)行
#!/bin/bash
[ -f .profile ] && exit 0 || exit 1
export 命令
此命令將作為它參數(shù)的變量導(dǎo)出到子shell中,并使之在子shell中有效。默認(rèn)情況下, 在一個shell中被創(chuàng)建的變量在這個shell調(diào)用的下級shell中是不可用的,export 命令把自己的參數(shù)創(chuàng)建為一個環(huán)境變量,而這個環(huán)境變量可以被當(dāng)前調(diào)用的其他腳本和程序看見。
expr命令
expr命令將它的參數(shù)當(dāng)做一個表達(dá)式來求值,它的最常見的用法就是進(jìn)行如下形式的簡單數(shù)學(xué)運(yùn)算:
x=‘expr $x =1’
printf命令
和 c語言中的使用方法相似,但是不支持浮點(diǎn)數(shù),因?yàn)閟hell中所有的算術(shù)運(yùn)算都是按照整數(shù)來進(jìn)行計算的。
return命令
這個命令的作用是是函數(shù)返回,可以有一個數(shù)值參數(shù)作為函數(shù)的返回值。
set命令
set命令的作用是為shell設(shè)置參數(shù)變量
eg:
得到月份
#!/bin/bash
echo the date is $(date)
set $(date)
echo The month si $2
exit 0
shift 命令
此命令將所有的參數(shù)變量左移一個位置,使$2變成$1,以此類推,原來$1的值將被丟棄,而$0的值將保持不變,如果shift命令時指定了一個數(shù)值參數(shù),則表示所有的參數(shù)將左移一定的次數(shù)。
eg:
#!/bin/bash
while [ “$1” !=” “ ];do
echo “$1”
shift
done
exit 0
trap命令
trap命令用于指定在接收到信號后將要采取的行動。
trap command signal
HUP(1) 掛起,通常因終端或用戶退出而引發(fā)
INT(2) 中斷。。。。。。。。。
more man 7 signal
eg:
#!/bin/bash
trap ‘rm –f /tmp/tmp_file_$$
date > /tmp/tmp_file_$$
echo “please interupt (CTRL-C) to interrupt
while
……………..懶得敲了 linux程序設(shè)計中文第四版,page51
unset 命令
其作用是從環(huán)境中刪除變量或函數(shù),不能刪除shell本身定義的只讀變量(如IFS)
#!/bin/bash
foo =”Hello World”
echo $foo
unset foo
echo $foo
find和grep命令
find / -name test –print
從根目錄開始查找test的文件,輸出文件的完整路徑
find / - mount –name test –print
這次不會搜索掛載的其他文件系統(tǒng)
還有好多,這里就不贅述了
grep命令使用正則表達(dá)式
-I 忽略大小寫
-c 輸出匹配行的數(shù)目,不輸出匹配行
-l 只列出包含匹配行的文件名,不輸出真正的匹配行
-v 對匹配模式取反,搜索不匹配行
等等
export命令
用于導(dǎo)出環(huán)境變量
/etc/profile
/etc/bashrc
$HOME/.bash_profile
$HOME/.bashrc
$HOME/.bash_logout