虽然学过 Linux Shell 编程,但由于编写 Shell 脚本的机会实在是比较少 ( 通常在项目初期搭建开发环境时编写得比较 多一些 ) ,所以一 些语法久而久之就会忘了,一个简单的语法去翻书效率实在是慢,所以就个人整理了一个表格,由于我用的编程语言是 C/C++ ,所以在编程的时候往往脑海里面首 先浮现的是用 C 语 言怎么去编写它,所以我干脆拿 C 语言的语法来和 Shell 编程的语法作个对比表,这样查起来就方便了
要实现的功能 | C 语言编程 | Linux Shell 脚本编程 |
程序 / 脚本的参数传递 | int main(int argc , char** argv ) { if (argv != 4) { printf ( “Usage: %s arg1 arg2 arg3”, argv [0] ); return 1; }
printf (“arg1:%s/n”,argv[1]); printf (“arg2:%s/n”,argv[2]); printf (“arg3:%s/n”,argv[3]); return 0; } | #!/bin/sh
if [ $# -lt 3 ]; then echo "Usage: `basename $0` arg1 arg2 arg3" >&2 exit 1 fi
echo "arg1: $1" echo "arg2: $2" echo "arg3: $3" exit 0 |
int main(int argc , char** argv ) { int i ; for (i =1; i <=argc;i ++) { printf (“arg:%s/n”,argv [i ]); } return 0; } | #!/bin/sh
while [ $# -ne 0 ] do echo "arg : $1" shift done | |
逻辑 / 数值运算 | if (d == 0) | if [ "$D" -eq "0" ] ; then |
if (d != 0) | if [ "$D" -ne "0" ] ; then | |
if (d > 0) | if [ "$D" -gt "0" ] ; then | |
if (d < 0) | if [ "$D" -lt "0" ] ; then | |
if (d <= 0) | if [ "$D" -le "0" ] ; then | |
if (d >= 0) | if [ "$D" -ge "0" ] ; then | |
字符串比较 | if (strcmp (str,”abc ”)==0) { } | if [ "$STR" != "abc " ]; then fi |
输入和输出 | scanf (“%d”,&D ); | read D |
printf ( “%d”, D); | echo –n $D | |
printf ( “%d”,D ); | echo $D | |
printf ( “Press any to continue...”); char ch =getchar (); printf ( “/nyou pressed: %c/n”, ch ); | #!/bin/sh
getchar () { SAVEDTTY=`stty -g` stty cbreak dd if=/dev/tty bs =1 count=1 2> /dev/null stty -cbreak stty $SAVEDTTY }
echo -n "Press any key to continue..." CH=`getchar ` echo "" echo "you pressed: $CH" | |
| read D <&3 | |
程序 / 脚本的控制流程 | if (isOK ) { //1 } else if (isOK2) { //2 } else { //3 } | if [ isOK ]; then #1 elif [ isOK2 ]; then #2 else #3 fi |
switch (d) { case 1: printf (“you select 1/n”); break; case 2: case 3: printf (“you select 2 or 3/n”); break; default: printf (“error/n”); break; }; | case $D in 1) echo "you select 1" ;; 2|3) echo "you select 2 or 3" ;; *) echo "error" ;; esac | |
for (int loop=1; loop<=5;loop++) { printf ( “%d”, loop); } | for loop in 1 2 3 4 5 do echo $loop done | |
do { sleep(5); } while( !isRoot ); | IS_ROOT=`who | grep root` until [ "$IS_ROOT" ] do sleep 5 done | |
counter=0; while( counter < 5 ) { printf ( “%d/n”, counter); counter++; } | COUNTER=0 while [ $COUNTER -lt 5 ] do echo $COUNTER COUNTER=`expr $COUNTER + 1` done | |
while (1) { } | while : do done | |
break; | break 或 break n , n 表示跳出 n 级循环 | |
continue; | continue | |
函数与过程的定义 | void hello() { printf ( “hello/n” ); } … // 函数调用 hello(); | hello() { Echo “hello” } 或者 function hello() { Echo “hello” } … # 函数调用 hello |
函数的参数和返回值 | int ret = doIt (); if (ret == 0) { printf ( “OK/n” ); } | doIt if [ “$?” –eq 0 ] ; then echo “OK” fi 或者 RET = doIt if [ “$RET” –eq “0” ] ; then echo “OK” fi |
int sum(int a,int b) { return a+b ; } int s = sum(1,2); printf (“the sum is: %d/n”, s); | sum() { echo -n "`expr $1 + $2`" } S=`sum 1 2` #tab键上面的~ echo "the sum is: $S" | |
bool isOK () { return false; } if (isOK ) { printf ( “YES/n” ); } else { printf ( “NO/n” ); } | isOK () { return 1; } if isOK ; then echo "YES" else echo "NO" fi |
expr用法
expr命令一般用于整数值,但也可用于字符串。一般格式为:
expr argument operator argument
expr也是一个手工命令行计数器。
$expr 10 + 10
20
$expr 1500 + 900
2500
$expr 30 / 3
10
$expr 30 / 3 / 2
5
(注意运算符左右都有空格)
使用乘号时,必须用反斜线屏蔽其特定含义。因为shell可能会误解显示星号的意义。
$expr 30 * 3
90
17.5.1 增量计数
expr在循环中用于增量计算。首先,循环初始化为0,然后循环值加1,反引号的用法意
即替代命令。最基本的一种是从(expr)命令接受输出并将之放入循环变量。
$LOOP=0
$LOOP=`expr $LOOP + 1`
17.5.2 数值测试
可以用expr测试一个数。如果试图计算非整数,将返回错误。
$rr=1.1
$expr $rr + 1
expr: non-numeric argument
$rr=2
$expr $rr + 1
3
(注意:这个例子与原文不同)
这里需要将一个值赋予变量(不管其内容如何),进行数值运算,并将输出导入dev/null,
然后测试最后命令状态,如果为0,证明这是一个数,其他则表明为非数值。
$value=12
$expr $value + 10 > /dev/null 2>&1
$echo $?
0
这是一个数。
$value=hello
$expr $value + 10 > /dev/null 2>&1
$echo $?
2
这是一个非数值字符。
expr也可以返回其本身的退出状态,不幸的是返回值与系统最后退出命令刚好相反,成
功返回1,任何其他值为无效或错误。下面的例子测试两个字符串是否相等,这里字符串为
“hello”和“hello”。
$value=hello
$expr $value = "hello"
1
$echo $?
0
expr返回1。不要混淆了,这表明成功。现在检验其最后退出状态,返回0表示测试成功,
“hello”确实等于“hello”。
17.5.3 模式匹配
expr也有模式匹配功能。可以使用expr通过指定冒号选项计算字符串中字符数。.*意即任
何字符重复0次或多次。
$value=accounts.doc
$expr $value : '.*'
12
在expr中可以使用字符串匹配操作,这里使用模式. d o c抽取文件附属名。
$expr $value : '(.*).doc'
accounts
=============================
请问各位大虾:shell 中有数组吗?
当然有,用
$varname[0]=value1
$varname[1]=value2
....
来定义
用
$echo ${varname[0]}
方式来引用
你可以在bash shell的环境下编写函数,有两种定义函数的格式:
代码:
function functname()
{
shell commands
}
functname()
{
shell commands
}
下面是一个简单函数的脚本(ex1)示例:
代码:
message()
{
echo "message"
}
let i=1
while [ $i -le 3 ]
do
message
let i=$i+1
done
函数同样可以接受参数,$1存放第一个参数,$2存放第二个参数,$*存放输入参数的列表,...
代码:
$ more ex2
power()
{
x=$1
y=$2
count=1
result=1
while [ $count -le $y ]
do
result=`expr ${result} * $x`
count=`expr ${count} + 1`
done
echo $result
}
echo "Enter two numbers"
read num1 num2
echo -n "power is: "
power $num1 $num2
$ ex2
Enter two numbers
3 4
power is: 81
函数同样也可以返回值,使用return语句,在主程序(块)中,在调用函数之后保存返回状态$?的值.
代码:
power()
{
x=$1
y=$2
count=1
result=1
while [ $count -le $y ]
do
result=`expr ${result} * $x`
count=`expr ${count} + 1`
done
return $result
}
echo "Enter two numbers"
read num1 num2
power $num1 $num2
answer=$?
echo "$num1 to $num2 is $answer"
你也可以编写递归函数:
代码:
power()
{
x=$1
y=$2
if [ $y -eq 1 ]
then
return $x
else
y=`expr $y - 1`
power $x $y
result=`expr $? * $x`
return $result
fi
}
echo "Enter two numbers"
read num1 num2
power $num1 $num2
answer=$?
echo "$num1 to $num2 is $answer"
默认情况下,所有函数的变量都是全局变量.你可以用typeset去声明一个局部变量:
代码:
easy()
{
typeset a
a=`expr $1 + $2`
b=`expr $1 + $2`
echo "easy a is " $a
echo "easy b is " $b
}
a=10
b=20
easy $a $b
echo "global a is " $a
echo "global b is " $b
Output:
easy a is 30
easy b is 30
global a is 10
global b is 30
如果要在脚本中多次使用函数,可以把它放在一个函数目录中,像一个普通文件一样,使用的时候把它放在脚本开始的地方:
. functionfile
$ more power
代码:
power()
{
x=$1
y=$2
if [ $y -eq 1 ]
then
return $x
else
y=`expr $y - 1`
power $x $y
result=`expr $? * $x`
return $result
fi
}
$ more small
代码:
. power
echo "Enter two numbers:"
read x y
power $x $y
result=$?
echo "Answer is:" $result
$ small.ksh
2 5
Answer is: 32
dd命令:
功能说明:读取,转换并输出数据。
语 法:dd [bs=<字节数>][cbs=<字节数>][conv=<关键字>][count=<区块数>][ibs=<字节数>][if=<文件>][obs=<字节数>][of=<文件>][seek=<区块数>][skip=<区块数>][--help][--version]
补充说明:dd可从标准输入或文件读取数据,依指 定的格式来转换数据,再输出到文件,设备或标准输出。
参 数:
bs=<字节数> 将ibs( 输入)与obs(输出)设成指定的字节数。
cbs=<字节数> 转换时,每次只转换指定的字节数。
conv=<关键字> 指定文件转换的方式。
count=<区块数> 仅读取指定的区块数。
ibs=<字节数> 每次读取的字节数。
if=<文件> 从文件读取。
obs=<字节数> 每次输出的字节数。
of=<文件> 输出到文件。
seek=<区块数> 一开始输出时,跳过指定的区块数。
skip=<区块数> 一开始读取时,跳过指定的区块数。
--help 帮助。
--version 显示版本信息。