http://www.blogjava.net/liubowu/archive/2007/06/25/99317.html
\d | 本地端时间的日期 |
\l | 显示第几个终端机接口 |
\m | 显示硬件的等级 (i386/i486/i586/i686...) |
\n | 显示主机的网络名称 |
\o | 显示 domain name |
\r | 操作系统的版本 (相当于 uname -r) |
\t | 显示本地端时间的时间 |
\s | 操作系统的名称 |
\v | 操作系统的版本 |
#source ~/.bashrc
#. ~/.bashrc
$PATH:决定了shell将到哪些目录中寻找命令或程序。
$HOME:当前用户主目录。
$MAIL:是指当前用户的邮件存放目录。
$SHELL:是指当前用户用的是哪种Shell。
$HISTSIZE:是指保存历史命令记录的条数。
$LOGNAME:是指当前用户的登录名。
$HOSTNAME:是指主机的名称,许多应用程序如果要用到主机名的话,通常是从这个环境变量中来取得的。
$LANG/LANGUGE:是和语言相关的环境变量,使用多种语言的用户可以修改此环境变量。
$PS1:是基本提示符,对于root用户是#,对于普通用户是$,也可以使用一些更复杂的值。
$PS2:是附属提示符,默认是“>”。
$IFS:输入域分隔符。当shell读取输入时,用来分隔单词的一组字符,它们通常是空格、制表符和换行符。
$0:shell脚本的名字。
$#:传递给脚本的参数个数。
$$:shell脚本的进程号,脚本程序通常会用它生成一个唯一的临时文件,如/tmp/tmfile_$
echo:显示指定环境变量。
export:设置新的环境变量。
env:显示所有环境变量。
set:显示所有本地定义的shell变量。
unset:清除环境变量。
将一个路径加入到PATH变量中:
如在PATH 这个变量当中“累加”一个新目录 这个目录
#1,控制台中:
$ PATH="$PATH":/my_new_path"
#2,修改profile文件:
$ vi /etc/profile
在里面加入:
export PATH="$PATH:/my_new_path"
#3,修改.bashrc文件:
$ vi /root/.bashrc
在里面加入:
export PATH="$PATH:/my_new_path"
#后两种方法一般需要重新注销系统才能生效,最后可以通过echo命令测试一
* | 代表0个或多个任意字符 |
? | 代表一定有一个任意字符 |
[ ] | [abcd],表示一个字符,或a或b或c或d |
[-] | [0-9],表示一个数字,0到9之间的某个 |
[^] | [^abc],表示一个字符,且不是a、b、c |
[root@linux ~]# ls test* #那个 * 代表后面不论接几个字符都予以接受
[root@linux ~]# ls test? #那个 ? 代表后面"一定"要接"一个"字符
[root@linux ~]# ls test??? #那个 ??? 代表"一定要接三个"字符!
[root@linux ~]# cp test[1-5] /tmp # 将 test1, test2, test3, test4, test5 若存在的话,就拷贝到 /tmp
[root@linux ~]# cp test[!1-5] /tmp # 只要不是 test1, test2, test3, test4, test5 之外的其它 test?拷贝到 /tmp
[root@linux ~]# cd /lib/modules/`uname -r`/kernel/drivers # 系统先执行 uname -r 找出输出结果;将结果累加在目录上面,来执行 cd 的功能!
= cd /lib/modules/$(uname -r)/kernel #另外,这个 quot (`) 的功能,也可以利用 $() 来取代喔!
[root@linux ~]# cp *[A-Z]* /tmp #表示文件中包含大写字母
[root@linux ~]# ls -lda /etc/*[35]* #表示文件中包含数字3或者5.
# | 注释 |
\ | 转义字符 |
| | 管道(pipe) |
; | 连续命令 |
~ | 用户主文件夹 |
$ | 变量前导符 |
& | 作业控制的后台运行 |
! | 逻辑非 |
/ | 目录分隔符 |
>,>> | 数据流重定向,输出导向,分别是“替换“和”增加“ |
<,<< | 数据流重定向,输入导向 |
' ‘ | 单引号,不具有变量置换功能 |
” “ | 双引号,具有变量置换功能 |
` ` | ` `中内容可以先执行的命令,也可以用$( )来替换 |
( ) | 在中间为子shell的起始与结束 |
{ } | 在中间为命令块的组合 |
Ctrl + C | 终止目前的命令 |
Ctrl + D | 输入结束(EOF),例如邮件结束的时候; |
Ctrl + M | 就是 Enter 啦! |
Ctrl + S | 暂停屏幕的输出 |
Ctrl + Q | 恢复屏幕的输出 |
Ctrl + U | 在提示字符下,将整列命令删除 |
Ctrl + Z | 暂停目前的命令 |
0 | 标准输入 standard input |
1 | 标准输出standard output |
2 | 错误输出error output |
ls -al > newtxt #本来ls -al 命令预设输出到屏幕,现在被重新导出到newtxt文档。
ls -al >> newtxt #现将ls -al 命令输出结果“增加”到文件newtxt末尾。
$ find /home -name testing > list_right 2> list_error
有 Permission 的那几行错误信息都会跑到 list_error 这个档案中,至于正确的输出数据则会存到 list_right 这个档案中。
将错误信息不要(置于垃圾箱中/dev/null)
$ find /home -name testing > list_right 2> /dev/null
将正确输出和错误输出都放置到同一个文件中testing中去
$ find /home -name testing > list 2> list <==错误写法
$ find /home -name testing > list 2>&1 <==正确写法
另外,这里区分一下command>file 2>file 与 command>file 2>&1:
分号; | cmd;cmd 多条命令顺序执行,执行顺序是从左到右的顺序。 |
与&& | cmd1 && cmd2 若cmd1执行完毕且正确执行($?=0),则开始执行cmd2 若cmd2执行完毕且为错误($? !=0),则cmd2不执行 |
或|| | cmd1 || cmd2 若cmd1执行完毕且正确执行($?=0),则cmd2不执行 若cmd2执行完毕且为错误($? !=0),则开始执行cmd2 |
ls /tmp/abc || mkdir /tmp/abc && touch /tmp/abc/hehe
该范例总会创建/tmp/abc/hehe文件。而不是先执行后面的。
[ -f file1 ] && exit 0 || exit 1
$ sh -x ./script.sh
#!/bin/sh
符号#!用来告诉系统它后面的参数是用来执行该文件的程序,在这个例子中我们使用/bin/sh来执行程序。
chmod +x filename
当编辑好脚本时,如果要执行该脚本,还必须使其可执行。 这样才能用./filename 来运行。
在进行shell编程时,以#开头的句子表示注释,直到这一行的结束。
文档可以这样写:
###################################################################################
## The script is used for the regression of lineage jar with latest hive-exec..jar
## , expression_analyze.jar, parse_common.jar, field_lineage.jar, ast_parser.jar
## in trunk.
###################################################################################
区块可以这样写
###############################################
## PARAMETERS
##
2.3.1 变量类型默认为字符串类型
#!/bin/sh
name="Jack"
s="$name, hello!" #注意等号"="前后都不能有空格。建议字符串用双引号(单引号表示纯字符串,不支持$等)。
echo $s #输出Jack, hello!(若s用单引号,则输出$name, hello!)
unset s #删除变量s
2.3.2 单引号,双引号,无引号
s="./*"
echo $s #这是变量,命令即为echo ./* ,通配符解开为:./1.sh ./a ./b ./c
echo '$s' #这里的单引号表示一个字符串,字符串中的$等符号不能转义,输出:$s
echo "$s" #这里的双引号表示一个字符串,字符串中的$等符号要转义,其中$s为变量,所以输出./*
2.3.3 参数扩展——花括号
num=2
echo "this is the $numnd" #this is the
这并不会打印出"this is the 2nd",而仅仅打印"this is the ",因为shell会去搜索变量numnd的值,但是这个变量时没有值的。可以
使用花括号来告诉shell我们要打印的是num变量:
num=2
echo "this is the ${num}nd" #this is the 2nd
这将打印: this is the 2nd
${name:-default} 使用一个默认值(一般是空值)来代替那些空的或者没有赋值的变量name;
${name:=default}使用指定值来代替空的或者没有赋值的变量name;
${name:?message}如果变量为空或者未赋值,那么就会显示出错误信息并中止脚本的执行同时返回退出码1。
${#name} 给出name的长度
${name%word} 从name的尾部开始删除与word匹配的最小部分,然后返回剩余部分
${name%%word} 从name的尾部开始删除与word匹配的最长部分,然后返回剩余部分
${name#word} 从name的头部开始删除与word匹配的最小部分,然后返回剩余部分
${name##word} 从name的头部开始删除与word匹配的最长部分,然后返回剩余部分
举例如下,使用cjpeg命令将一个GIF的文件转换为JPEG的文件:
$ cjpeg image.gif > image.jpg
也许有时我们会在大量的文件上进行这样的操作.这时我们如何自动重定向?我们可以很容易的这样来做:
#!/bin/sh
for image in *.gif
do
cjpeg $image > ${image%%gif}jpg
done
2.3.4 注意变量与变量字符串的问题:
read a
if [ $a = "yes" ];then
echo "OK"
fi
if [ "$a" = "yes" ];then
echo "OK"
fi
这里$a是变量a的值,"$a"是对变量a做字符串处理结果。如果read a 时直接回车,那么$a就是空,而不是"",这时程序变成了 if [ = "yes" ]就错了,所以一般用双引号括起来,表示使用字符串值,且转义其中的$变量。
2.3.5 注意打印"*"的问题:
#!/bin/sh
sql='select * from gexing;'
echo $sql #其中的*会被替换成所有文件,这就相当于echo select * from table;
echo "$sql" #这就相当于echo "select * from table"
names=$var_name1$var_name2 #注意,两个变量之间没有空格
sentence=${names}"hello" #直接连接
语法:
declare [+/-][afrix] variable
说明:
+/- "-"可用来指定变量的属性,"+"则是取消变量所设的属性。
-a 定义变量variable为数组(array)类型
-i 定义变量variable为整数(integer)类型
-r 定义变量variable为只读(readonly)类型
-x 用法与export一样,将variable设置为环境变量
示例1:让变量 sum 保存 100+300+50 的加和结果
[root@linux ~]# sum=100+300+50
[root@linux ~]# echo $sum #结果为:100+300+50
[root@linux ~]# declare -i sum=100+300+50
[root@linux ~]# echo $sum #结果为:450
示例2:生成随机数
[root@linux ~]# declare -i number=$RANDOM*10/32767 ; echo $number
foo=1
foo=$(($foo+1))
echo $ (( 13 % 3 ))
#!/bin/bash
#赋值
a[0]=1 #第一种赋值方法
a[1]=2
a[2]=3
b=(6,7,8,9,10) #第二种赋值方法
#取值
echo ${b[0]} #用${数组名[下标]},下标是从0开始。下标是*或者@,则得到整个数组内容。输出6
echo ${b[*]:1:3} #直接通过${数组名[@或*]:起始位置:长度}切片原先数组,输出7 8 9
echo ${b[*]::3} #输出6 7 8(前三个元素)
#遍历
echo ${b[*]} #遍历数组除用循环外还可用:“数组名[*]”或“数组名[@]”,输出6 7 8 9 10
echo ${b[@]} #输出:6 7 8 9 10
for var in ${arr[@]};do echo $var; done #分行输出:6 7 8 9 10
#数组个数
echo ${#b[*]} #输出:5
echo ${#b[@]} #输出:5
#修改和删除
b[0]=0 #修改:重新赋值
echo ${b[*]} #输出:0 7 8 9 10
unset b[0] #删除:删除第一个元素
echo ${b[*]} #输出:7 8 9 10
{...}
$* 为"1 2 3"(在一个变量中列出所有参数,各个参数之间用环境变量IFS中的第一个字符分隔开,所以如果IFS置空,则会变成"123")
$@ 为"1 2 3"($*的变体,不适用环境变量IFS,而是以空格连接参数,所以当IFS置空,则扔为"1 2 3")
$# 为3(参数数量)
$0 $n,用来存放函数调用或脚本执行时传入的参数,$0为test.sh
$1 为1,以此类推
$$ 脚本运行的当前进程的ID号
$! 后台运行的最后一个进程的ID号
$- 显示shell使用的当前选项
$? 显示最后命令的退出状态,0表示无错误(这个变量也常常用来打印输出,在脚本调试时标记某个shell命令或某个函数是否正确执行,但是要注意,$?记载的是最近的函数或命令的退出状态,因此打印时应该立即打印以获得正确的信息)
[root@linux ~]# read [-pt] variable
参数:
[root@linux ~]# read -p "Please keyin your name: " -t 30 name
Please keyin your name: VBird Tsai
[root@linux ~]# echo $name
VBird Tsai
echo -e hello,"/n"world!
设置颜色
设置彩色文本 重置=0 黑色=30 红色=31 绿色=32...
echo -e "\e[1;31m This is red text \e[0m"
设置彩色背景 重置=0 黑色=40 红色=41 绿色=42...
echo -e "\e[1;42m This is green background \e[0m"
注意:如果alias ls = 'ls --color' 这时候 ls | xargs tar -czvf 1.tar.gz会出现以上类似的错误tar: \033[00mxy_psp_proto.h\033[00m: Cannot stat: No such file or directory
用echo -n 去掉末尾的换行符。
echo -n "string to output"
输出命令printf(默认无换行符)
printf "hello"
#!/bin/sh
# we have less than 3 arguments. Print the help text:
if [ $# -lt 3 ] ; then
cat << EOF
[批量换名:对文件名进行批量替换]
USAGE: ren 'regexp' 'replacement' files...
EXAMPLE: rename all *.HTM files in *.html:
sh $0 'HTM$' 'html' *.HTM
HELP
EOF
exit 0
fi
OLD="$1"
NEW="$2"
# The shift command removes one argument from the list of
# command line arguments.
shift
shift
# $* contains now all the files:
for file in $*; do
if [ -f "$file" ] ; then
#这里的|是管道,将源文件名进行词汇替换
newfile=`echo "$file" | sed "s/${OLD}/${NEW}/g"`
if [ -f "$newfile" ]; then
echo "ERROR: $newfile exists already"
else
echo "renaming $file to $newfile ."
mv "$file" "$newfile"
fi
fi
done
分析:
这是一个复杂一些的例子。让我们详细讨论一下。第一个if表达式判断输入命令行参数是否小于3个 (特殊变量$# 表示包含参数的个数) 。如果输入参数小于3个,则将帮助文字传递给cat命令,然后由cat命令将其打印在屏幕上。打印帮助文字后程序退出。 如果输入参数等于或大于3个,我们就将第一个参数赋值给变量OLD,第二个参数赋值给变量NEW。下一步,我们使用shift命令将第一个和第二个参数从 参数列表中删除,这样原来的第三个参数就成为参数列表$*的第一个参数。然后我们开始循环,命令行参数列表被一个接一个地被赋值给变量$file。接着我 们判断该文件是否存在,如果存在则通过sed命令搜索和替换来产生新的文件名。然后将反短斜线内命令结果赋值给newfile。这样我们就达到了我们的目 的:得到了旧文件名和新文件名。然后使用mv命令进行重命名。
test expression
其中条件expression是一个表达式,该表达式可由数字、字符串、文本和文件属性的比较,同时可加入各种算术、字符串、文本等运算符。
[ expression ]
其中“[ ”是启动测试的命令,但要求在expression后要有一个“ ]”与其配对。使用该命令时要特别注意“[”后和“]”前的空格是必不可少的。
ls | grep "core"
2,使用反斜线
tar -zcvf lastmod.tar.gz `find . -mtime -1 -type f -print`
3,使用$()
more $(grep -l POSIX *)
常用命令语法及功能
echo "some text" | 将文字内容打印在屏幕上 |
ls | 文件列表 |
wc –l file wc -w file wc -c file |
计算文件行数 计算文件中的单词数 计算文件中的字符数 |
cp sourcefile destfile | 文件拷贝 |
mv oldname newname | 重命名文件或移动文件 |
rm file | 删除文件 |
grep 'pattern' file | 在文件内搜索字符串比如:grep 'abc' 1.txt |
cut -b colnum file | 指定欲显示的文件内容范围,并将它们输出到标准输出设备 比如:输出每行第5个到第9个字符cut -b5-9 file.txt 千万不要和cat命令混淆,这是两个完全不同的命令 |
cat file.txt | 输出文件内容到标准输出设备(屏幕)上 |
file somefile | 得到文件类型 |
read var | 提示用户输入,并将输入赋值给变量 |
sort file.txt | 对file.txt文件中的行进行排序 |
uniq | 删除文本文件中出现的行列 比如: sort file.txt | uniq |
expr | 进行数学运算Example: add 2 and 3expr 2 "+" 3 |
find | 搜索文件 比如:根据文件名搜索find . -name filename -print |
tee | 将数据输出到标准输出设备(屏幕) 和文件 比如:somecommand | tee outfile |
basename file | 返回不包含路径的文件名 比如: basename /bin/tux将返回 tux |
dirname file | 返回文件所在路径 比如:dirname /bin/tux将返回 /bin |
head file tail file |
打印文本文件开头几行 打印文本文件末尾几行 |
sed | Sed是一个基本的查找替换程序。 |
awk | awk 用来从文本文件中提取字段。 |
if ....; then
....
elif ....; then
....
else
....
fi
大多数情况下,可以使用测试命令来对条件进行测试。比如可以比较字符串、判断文件是否存在及是否可读等等…
通常用" [ ] "来表示条件测试。注意这里的空格很重要。要确保方括号的空格。
[ ! -d $CASE ] && echo "No case path $CASE, quit!" && exit 1 #判断如果没有目录$CASE就退出
[ -f "somefile" ]
:判断是否是一个文件
直接执行以下脚本:
#!/bin/sh
if [ "$SHELL" = "/bin/bash" ]; then
echo "your login shell is the bash (bourne again shell)"
else
echo "your login shell is not bash but $SHELL"
fi
变量$SHELL包含了登录shell的名称,我们和/bin/bash进行了比较。
快捷操作符可用的。这里有个例子:
#!/bin/sh
mailfolder=./lineage_case
[ ! -r "$mailfolder" ]&&{ echo "Can not read $mailfolder" ; exit 1; }
dir="${mailfolder}/*"
#grep "^From" `echo "$dir"` #
grep "^From" $dir #这两者效果相同,关键在于要知道这里的*要表达的是真正的*,还是表示通配,这里表示通配
sql="select * from table;"
echo "$sql" #这里要表达的是真正的*,而不是通配
该脚本首先判断mailfolder是否可读。如果可读则打印该文件中的"From" 一行。如果不可读则或操作生效,打印错误信息后脚本退出。{}构成匿名函数。
case ... in
...) do something here ;;
esac
让我们看一个例子。 file命令可以辨别出一个给定文件的文件类型,比如:
#!/bin/sh
ftype=`file "$1"`
case "$ftype" in
"$1: Zip archive"*)
unzip "$1" ;;
"$1: gzip compressed"*)
gunzip "$1" ;;
"$1: bzip2 compressed"*)
bunzip2 "$1" ;;
*) echo "File $1 can not be uncompressed with smartzip";;
esac
您可能注意到我们在这里使用了一个特殊的变量$1。该变量包含了传递给该程序的第一个参数值。也就是说,当我们运行:
再看一例
#!/bin/sh
echo “Is it morning? Please answer yes or no”
read timeofday
case “$timeofday” in
[yY] | [Yy][Ee][Ss])
echo “Good Morning”;;
[nN]*)
echo “Good Afternoon”;;
*)
echo “Sorry, answer not recognized”
exit 1
;;
esac
exit 0
select var in ... ; do
break
done
.... now $var can be used ....
下面是一个例子:
#!/bin/sh
echo "What is your favourite OS?"
select var in "Linux" "Gnu Hurd" "Free BSD" "Other"; do
break
done
echo "You have selected $var"
下面是该脚本运行的结果:
What is your favourite OS?
1) Linux
2) Gnu Hurd
3) Free BSD
4) Other
#? 1
You have selected Linux
while表达式:
while ...; do
....
done
while-loop 将运行直到表达式测试为真。关键字"break" 用来跳出循环。而关键字”continue”用来不执行余下的部分而直接跳到下一个循环。
例如:
#!/bin/sh
i=1
while [ "$i" -le 10 ];do
echo "num is $i"
i=$((i+1))
done
或:
#!/bin/sh
i=1
while [ "$i" -le 10 ]
do
echo "num is $i"
i=$((i+1))
done
until 条件
do
语句
done
以下代码直到有内容时返回值才为0,因此跳过do|done,然后输出echo。其中的>/dev/null只是为了将结果不在屏幕显示,不影响返回值。
until who | grep "$1" > /dev/null
do
sleep(60)
done
echo "$1 has logged in"
for var in ....; do
....
done
在下面的例子中,将分别打印ABC到屏幕上:
#!/bin/sh
for var in A B C ; do
echo "var is $var"
done
下面是一个更为有用的脚本showrpm,其功能是打印一些RPM包的统计信息:
#!/bin/sh
# list a content summary of a number of RPM packages
# USAGE: showrpm rpmfile1 rpmfile2 ...
# EXAMPLE: showrpm /cdrom/RedHat/RPMS/*.rpm
for rpmpackage in $*; do
if [ -r "$rpmpackage" ];then
echo "=============== $rpmpackage =============="
rpm -qi -p $rpmpackage
else
echo "ERROR: cannot read file $rpmpackage"
fi
done
这里出现了第二个特殊的变量$*,该变量包含了所有输入的命令行参数值。
for的另一种用法:
for (( 初始值; 限制值; 执行步长 ))
do
程序段
done
例如:
#!/bin/bash
# Program:
# Try do calculate 1+2+....+${your_input}
# History:
# 2005/08/29 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
read -p "Please input a number, I will count for 1+2+...+your_input: " nu
s=0
for (( i=1; i<=$nu; i=i+1 ))
do
s=$(($s+$i))
done
echo "The result of '1+2+3+...+$nu' is ==> $s"
break
continue
通常,当一个脚本执行一条外部命令或者脚本程序时,它会创建一个新的环境,也就是一个子shell,命令将在这个新环境中执行,在执行完毕后,这个环境被丢弃,留下退出码返回给父shell。但是外部的source命令和点命令在执行脚本程序中列出的命令时,使用的是调用该脚本程序的同一个shell。source命令或dot命令将外部命令放在当前进程(而不是子进程)环境中运行(类似c语言中的 #include语句),并继承当前进程(shell)的所有变量。
范例:用dot命令修改当前进程的环境变量
以下是文件classic_set (当前目录下)的内容:
version=classic
PATH=/usr/local/old_bin:/usr/bin:/bin:.
PS1=“classic>”
以下是文件latest_set (当前目录下)的内容:
version= latest
PATH=/usr/local/new_bin:/usr/bin:/bin:.
PS1=“latest >”
用dot 命令执行这两个shell脚本:
$ . ./classic_set
classic> echo $version
classic
classic> . latest_set
latest > echo $version
latest
latest >
在默认情况下,在一个shell里创建的变量在此shell调用的下级(子)shell里是不可用的。
export命令将作为它参数的变量导出到子shell中,并使之在子shell中有效,一旦一个变量被shell到处,它就可以被该shell调用的任何脚本使用,也可以被后续依次调用的任何shell使用。
将当前的shell替换为一个不同的程序,wall会替换整个脚本,然后原脚本exec语句后面的脚本内容都不会再继续运行。
...
exec wall "that's all,we will finish now"
...
#!/bin/sh
while [ "$1" != "" ];do
echo "$1"
shift
done
exit 0
trap命令用来指定在接收到操作系统信号之后将要采取的行动。脚本程序通常是从头到尾解释并运行的,所以必须把trap命令放在准备保护的脚本程序部分之前。
trap命令常见的用途在于脚本程序中断时完成清理工作,比如临时文件等。例子程序如下:
#!/bin/sh
trap 'rm -f /tmp/my_tmp_file_$$' INT
echo creating file /tmp/my_tmp_file_$$
date > /tmp/my_tmp_file_$$
echo "press interrupt (CTRL-C) to interrupt ......"
while [ -f /tmp/my_tmp_file_$$ ]; do
echo File exists
sleep 3
done
echo we never get here
exit 0
在这个脚本程序里,先用trap命令安排它在出现INT(中断)信号时执行“rm -f /tmp/my_tmp_file_$$”命令删除临时文件。然后让脚本程序进入一个while循环,在临时文件存在的情况下不断循环。当用户按下CTRL-C组合键时,语句rm -f /tmp/my_tmp_file_$$ 就会被执行,然后继续下一个循环。但是因为临时文件已经被删除了,所以while循环在第一次执行时就会正常退出。注:$$表示当前的shell进程号。运行该脚本,首先在tmp下创建临时文件my_tmp_file_$$,如果遇到INT中断,即Ctrl+c,即删除该文件。
使用后台运行的方式 & 以及wait函数来控制多进程步骤
#!/bin/bash
sh aa.sh
sh bb.sh &
p1=$!
sh cc.sh &
p2=$!
wait $p1 && wait $p2
[ function ] funname [()]
{
action;
[return int;]
}
说明:
1、可以带function f() 定义,也可以直接f() 定义,不带任何参数。
2、函数的参数默认保存在$1,$2,...中,$0中保存函数名。
3、函数的返回值默认是最后一条命令的运行结果,除非显示有return n(0-255)。返回值由$?获取。
4、先定义后使用。
其一,函数内部使用 return 这个命令,出函数后立刻用$?访问,return只能返回非负数整数 且超过255的会反卷,也就是256就会变成0。
即函数内部:return,函数外部:echo $?
#!bin/sh
function sum()
{
return $(($1+$2))
}
sum 1 2
echo $?
其二,函数内部使用echo这个命令输出想要返回的值,同时调用函数的时候把函数的执行结果赋值给一个变量,那么这个变量里才是真正想要的返回值。
即函数内部 echo,函数外部:c = $( sum 1 2)
#!bin/sh
function sum()
{
echo $(($1+$2))
}
c=$(sum 1 2)
echo $c
#!bin/sh
function sum()
{
echo $(($1+$2))
return $(($1-$2))
}
sum $1 $2 #这里因为调用函数,所以输出5+2=7
c=$(sum $1 $2) #这里调用函数被当做一条命令,因此其中的echo不起作用,因此只将函数体内最后一条语句的结果(而非返回值)保存在c中,即echo的结果。5+2=7.
echo $? #这是上一个函数调用的返回值,为3,(这里用$?,所以函数内部找return)
echo $c #这里用$c,所以函数内部找echo
运行结果:
$ . 1.sh 5 2
7
3
7
c=$(sum $1 $2); 在shell中,但括号里是命令语句。 因此,我们可以将shell中函数,看作是定义一个新的命令。
范例:下面是一个叫做xtitlebar的脚本,使用这个脚本您可以改变终端窗口的名称。这里使用了一个叫做help的函数。正如您可以看到的那样,这个定义的函数被使用了两次。
#!/bin/sh
# vim: set sw=4 ts=4 et:
help()
{
cat <
#!/bin/sh
help()
{
cat < shift by 2
--) shift;break;; # end of options
-*) echo "error: no such option $1. -h for help";exit 1;;
*) break;;
esac
done
命令:
原理:
这个脚本是如何工作的呢?脚本首先在所有输入命令行参数中进行循环,将输入参数与case表达式进行比较,如果匹配则设置一个变量并且移除该参数。根据unix系统的惯例,首先输入的应该是包含减号的参数.
###################################################################################
## The script is used for the test of ABC.jar in myApps
## @author:xing.gexing
## @date 2012-10-26 下午4:05:07
## @version V1.0
###################################################################################
###############################################
## PARAMETERS
##
SMOKE='true'
SMOKE_MAILTO='xing.gexing\@xxx.com'
MAILTO='xing.gexing\@xxx.com'
WHITE_LIST='white.list'
DIR='/home/admin'
WORKSPACE="${DIR}/myApps"
[ ! -d $WORKSPACE ] && echo "No case path $WORKSPACE, quit!" && exit 1
##############################################
## BUILD ABC.jar
##
SOURCE="$WORKSPACE/source"
DEST="$WORKSPACE/dest"
cd $TRUNK
svn up --username=xxx --password=ooo
[ $? -ne 0 ] && echo "svn up failed!!! quit!" && exit 1
ant clean && ant package
[ $? -ne 0 ] && echo "build ABC.jar failed!!! quit!" && exit 1
cp $TRUNK/build/dist/*.jar $DEST/lib
[ "$SMOKE" == 'true' ] && MAILTO=$SMOKE_MAILTO && WHITE_LIST=$WORKSPACE/white.list
sed -i "s@#MAIL_TO#@$MAILTO@" $ENV_CFG
sed -i "s@#WHITE_LIST#@$WHITE_LIST@" $ENV_CFG
sed -i "s@#TRUNK_PATH#@$WORKSPACE@" $ENV_CFG
###############################################
## run
##
python test.py -abcd
#!/bin/sh
##############################################
#Author GE Xing
#Time 2013 05 16
##############################################
# column title
#
echo -e "Reduce, jvm start, reduce done, reduce duration, write size, writing start, writing end, writing duration, real writing start, real writing end, real writing duration"
for line in `cat "./ids.result"`
do
##############################################
## task_name(REDUCE)
##
reduce_name=$line
#echo ----reduce_name:
echo -e "${reduce_name}, \c"
##############################################
## jvm start time
##
jvm_start=`cat mapAndReduce.result| grep $reduce_name | grep "given task" | awk '{print $1, $2}'`
#time_jvm_start=`date -d "$jvm_start" +%s`
time_jvm_start=$(transTime "$jvm_start")
#echo ----jvm_start:
echo -e "${time_jvm_start}, \c"
##############################################
## reduce done
##
reduce_done=`cat mapAndReduce.result| grep $reduce_name | grep " is in commit-pending, task state:" | awk '{print $1, $2}'`
time_reduce_done=$(transTime "$reduce_done")
#echo ----reduce_done:
echo -e "${time_reduce_done}, \c"
##############################################
## reduce duration
##
reduce_duration=`expr $time_reduce_done - $time_jvm_start`
#echo ----reduce_duration:
echo -e "${reduce_duration}, \c"
##############################################
## write size
##
write_size=`cat mapAndReduce.result| grep $reduce_name | grep "op: HDFS_WRITE, cliID:" | awk 'NR==1 {print $10}'`
#echo ----write_size:
echo -e "${write_size} \c"
##############################################
## writing start time
##
writing_start=`cat mapAndReduce.result| grep $reduce_name | grep "NameSystem.allocateBlock" | awk '{print $1, $2}'`
time_writing_start=$(transTime "$writing_start")
#echo ----writing_start:
echo -e "${time_writing_start}, \c"
##############################################
## writing end time
##
writing_end=`cat mapAndReduce.result| grep $reduce_name | grep "Removing lease on file" | awk '{print $1, $2}'`
time_writing_end=$(transTime "$writing_end")
#echo ----writing_end:
echo -e "${time_writing_end}, \c"
##############################################
## writing duration
##
writing_duration=`expr $time_writing_end - $time_writing_start`
#echo ----writing_duration:
echo -e "${writing_duration}, \c"
##############################################
## real writing start time
##
T=`cat mapAndReduce.result| grep $reduce_name | grep "op: HDFS_WRITE, cliID:" | awk '{print $1, $2, $22}'`
#echo -e "T $T\n"
t1=`echo $T |awk '{print $1, $2}'`
#echo -e "t1 $t1\n"
r1=$(transTime "$t1")
#echo -e "r1 $r1\n"
d1=`echo $T |awk '{print $3/1000}'`
#echo -e "d1 $d1\n"
b1=`expr $r1 - $d1`
#echo -e "b1 $b1\n"
#t2=`echo $T |awk '{print $4, $5}'`
#r2=`date -d "$t2" +%s`
#d2=`echo $T |awk '{print $6}'`
#b2=`expr $r2 - $d2`
#
#t3=`echo $T |awk '{print $7, $8}'`
#r3=`date -d "$t3" +%s`
#d3=`echo $T |awk '{print $9}'`
#b3=`expr $r3 - $d3`
#
#min=$b1
#if test $b2 -lt $min
# then
# min=$b2
#fi
#if test $b3 -lt $min
# then
# min=$b3
#fi
#
#max=$b1
#if test $b2 -gt $max
# then
# max=$b2
#fi
#if test $b3 -gt $max
# then
# max=$b3
#fi
real_writing_start=$b1
#echo ----real_writing_start:
echo -e "${real_writing_start}, \c"
##############################################
## real_writing end time
##
real_writing_end=$r1
#echo ----real_writing_end:
echo -e "${real_writing_end}, \c"
##############################################
## real_writing duration
##
#real_time_writing_start=`date -d "$real_writing_start" +%s`
#real_time_writing_end=`date -d "$real_writing_end" +%s`
#real_writing_duration=`expr $real_time_writing_end - $real_time_writing_start`
real_writing_duration=`expr $real_writing_end - $real_writing_start`
#echo ----real_writing_duration:
echo -e "${real_writing_duration}"
done
function transTime
{
echo "$1" | awk -F'[:, ]' '{print ($4+$3*60+$2*60*60)*1000+$5}'
}
bash -v sum.sh表示将代码执行之前,先将代码显示出来
[gexing111@gexing111 myapps]$ bash -v sum.sh
#!/bin/bashNO
bash -v sum.sh表示将代码执行过程中显示出来
NO
程序1:Hello.sh
#!/bin/bash
clear
echo "Welcome to my first Linux Program!"
echo "Enter your name :"
read response
echo "Hello,$response!"
程序2:readEmployees.sh
#!/bin/bash
clear
echo "Plz input your Name"
read Name
echo "Plz input your Age"
read Age
echo "Name:$Name Age:$Age">>mydata.dat
echo ""
echo "Employees:"
echo ""
cat mydata.dat
程序3:sum.sh
#!/bin/bash
let a=30
let b=20
let sum="$a + $b"
if test $a -lt $b
then
echo "OK"
else
echo "NO"
fi
程序4:mymenu.sh
#!/bin/bash
declare flag="1"
while [ $flag -eq "1" ]
do
echo "The Telephone Book"
echo ""
echo "1.Display A Telephone Number"
echo "2.Add A New Telephone NUmber"
echo ""
echo "Q Quit"
echo ""
echo "Enter your selection:"
read selection
case $selection in
"1")
echo "You want to display a telephone number."
getnum
;;
"2")
echo "You want to add a new telephone number."
addnum
;;
"q")
flag="0"
;;
"Q")
flag="0"
;;
*)
echo "You made an invalid selection."
esac
done
5,程序friends.sh
#!/bin/bash
for friend in "Mary Jones" "Joe Smith" "Sue Jones"
do
echo "Hello,$friend"
done
6,程序raining.sh
#!/bin/bash
declare raining="1"
while [ $raining -eq "1" ]
do
clear
echo ""
echo "Is it raining?"
echo ""
echo "1,YES"
echo "2,NO"
echo ""
echo "Enter your selection:"
read raining
done
echo "It stopped raining."
#!/bin/bash
clear
declare count1=1
declare count2
while [ $count1 -lt 6 ]
do
echo "Warning:There is a bug in your program!"
let count2=1
while [ $count2 -lt 20000 ]
do
let count2="$count2 + 1"
done
clear
let count2=1
while [ $count2 -lt 20000 ]
do
let count2="$count2 + 1"
done
let count1="$count1 + 1"
done
#!/bin/bash
let n=1
while [ $n -eq 1 ]
do
echo "Enter your name or \"stop\" to end:"
read name
case $name in
"stop")
echo "Bye!"
break
;;
*)
echo "Hi,$name!"
;;
esac
done
#!/bin/bash
clear
function display
{
echo "Welcome to the world"
echo "of functions."
}
display
#!/bin/bash
clear
function verify
{
if [ $# -ne 2 ]
then
echo "Wrong number of arguments!"
#字符串的比较用= 而数字的比较用-eq
elif [ $1 = "gexing111" ] && [ $2 = "111gexing" ]
then
echo "Verified"
else
echo "Rejected"
fi
}
verify $1 $2