一、shell的介绍
Shell的作用是解释执行用户的命令,用户输入一条命令,Shell就解释执行一条,这种方式称为交互式(Interactive),Shell还有一种执行命令的方式称为批处理(Batch)
,用户事先写一个Shell脚本(Script),其中有很多条命令,让Shell一次把这些命令执行完,而不必一条一条地敲命令。Shell脚本和编程语言很相似,也有变量和流程控制语句,但Shell脚本是解释执行的,不需要编译,Shell程序从脚本中一行一行读取并执行这些命令,相当于一个用户把脚本中的命令一行一行敲到Shell提示符下执行。
由于历史原因,UNIX系统上有很多种Shell:
sh(Bourne Shell)
:由Steve Bourne开发,各种UNIX系统都配有sh。csh(C Shell)
:由Bill Joy开发,随BSD UNIX发布,它的流程控制语句很像C语言,支持很多Bourne Shell所不支持的功能:作业控制,命令历史,命令行编辑。ksh(Korn Shell)
:由David Korn开发,向后兼容sh的功能,并且添加了csh引入的新功能,是目前很多UNIX系统标准配置的Shell,在这些系统上/bin/sh往往是指向/bin/ksh的符号链接。tcsh(TENEX C Shell)
:是csh的增强版本,引入了命令补全等功能,在FreeBSD、MacOS X等系统上替代了csh。bash(Bourne Again Shell)
:由GNU开发的Shell,主要目标是与POSIX标准保持一致,同时兼顾对sh的兼容,bash从csh和ksh借鉴了很多功能,是各种Linux发行版标准配置的Shell,在Linux系统上/bin/sh往往是指向/bin/bash的符号链接。虽然如此,bash和sh还是有很多不同的,一方面,bash扩展了一些命令和参数,另一方面,bash并不完全和sh兼容,有些行为并不一致,所以bash需要模拟sh的行为:当我们通过sh这个程序名启动bash时,bash可以假装自己是sh,不认扩展的命令,并且行为与sh保持一致。
查看用户对应的Shell 类型:
-
man /etc/passwd
命令
最后一列显示了用户对应的shell类型 -
查看环境变量
echo $SHELL
内建命令:
用户在命令行输入命令后,一般情况下Shell会fork并exec该命令,但是Shell的内建命令
例外,执行内建命令相当于调用Shell进程中的一个函数,并不创建新的进程。以前学过的cd、alias、umask、exit
等命令即是内建命令。
查看命令是否为内置命令:type 命令
二、执行脚本
编写一个简单的脚本test.sh
:
#!/bin/sh
echo HelloWorld
cd ..
ls
- 直接
./
执行
Shell脚本中用#
表示注释,相当于C语言的//
注释。但如果#位于第一行开头,并且是#!(称为Shebang)则例外,它表示该脚本使用后面指定的解释器/bin/sh解释执行。把这个脚本文件加上可执行权限然后执行: /bin/sh
test.sh执行
这种方式不需要脚本有可执行权限,仅需要脚本有可读权限即可。在一些没办法调整脚本权限的情况下可以使用这种方式,但是这种方式需要关注当前脚本使用什么解释器。- 命令行下输入的命令用
()
括起来 source
脚本地址
这种方式执行脚本不会产生子进程,而是将脚本命令都加载进来执行。常用于加载配置文件例如:source /etc /profile
Shell执行的过程:Shell会fork一个子进程并调用exec执行./test.sh
这个程序,exec系统调用把子进程的代码段替换成./test.sh程序的代码段,并从它的_start开始执行。
三、shell的基本语法
1. 变量的使用
Shell变量通常由字母加下划线开头,由任意长度的字母、数字、下划线组成
变量的定义:声明即赋值
varname=value
,注意等号两边不能留空格,留了空格就变成了一个命令+两个参数
变量的使用: 用$
符号跟上变量名表示对某个变量取值,变量名可以加上{}
来表示变量名的范围:
2. 变量的分类
shell内变量: 在shell解析环境中存在的变量。
全局变量
: shell中不使用任何修饰符修饰的变量都是全局变量。不管是在函数内部还是函数外都一样,从声明语句开始一直到脚本结束都是其生命周期环境变量
:操作系统自带的,每一个进程都会有。当创建一个子进程时,子进程会继承父进程的环境变量。
#!/bin/sh
globalVar1="hello" // 全局变量
function test()
{
globalVar2="world" // 全局变量
local localVar="itcast" // 局部变量
}
#调用函数
test
echo $globalVar1 $globalVar2
shell中的变量只能在当前shell进程中使用,跨进程是无法传递的。除非使用source
,将另一个进程中的程序加载到当前进程中。
subScript.sh
#!/bin/sh
echo "this is in subScript"
echo $globalVar1
echo "subScript end"
在test.sh中执行subScript:
环境变量
是单向传递的,只能从父进程传递给子进程而不能由子进程传给父进程。
定义一个环境变量:export varname=value
或者 varname=value; export varname
删除变量
无论是普通变量还是环境变量都可以使用unset
命令删除。