shell基本知识

shell基本知识

1.shell起源

  • 1964年,美国AT&T公司的贝尔实验室、麻省理工学院及美国通用电气公司共同参与开始研发一套可以安装在大型主机上的多用户、多任务的操作系统,该操作系统的名称为Multics。
  • 1970年,丹尼斯•里奇和汤普逊启动了另外一个新的多用户、多任务的操作系统的项目,他们把这个项目称之为UNICS。
  • 1973年,使用C语言重新编写了Unix。通过这次编写,使得Unix得以移植到其他的小型机上面。
  • 1979年,第一个重要的标准UNIX Shell在Unix的第7版中推出,并以作者史蒂夫•伯恩(StephenBourne)的名字命名,叫做Bourne Shell,简称为sh。
  • 20世纪70年代末,C Shell作为2BSD UNIX的一部分发布,简称csh。
  • 之后又出现了许多其他的Shell程序,主要包括Tenex C Shell(tcsh)、Korn Shell(ksh)以及GNU Bourne-Again shell(bash)。

2.shell功能
Shell又称命令解释器,它能识别用户输入的各种命令,并传递给操作系统。它的作用类似于Windows操作系统中的命令行,但是,Shell的功能远比命令行强大的多。在UNIX或者localhost中,Shell既是用户交互的界面,也是控制系统的脚本语言。

3.shell分类

  • Bourne Shell:标识为sh,该Shell由Steve Bourne在贝尔实验室时编写。在许多Unix系统中,该Shell是root用户的默认的Shell。
  • Bourne-Again Shell:标识为bash,该Shell由Brian Fox在1987年编写,是绝大多数localhost发行版的默认的Shell。
  • Korn Shell:标识为ksh,该Shell由贝尔实验室的David Korn在二十世纪八十年代早期编写。它完全向上兼容 Bourne Shell 并包含了C Shell 的很多特性。
  • C Shell:标识为csh,该Shell由Bill Joy在BSD系统上开发。由于其语法类似于C语言,因此称为C Shell。

如何查看当前系统支持的shell?

[root@centos-7 ~]# cat /etc/shells 
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash

如何查看当前系统默认shell?

[root@centos-7 ~]# echo $SHELL
/bin/bash

  1. 程序设计语言–shell
    Shell不仅仅是充当用户与UNIX或者localhost交互的角色,还可以作为一种程序设计语言来使用。
    通过Shell编程,可以实现许多非常实用的功能,提高系统管理的自动化水平。
    如果有一系列经常需要使用的命令,把它存储在一个文件里,shell可以读取这个文件并顺序执行其中的命令,我们把这样的文件就叫shell脚本。shell脚本按行解释文件里的命令。

编程变量名字规范:
驼峰式命名法:当变量名或函数名是由一个或多个单词连结在一起,而构成的唯一识别字时,第一个单词以小写字母开始;从第二个单词开始以后的每个单词的首字母都采用大写字母。例如:myFirstName、myLastName。
匈牙利命名法:
基本原则是:变量名=属性+类型+对象描述。
关键是:标识符的名字以一个或者多个小写字母开头作为前缀;前缀之后的是首字母大写的一个单词或多个单词组合,该单词要指明变量的用途。比如m_lpszStr, 表示指向一个以0字符结尾的字符串的长指针成员变量。

5.shell脚本的基本元素
一个基本shell程序 应该有以下基本元素:

  • 声明:声明用哪个命令解释器来解释并执行当前脚本文件中的语句,一般写的解释器为#!/bin/bash 。
  • 命令:可执行语句,实现程序的功能。
  • 注释:说明某些代码的功能,通过在代码中增加注释可以提高程序的可读性。
    (1)单行注释:#开头的一整行都是注释,例如:
#comment1 
#comment2 
#comment3
……

(2)多行注释,使用冒号“:”配合here document可实现多行注释,例如:

:<<BLOCK 
……注释内容 
BLOCK
  • 赋予rx的权限

6.shell脚本编写规范
(1)脚本文件名应见名知意,例如backup_mysql.sh
(2)文件开头指定脚本解释器 #!/bin/sh 或 #!/bin/bash
(3)开头加版本特权等信息

# Date:创建日期 
# Author:作者 
# Mail:联系方式 
# Function:功能 
# Version:版本

(4)脚本中尽量不要用中文注释
别吝啬添加注释,必要的注释方便自己别人理解脚本逻辑和功能;
尽量用英文注释,防止本机或切换系统环境后中文乱码的困扰;
单行注释,可以放在代码行的尾部或代码行的上部;
多行注释,用于注解复杂的功能说明,可以放在程序体中,也可以放在代码块的开始部分。
(5)多使用内部命令
常用的内部命令有:echo、eval、exec、export、read、shift、exit

  • echo 可在屏幕上输出信息
  • echo参数选项
    -n 不换行输出内容
    -e 解析转义字符
    \n 换行
    \r 回车
    \t 制表符
    \b 退格
    \v 纵向制表符
    举例:
[root@centos-7 ~]# echo -n i have a cat
i have a cat[root@centos-7 ~]# 
[root@centos-7 ~]# echo i\thave\ta\tcat
ithavetatcat
[root@centos-7 ~]# echo -e i\thave\ta\tcat
ithavetatcat
[root@centos-7 ~]# echo -e "i\thave\ta\tcat"
i	have	a	cat

  • eval
    命令格式:eval args
    功能:当shell程序执行到eval语句时,shell读入参数args,并将它们组合成一个新的命令,然后执行。
[root@centos-7 ~]# a='shuju;head -1 /etc/passwd'
[root@centos-7 ~]# echo $a
shuju;head -1 /etc/passwd
[root@centos-7 ~]# eval echo $a
shuju
root:x:0:0:root:/root:/bin/bash
  • exec命令能够在不创建新的子进程的前提下,转去执行指定的命令,当指定的命令执行完毕后,该进程就终止了。
  • export设置或者显示环境变量
  • read命令可从标准输入读取字符串等信息,传给shell程序内部定义的变量
    -p prompt:设置提示信息
    -t timeout:设置输入等待时间,单位默认为秒
[root@centos-7 ~]# read -t 10 -p "please input your name:" name
please input your name:xiaozhang
[root@centos-7 ~]# echo $name
xiaozhang
[root@centos-7 ~]# echo -n "please input your name:";read name1 name2
please input your name:xiaowang xiaoli
[root@centos-7 ~]# echo $name1
xiaowang
[root@centos-7 ~]# echo $name2
xiaoli

  • shift,在程序中每使用一次shift语句,都会使所有的位置参数依次向左移动一个位置,并使位置参数$#减1,直到减到0为止。
  • exit,退出shell程序。在exit之后可以有选择地指定一个数作为返回状态
    (6)没有必要使用cat命令
eg:cat /etc/passwd | grep guru 
使用以下方式即可 
eg:grep guru etc/passwd

(7)代码缩进

#!/bin/bash

i=1
while [ $i -le 10 ]
do
    if [$i -le 9 ]
    then
        username=user0$i
    else
        username=user$i
    fi
    ! id $username &>/dev/null && {
        useradd $username
        echo $username | passwd --stdin $username &>/dev/null
    }
    let i++
done

(8)如何快速生成脚本开头的版本版权注释信息

#vim ~/.vimrc
autocmd BufNewFile *.py,*.cc,*.sh,*.java exec ":call SetTitle()"

func SetTitle()
if expand("%:e") == 'sh'
   call setline(1,"#!/bin/bash")
   call setline(2,"#########################")
   call setline(3,"#File name:".expand("%"))
   call setline(4,"#Version:v1.0")
   call setline(5,"#Email:admin@test.com")
   call setline(6,"#Created time:".strftime("%F %T"))
   call setline(7,"#Description:")
   call setline(8,"#########################")
   call setline(9,"")
  endif
endfunc

7.shell脚本执行方式
(1)交互式执行

[root@centos-7 ~]# for filename in 'ls /etc'
> do
> if echo "$filename" | grep "passwd"
> then
> echo "filename"
> fi
> done

(2)作为程序文件执行(常用)
对于一组需要经常重复执行的Shell语句来说,将它们保存在一个文件中来执行。我们通常称这种包含多个Shell语句的文件为Shell脚本,或者Shell脚本文件。脚本文件是普通的文本文件,可使用任何的文本编辑器查看或修改Shell脚本。

[root@centos-7 ~]# cd /scripts/day1/
[root@centos-7 day1]# vim test1.sh
#!/bin/bash
#########################
#File name:test1.sh
#Version:v1.0
#Email:admin@test.com
#Created time:2021-08-13 08:00:25
#Description:
#########################
for filename in 'ls /etc'
do
    if echo "filename" | grep "passwd"
    then
      echo "filename"
    fi
done

8.脚本执行的方法
(1)bash ./filename.sh(产生子进程,再运行,使用当前指定的bash shell去运行)
(2)./filename.sh(产生子进程,再运行,使用脚本里面指定的shell去运行。使用该种方式执行需要x权限)
(3)source ./filename.sh(source命令是一个shell内部命令,其功能是读取指定的shell程序文件,并且依次执行其中的所有的语句,并没有创建新的子shell进程,所以脚本里面所有创建的变量都会保存到当前的shell里面)
(4). filename.sh(和source一样,也是使用当前进程执行)
例1:

[root@centos-7 day1]# vim test2.sh
#!/bin/bash
#########################
#File name:test2.sh
#Version:v1.0
#Email:admin@test.com
#Created time:2021-08-13 08:05:21
#Description:
#########################
cd /tmp
pwd
[root@centos-7 day1]# ll test2.sh 
-rw-r--r--. 1 root root 180 8月  13 08:05 test2.sh
[root@centos-7 day1]# bash test2.sh 
/tmp
[root@centos-7 day1]# ./test2.sh
-bash: ./test2.sh: 权限不够
[root@centos-7 day1]# chmod a+rx test2.sh 
[root@centos-7 day1]# ./test2.sh
/tmp
[root@centos-7 day1]# source  test2.sh 
/tmp
[root@centos-7 tmp]# cd /scripts/day1/
[root@centos-7 day1]# . test2.sh 
/tmp

执行shell脚本时,如果使用1和2这种方式执行会在当前的进程下产生一个新的bash子进程,所以子进程切换到了/tmp目录,当脚本结束,子进程也就结束了,所以当前进程的目录不会发生变化;3和4方式执行时,不会产生新的进程,所以脚本执行结束后当前的目录会变成/tmp。

例2:

[root@centos-7 day1]# echo 'userdir=`pwd`' > test3.sh
[root@centos-7 day1]# cat test3.sh 
userdir=`pwd`
[root@centos-7 day1]# bash test3.sh 
[root@centos-7 day1]# echo $userdir

[root@centos-7 day1]# chmod a+rx test3.sh 
[root@centos-7 day1]# ./test3.sh 
[root@centos-7 day1]# echo $userdir

[root@centos-7 day1]# source test3.sh 
[root@centos-7 day1]# echo $userdir
/scripts/day1
[root@centos-7 day1]# . test3.sh 
[root@centos-7 day1]# echo $userdir 
/scripts/day1

9.shell脚本的退出状态
在UNIX或者Linux中,每个命令都会返回一个退出状态码。退出状态码是一个整数,其有效范围为0~255。通常情况下,成功的命令返回0,而不成功的命令返回非0值。非0值通常都被解释成一个错误码。行为良好的UNIX命令,程序和工具都会返回0作为退出码来表示成功。

Shell脚本中的函数脚本本身也会返回退出状态码。在脚本或者是脚本函数中执行的最后的命令会决定退出状态码。另外,用户也可以在脚本中使用exit语句将指定的退出状态码传递给Shell。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值