shell编程的基本知知识<一>

这里有我在51cto的博客,写了一部分shell编程最基本的东西:
http://blog.51cto.com/13132323/2043713

shell脚本语言的种类

  • bourne shell(包括sh,ksh和bash)
  • C shell
  • 他是一个弱脚本语言,对语法要求不是很严格,本博客主要针对bash,因为是linux,默认bash

查看默认Linux的默认shell

  • 也就是直接取变量直接打印 echo $SHELL

linux 中shell的组成

  • 脚本开头:#!/bin/bash
    指出由那个解释器执行我们的脚本,#!又称为幻数,在执行bash脚本的时候,内核会根据它来确定用哪个程序来解释脚本中的任务,这一行必须在第一行,否则被视为注释。
  • 脚本动作
  • 脚本注释

执行脚本的基本区别

source或者’.’执行可以将脚本的的变量的值或者函数传入当前副脚本的shell中,而不像+x 权限和/bin/sh是创建一个子shell来执行脚本

shell的变量类型

  • 环境变量(全局变量)
    当前环境shell和任意子shell中都可以使用,就先当于在/etc/profile.d/下的目录放了相应的脚本,登录默认执行。
  • 局部变量
    只能在当前环境中使用
    这里说连个优化: TMOUT和HISTSIZ分别是待机时间,历史记录的数量

自定义环境变量(unset 是取消变量)

  • 使用export(-f,-n,-p参数)
    export 变量名=value
    变量名=value,export 变量名
  • 使用declare
    declare -x 变量名=value

单引号和双引号区别

单引号

强引用,所见即所得,单引号的内容在输出的时候,会按照原样输出

双引号

弱引用,在输出前,会将变量解析之后,在输出

[loveyu@feitian ~]$ a=172.25.254.7
[loveyu@feitian ~]$ echo $a
172.25.254.7
[loveyu@feitian ~]$ a=172.25.254.7-$a
[loveyu@feitian ~]$ echo $a
172.25.254.7-172.25.254.7
[loveyu@feitian ~]$ b='172.25.254.7-$a'
[loveyu@feitian ~]$ echo $b
172.25.254.7-$a
[loveyu@feitian ~]$ c="172.25.254.7-$a"
[loveyu@feitian ~]$ echo $c
172.25.254.7-172.25.254.7-172.25.254.7

把一个命令作为变量

  • 方式一
[loveyu@feitian ~]$ CMD=`ls`
[loveyu@feitian ~]$ echo $CMD
fenghui tools
  • 方式二
[loveyu@feitian ~]$ echo $(date +%F)
2017-11-21

sehll中特殊变量

位置变量

  • $0 获取当前执行的shell脚本的文件名,包括路径,也就是脚本的名称
    注意:在执行脚本前面加上dirname或者basename,就是只取出文件名称称和路径名称
  • $n 获取当前执行的shell脚本的第n个参数值,如果大于9,用大括号括起来{10}
  • $@ 这个程序的所有参数 “$1”,”$2”,”……”,这个是将所有参数传递给其他程序的最佳方式,因为他会保留所有内嵌在每个参数里的任何空白。
  • $# 获取当前shell命令中参数的总个数
  • $* 获取当前shell的所有参数,将所有的命令行参数视为单个字符串,相当于”$1$2”,注意和$#的区别
注意:在/etc/init.d/network 的最后有这样一行,也就是我们的$0
echo $"Usage: $0 {start|stop|status|restart|reload|force-reload}"
[loveyu@feitian /]$ /etc/init.d/network dfsf
Usage: /etc/init.d/network {start|stop|status|restart|reload|force-reload}
[loveyu@feitian /]$ dirname /etc/init.d/network 
/etc/init.d
[loveyu@feitian /]$ basename /etc/init.d/network 
network

$*和$@的区别

$* 是将所有的参数变成一个字符串,而$@是将每个参数视为一个字符串

[loveyu@feitian /]$ set  -- "I am " handsome feitian
[loveyu@feitian /]$ for i in $*;do echo $i;done
I
am
handsome
feitian
[loveyu@feitian /]$ for i in $@;do echo $i;done
I
am
handsome
feitian
[loveyu@feitian /]$ for i in "$*";do echo $i;done
I am handsome feitian
[loveyu@feitian /]$ for i in "$@";do echo $i;done
I am
handsome
feitian
#可以注意到,他俩不加引号,没有区别看,如果就是上面所说的作用

进程状态变量

  • $$ 获取当前shell的进程号
  • $!获取上一个命令的PID,上一个后台运行进程的进程号
  • $? 获取上一个命令的返回值(0为成功,非零为失败),返回值如下:
0   表示运行成功
2   表示权限被拒
126 表示找到该命令了,但是无法执行
127 表示未找到要运行的命令
128 表示命令被系统强制结束
  • $_在此之前执行的命令(上一个命令)或者脚本的最后一个参数

利用getopts处理命令行选项

[root@feitian day1]# cat getopt.sh 
#!/bin/sh
while getopts lrt options
do
        case $options in
                l) echo  "you entered  $options" ;;
                r) echo  "you entered  $options" ;;
                t) echo  "you enetered $options" ;;
        esac
done
[root@feitian day1]# sh getopt.sh  -lrt
you entered  l
you entered  r
you enetered t
#他就是将lrt赋值给options,然后用swtch case语句,如果有l,就将l打印出来,如果有r,就将r打印出来。还有要注意,如果在执行脚本时候不加-他就会接收不到,而且他只能接收lrt,也就是你脚本中定义的。

练习

  • 只允许管理员使用脚本清空日志
#!/bin/bash
if [ "$UID" -ne "0" ]
# -ne是不等于的意思
then
  echo "must be root run this scripts"
  exit
fi
cd $LOG_DIR|| {
  echo "cannot change to neccessary directory" >&2
  exit 1
}
#这里我们有两层筛选,如果他的UID不等于0或者进不了root的家目录,则直接退出
cat /dev/null >/var/log/messages && echo "Logs cleaned up"
  • 理解下面这个脚本语句
    runlevel=$(set – $(runlevel); eval “echo $$#” )
(set -- $(runlevel);
他的意思是将runlevel命令所执行的结果当成参数个数
eval "echo \$$#"
他的意思是执行后面的echo,将他当成命令执行,而$$#,则就等于runlevel命令执行结果的个数,也就是$2
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值