shell 编程 /****** 不定期更新 **************

系统 1544 0

1、 shell 编程跳转目录使用 cd 时无效

例如 : 脚本 cd.sh

#!/bin/sh

cd /etc


解决办法和出错原因

这是因为你的脚本是由shell终端fork产生的子shell执行的,所以脚本执行完毕子shell也结束,因而返回父shell也就是当前的终端

可使用

# source cd.sh 或者

# . . /cd.sh 注意这里的格式为 #点/空格/点/cd.sh

也就是说我们所建立的 。sh 程序本身是Linux shell 创建的一个子进程。在使用cd 跳转时,实际是已经执行了跳转指令了,但在

这个 .sh 脚本结束的时候,父进程 终端shell 就拿到了主动权,它又将目录转回为原来的目录,执行下面的脚本,有助于你理解这个问题


#! /bin/sh

cd /etc

mypath='pwd'

echo "$mypath"


执行后,会打印信息可以帮你理解上面的问题。

2、 C 和 shell 混合编程

#i nclude<stdlib.h>
main()
{
system(“ls -al /etc/passwd /etc/shadow”);
}
执行结果:

-rw-r--r-- 1 root root 705 Sep 3 13 :52 /etc/passwd
-r--------- 1 root root 572k


3、shell 变量

详细出处参考: http://www.itwis.com/html/os/linux/20100202/7373.html

http://56214415.blog.51cto.com/745987/375832

linux中shell变量$#,$@,$0,$1,$2的含义解释:
变量说明:
$$
Shell本身的PID(ProcessID)
$!
Shell最后运行的后台Process的PID
$?
最后运行的命令的结束代码(返回值)
$-
使用Set命令设定的Flag一览
$*
所有参数列表。如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。
$@
所有参数列表。如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。

$#
添加到Shell的参数个数
$0
Shell本身的文件名
$1~$n
添加到Shell的各参数值。$1是第1参数、$2是第2参数…。
我们先写一个简单的脚本,执行以后再解释各个变量的意义
# touch variable
# vi variable
脚本内容如下:
#!/bin/sh
echo "number:$#"
echo "scname:$0"
echo "first :$1"
echo "second:$2"
echo "argume:$@"
保存退出
赋予脚本执行权限
# chmod +x variable
执行脚本
# ./variable aa bb
number:2
scname:./variable
first: aa
second:bb
argume:aa bb
通过显示结果可以看到:
$# 是传给脚本的参数个数
$0 是脚本本身的名字
$1是传递给该shell脚本的第一个参数
$2是传递给该shell脚本的第二个参数
$@ 是传给脚本的所有参数的列表

关于$@和$*是否作用相同的问题,我测试了下,应该是相同的

3、shell 函数内部变量 及 函数$1 $2 $*的使用

#!/bin/sh

TEST_ONE=first

TEST_TWO=second

test()

{

echo "$1"

echo "$2"

}

test $TEST_ONE $TEST_TWO


执行结果为
first

second

也就是说 在shell 函数后面跟的变量会依次被指定为$1 和 $2 后面如果还有变量就会依次$*



4、shell 一些基础编程 例如 判断数字变量的大小,自定义函数的使用 此知识点来源于网络

下面我们来看一个更复杂的例子,结合这个例子,我们来讲述Shell Script的语法。

1 #!/bin/bash
2 #wehavelessthan3arguments. Print thehelptext:
3 if [$#-lt3]; then
4 cat<<HELP
5 ren --renamesanumberof files usingsedregularexpressions
6
7 USAGE: ren 'regexp''replacement' files
8 EXAMPLE: rename all*.HTM files in*.html:
9 ren 'HTM$''html'*.HTM
10
11 HELP
12 exit 0
13 fi
14 OLD="$1"
15 NEW="$2"
16 #The shift command removesoneargumentfromthelistof
17 # command linearguments.
18 shift
19 shift
20 #$*containsnowallthe files :
21 for filein$*; do
22 if [-f"$file"]; then
23 newfile=` echo "$file"|sed"s/${OLD}/${NEW}/g"`
24 if [-f"$newfile"]; then
25 echo "ERROR:$newfileexistsalready"
26 else
27 echo "renaming$fileto$newfile "
28 mv"$file""$newfile"
29 fi
30 fi
31 done

我们从头来看,前面两行上一个例子中已经解释过了,从第三行开始,有新的内容。if语句和其他编程语言相似,都是流程控制语句。它的语法是:

if …; then

elif …; then

else

fi

与其他语言不同,Shell Script中if语句的条件部分要以分号来分隔。第三行中的[]表示条件测试,常用的条件测试有下面几种:

[ -f "$file" ] 判断$file是否是一个文件

[ $a -lt 3 ] 判断$a的值是否小于3,同样-gt和-le分别表示大于或小于等于

[ -x "$file" ] 判断$file是否存在且有可执行权限,同样-r测试文件可读性

[ -n "$a" ] 判断变量$a是否有值,测试空串用-z

[ "$a" = "$b" ] 判断$a和$b的取值是否相等

[ cond1 -a cond2 ] 判断cond1和cond2是否同时成立,-o表示cond1和cond2有一成立

要注意条件测试部分中的空格。在方括号的两侧都有空格,在-f、-lt、=等符号两侧同样也有空格。如果没有这些空格,Shell解释脚本的时候就会出错。

$#表示包括$0在内的命令行参数的个数。在Shell中,脚本名称本身是$0,剩下的依次是$0、$1、$2…、${10}、${11},等等。$*表示整个参数列表,不包括$0,也就是说不包括文件名的参数列表。

现在我们明白第三行的含义是如果脚本文件的参数少于三个,则执行if和fi语句之间 的内容。然后,从第四行到第十一行之间的内容在Shell Script编程中被称为Here文档,Here文档用于将多行文本传递给某一命令。Here文档的格式是以<<开始,后跟一个字符串,在 Here文档结束的时候,这个字符串同样也要出现,表示文档结束。在本例中,Here文档被输出给cat命令,也即将文档内容打印在屏幕上,起到显示帮助 信息的作用。

第十二行的exit是Linux的命令,表示退出当前进程。在Shell脚本中可以使用所有的Linux命令,利用上面的cat和exit,从一方面来说,熟练使用Linux命令也可以大大减少Shell脚本的长度。

十四、十五两句是赋值语句,分别将第一和第二参数赋值给变量OLD和NEW。紧接下来的两句是注释,注释下面的两条shift的作用是将参数列表中的第一个和第二个参数删除,后面的参数依次变为新的第一和第二参数,注意参数列表原本也不包括$0。

然后,自二十一行到三十一行是一个循环语句。Shell Script中的循环有下面几种格式:

while [ cond1 ] && { || } [ cond2 ] …; do

done

for var in …; do

done

for (( cond1; cond2; cond3 )) do

done

until [ cond1 ] && { || } [ cond2 ] …; do

done

在上面这些循环中,也可以使用类似C语言中的break和continue语句中断 当前的循环操作。第二十一行的循环是将参数列表中的参数一个一个地放入变量file中。然后进入循环,判断file是否为一个文件,如果是文件的话,则用 sed命令搜索和生成新的文件名。sed基本上可以看成一个查找替换程序,从标准输入,例如管道读入文本,并将结果输出到标准输出,sed使用正则表达式 进行搜索。在第二十三行中,backtick(`)的作用是取出两个backtick之间的命令输出结果,在这里,也就是将结果取出赋给变量 newfile。此后,判断newfile是否已经存在,否则就把file改成newfile。这样我们就明白这个脚本的作用了,Shell Script编写的其他脚本与此相似,只不过是语法和用法稍有不同而已。

通过这个例子我们明白了Shell Script的编写规则,但还有几件事情需要讲述一下。

第一个,除了if语句之外,Shell Script中也有类似C语言中多分支结构的case语句,它的语法是:

case var in

pattern 1 )

… ;;

pattern 2 )

… ;;

*)

… ;;

esac


我们再就下面一个例子,看看case语句的用法。

while getopts vc: OPTION

do

case $OPTION in

c) COPIES=$OPTARG

ehco "$COPIES";;

v) echo "suyang";;

\?) exit 1;;

esac

done

上面的getopts类似于C语言提供的函数getopts,在Shell Script中,getopts经常和while语句联合起来使用。getopts的语法如下:

getopts option_string variable

option_string中包含一串单字符选项,若getopts在命令行参数中 发现了连字符,那么它会将连字符之后的字符与option_string进行比较,若匹配成功,则把变量variable的值设为该选项,若无匹配,则把 变量的值设为?。有时候,选项还会带一个值,例如-c5等,这时要在option_string中该选项字母后面加上一个冒号,getopts发现冒号 后,会读取该值,然后将该值放入特殊变量OPTARG中。这个命令比较复杂,如有需要,读者可以详细参阅Shell编写的相关资料。

上面这个循环的作用就是依次取出脚本名称后面的选项,进行处理,如果输入了非法选项,则进入"?指定的部分,退出脚本程序。

第二个,Bash提供了一种用于交互式应用的扩展select,用户可以从一组不同的值中进行选择。其语法如下:

select var in …; do

break;

done

例如,下面这段程序的输出是:

#!/bin/bash

echo "Your choice?"

select var in "a" "b" "c"; do

break

done

echo $var

----------------------------

Your choice?

1) a

2) b

3) c

第三,Shell Script中也可以使用自定义的函数,其语法形式如下:

functionname()

{

}

例如我们可以把上面第二个例子中第四到第十二行放入一个名为help函数体内,以后每次调用的时候直接写help即可。函数中处理函数调用参数的方法是,直接用上面讲过的$1、$2来分别表示第一、第二个参数,用$*表示参数列表。

第四,我们也可以在Shell下调试Shell Script脚本,当然最简单的方法就是用echo输出查看变量取值了。Bash也提供了真正的调试方法,就是执行脚本的时候用-x参数。

sh ?x filename.sh

这会执行脚本并显示脚本中所有变量的取值,也可以使用参数-n,它并不执行脚本,只是返回所有的语法错误。

5、shell 读一个文件 将每一行转换成为变量

sys_info=$(cat /usr/local/sysconfig.txt)
var=`echo $sys_info | awk -F ', ' '{print $0} ' | sed "s/,/ /g "`

ip=$(echo $var | awk '{print $1}')
netmask=$(echo $var | awk '{print $2}')
gateway=$(echo $var | awk '{print $3}')
db_ip=$(echo $var | awk '{print $4}')
record_ip=$(echo $var | awk '{print $5}')

或者使用

IP=$(sed -n '1p' /opt/config)

echo "$IP"

DIR=$(sed -n '2p' /opt/config)
echo "$UPDATEDIR"
FILE=$(sed -n '3p' /opt/config)
echo "$FILE"

6、shell 检测终端输入 将输入内容转化成为变量

while read var1 var2 var3; do
echo var1=${var1} var2=${var2}
done

7、找到动态 驱动设备节点

找到动态 驱动设备节点


awk "\$2==\"PWM\" {print \$1}" /proc/devices





shell 编程 /****** 不定期更新 **************/


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论