码迷,mamicode.com
首页 > 其他好文 > 详细

shell编程基础

时间:2014-09-30 23:59:21      阅读:259      评论:0      收藏:0      [点我收藏+]

标签:shell编程基础

1、人类如何与计算机"沟通"?

    翻译官:编译器、解释器;

    编程语言:机器语言、汇编语言、高级语言

    

    静态语言:编译型语言

            强类型语言:变量在使用之前,需要声明定义,甚至需要初始化

                        事先转换成可执行格式

                        C、C++、Java、C#

    动态语言:解释型语言

            弱类型语言:变量在使用之前,不需要声明定义

                        边解释、边执行

                        PHP、JSP、Perl、shell编程、Python


    面向过程:shell、C

    面向对象:C++、JAVA、Python、Perl


    变量:就是命名的内存空间;

    内存:就是编址的存储单元;




    为什么会有变量:想象一下,如果没有变量这个概念的话,让计算机做一个1到10000的加法,这需要10000个内存空间去存放,但如果引入了变量这个概念,则需要两个变量即可。


    变量类型的作用及功能:事先确定变量的存储格式及长度

        整型,8bit: 256

        0-255, 溢出



                        字符变量

                        数值变量:

                            整型

                            浮点型:11.23,1.123*10,0.1123*10^2

                        eg:字符型:2014/9/30 64bit

                            数值型:99999    24bit        

                            布尔型:真、假

                            

                            字符:10:16bit

                            数值:10: 1010, 8bit

           

shell编程:shell弱类型的编程语言

       

什么是强?什么是弱?

        强类型:变量在使用前,需要声明定义,甚至初始化

        弱类型:变量在使用时才声明,甚至不区分类型

    

变量赋值:VER_NAME=VALUE


bash变量:

        本地变量(局部变量)

        环境变量

        位置变量

        特殊变量


本地变量:

set VARNAME=VALUE: 作用域为整个bash进程;


局部变量:

local VARNAME=VALUE:作用域为当前代码段;


环境变量:

export VARNAME=VALUE;

VARNAME=VALUE

export VARNAME

        “导出”


位置变量:

$1,$2......


特殊变量:

$?(返回上一个命令的执行状态码),$*(参数列表),$@


程序的执行可以返回两类结果:

     1、程序的执行结果;

     2、程序的执行状态码:0-255

            0:正确执行

          1-255:错误代码


输出重定向:

>:覆盖输出重定向

>>:追加输出重定向

2>:错误覆盖输出重定向

2>>:错误追加重定向

&>:标准输出+错误输出重定向


撤销变量:

unset VERNAME


查看变量:(环境变量+本地变量)

set


查看环境变量:

printenv

env

export 


脚本:命令的堆砌,按实际需要,结合控制流程机制实现的源程序


shebang:魔数

#!/bin/bash

#注释,不执行


/dev/null:软件设备 ; 位桶(bit bucket) 数据黑洞


脚本在执行时,会启动一个子shell进程:

        在命令行运行的脚本,会继承当前shell环境变量

        系统自动运行的脚本(非命令行启动),则需要自我定义各个环境变量



        

练习:写一个脚本,完成以下任务

1、添加5个用户, user1,..., user5

2、每个用户的密码同用户名,而且要求,添加密码完成后不显示passwd命令的执行结果信息;

3、每个用户添加完成后,都要显示用户某某已经成功添加;

useradd user1

echo "user1" | passwd --stdin user1 &> /dev/null

echo "Add user1 successfully."

                             

条件判断:

如果用户不存在

添加用户,给密码并显示添加成功;

否则

显示如果已经没在,没有添加;


bash 中如何实现条件判断:

    条件测试的类型:

                整数测试

                文件测试

                字符测试


    条件测试的表达式:

                [ expression ]

                [[ expression ]]

                test expression


整数比较:

        -gt:大于

        -lt:小于

        -ge:大于等于

        -le:小于等于

        -eq:等于

        -ne:不等于


命令间的逻辑关系:

    &&:与,一假全假,当左边为假时,则不需要执行右边,整个逻辑表达式即为假

    ||:或,一真全真,当左边为真时,则不需要执行右边,整个逻辑表达式即为真


如果用户user6不存在,就添加用户user6

!id user6 && useradd user6

 id user6 || useradd user6


如果/etc/inittab文件的行数大于100,就显示好大的文件;

[ wc -l /etc/inittab | cut -d " " -f 1 -gt 100 ] && echo "Large file"


变量命名规则:

1、只能包含字母,数字,下划线,并且不能以数字开头。

2、不能与系统中已有的环境变量重名

3、最好能够做到见名知意


如果用户存在,就显示用户已存在;否则,就添加此用户;

id user && echo "user exists" || adduser user

!id user || echo "user exists" && adduser user


如果用户不存在,就添加;否则,显示其已经存在;

!id user && useradd user || echo "user exists"

 id user || useradd user && echo "user exists"


如果用户不存在,添加并且给密码;否则,显示其已经存在;

!id user && useradd user && echo "user" | passwd --stdin user || echo "user exists"


练习,写一个脚本,完成以下要求:

1、添加3个用户user1, user2, user3;但要先判断用户是否存在,不存在而后再添加;

2、添加完成后,显示一共添加了几个用户;当然,不能包括因为事先存在而没有添加的;

3、最后显示当前系统上共有多少个用户;

USERNUM1=`wc -l /etc/passwd | cut -d ‘ ‘ -f1`#用户为添加之前的事先存在的用户数

id user1 && echo "user1 exists" || adduser user1

id user2 && echo "user2 exists" || adduser user2

id user3 && echo "user3 exists" || adduser user3

USERNUM2=`wc -l /etc/passwd | cut -d ‘ ‘ -f1`

echo "USERADDNUM=$[ $USERNUM2-&USERNUM1 ]"

echo "USERNUM2"


练习,写一个脚本,完成以下要求:

给定一个用户:

1、如果其UID为0,就显示此为管理员;

2、否则,就显示其为普通用户;


如果 UID为0;那么

  显示为管理员

否则

  显示为普通用户

NAME=user16

USERID=`id -u $NAME`

if [ $USERID -eq 0 ]; then

  echo "Admin"

else

  echo "common user."

fi




NAME=user16

if [ `id -u $NAME` -eq 0 ]; then

  echo "Admin"

else

  echo "common user."

fi



if id $NAME; then

  


练习:写一个脚本

判断当前系统上是否有用户的默认shell为bash;

   如果有,就显示有多少个这类用户;否则,就显示没有这类用户;

grep "bash$" /etc/passwd &> /dev/null

RETVAL=$?

if [ $RETVAL -eq 0 ]; then

   

if grep "bash$" /etc/passwd &> /dev/null; then

提示:“引用”一个命令的执行结果,要使用命令引用;

        比如: RESAULTS=`wc -l /etc/passwd | cut -d: -f1`;

       使用一个命令的执行状态结果,要直接执行此命令,一定不能引用;

        比如: if id user1一句中的id命令就一定不能加引号;

 

      如果想把一个命令的执行结果赋值给某变量,要使用命令引用,比如USERID=`id -u user1`;

      如果想把一个命令的执行状态结果保存下来,并作为命令执行成功与否的判断条件,则需要先执行此命令,而后引用其状态结果,如

id -u user1

RETVAL=$?

此句绝对不可以写为RETVAL=`id -u user1`;

练习:写一个脚本

判断当前系统上是否有用户的默认shell为bash;

   如果有,就显示其中一个的用户名;否则,就显示没有这类用户;


练习:写一个脚本

给定一个文件,比如/etc/inittab

判断这个文件中是否有空白行;

如果有,则显示其空白行数;否则,显示没有空白行。

#!/bin/bash

A=`grep ‘^$‘ /etc/inittab | wc -l`

if [ $A -gt 0 ]; then

 echo "$A"

else

 echo "meiyoukongbaihang"

fi

        

 

#!/bin/bash

FILE=/etc/inittab

if [ ! -e $FILE ]; then

  echo "No $FILE."

  exit 8

fi


if grep "^$" $FILE &> /dev/null; then

  echo "Total blank lines: `grep "^$" $FILE | wc -l`."

else

  echo "No blank line."

fi


练习:写一个脚本

给定一个用户,判断其UID与GID是否一样

如果一样,就显示此用户为“good guy”;否则,就显示此用户为“bad guy”。

#!/bin/bash

USERNAME=user1

USERID=`id -u $USERNAME`

GROUPID=`id -g $USERNAME`

if [ $USERID -eq $GROUPID ]; then

  echo "Good guy."

else

  echo "Bad guy."

fi


进一步要求:不使用id命令获得其id号;


#!/bin/bash

#

USERNAME=user1

if ! grep "^$USERNAME\>" /etc/passwd &> /dev/null; then

  echo "No such user: $USERNAME."

  exit 1

fi


USERID=`grep "^$USERNAME\>" /etc/passwd | cut -d: -f3`

GROUPID=`grep "^$USERNAME\>" /etc/passwd | cut -d: -f4`

if [ $USERID -eq $GROUPID ]; then

  echo "Good guy."

else

  echo "Bad guy."

fi




练习:写一个脚本

给定一个用户,获取其密码警告期限;

而后判断用户密码使用期限是否已经小于警告期限;

提示:计算方法,最长使用期限减去已经使用的天数即为剩余使用期限;

如果小于,则显示“Warning”;否则,就显示“OK”。


圆整:丢弃小数点后的所有内容


#!/bin/bash

W=`grep "student" /etc/shadow | cut -d: -f6`

S=`date +%s`

T=`expr $S/86400`

L=`grep "^student" /etc/shadow | cut -d: -f5`

N=`grep "^student" /etc/shadow | cut -d: -f3`

SY=$[$L-$[$T-$N]]


if [ $SY -lt $W ]; then

  echo ‘Warning‘

else

  echo ‘OK‘

fi




练习:写一个脚本

判定命令历史中历史命令的总条目是否大于1000;如果大于,则显示“Some command will gone.”;否则显示“OK”。



shell中如何进行算术运算:

A=3

B=6

1、let 算术运算表达式

let C=$A+$B

2、$[算术运算表达式]

C=$[$A+$B]

3、$((算术运算表达式))

C=$(($A+$B))

4、expr 算术运算表达式,表达式中各操作数及运算符之间要有空格,而且要使用命令引用

C=`expr $A + $B`



   

条件判断,控制结构:


单分支if语句

if 判断条件; then

  statement1

  statement2

  ...

fi


双分支的if语句:

if 判断条件; then

statement1

statement2

...

else

statement3

statement4

...

fi


多分支的if语句:

if 判断条件1; then

  statement1

  ...

elif 判断条件2; then

  statement2

  ...

elif 判断条件3; then

  statement3

  ...

else

  statement4

  ...

fi




测试方法:

[ expression ]

[[ expression ]]

test expression


bash中常用的条件测试有三种:

整数测试:

-gt

-le

-ne

-eq

-ge

-lt


INT1=63

INT2=77

[ $INT1 -eq $INI2 ]

[[ $INT1 -eq $INT2 ]]

test $INT1 -eq $INT2  

文件测试:

-e FILE:测试文件是否存在

-f FILE: 测试文件是否为普通文件

-d FILE: 测试指定路径是否为目录

-r FILE: 测试当前用户对指定文件是否有读取权限;

-w

-x


[ -e /etc/inittab ]

[ -x /etc/rc.d/rc.sysinit ]


练习:写一个脚本

给定一个文件:

如果是一个普通文件,就显示之;

如果是一个目录,亦显示之;

否则,此为无法识别之文件;




定义脚本退出状态码


exit: 退出脚本

exit #

如果脚本没有明确定义退出状态码,那么,最后执行的一条命令的退出码即为脚本的退出状态码;



测试脚本是否有语法错误:

bash -n 脚本


bash -x 脚本:单步执行




bash变量的类型:

本地变量(局部变量)

环境变量

位置变量: 

$1, $2, ...

shift

特殊变量:

$?

$#:参数的个数

$*: 参数列表

$@:参数列表

./filetest.sh /etc/fstab /etc/inittab

$1: /etc/fstab

$2: /etc/inittab


练习:写一脚本

能接受一个参数(文件路径)

判定:此参数如果是一个存在的文件,就显示“OK.”;否则就显示"No such file."


练习:写一个脚本

给脚本传递两个参数(整数);

显示此两者之和,之乘积;

#!/bin/bash

#

if [ $# -lt 2 ]; then

  echo "Usage: cacl.sh ARG1 ARG2"

  exit 8

fi


echo "The sum is: $[$1+$2]."

echo "The prod is: $[$1*$2]."


练习:写一个脚本,完成以下任务

1、使用一个变量保存一个用户名;

2、删除此变量中的用户,且一并删除其家目录;

3、显示“用户删除完成”类的信息;




bash: 


引用变量:${VARNAME}, 括号有时可省略。



shell编程基础

标签:shell编程基础

原文地址:http://xxaqwqm.blog.51cto.com/9368217/1560207

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!