目录
编辑
什么是shell
编译型语言和解释型语言
解释型语言
变量
1.局部变量:
2.环境变量通常又称“全局变量”
3.设置环境变量:
命名法则举例
变量命名
取消变量
特殊变量
1、只读变量(常量):
查看常量值
括号的使用
位置变量
$* 和 $@ 的区别。
$0 引用名称的使用
shift命令: 整体往左移位
退出状态
shell 是一个命令解释器,提供用户和机器之间的交互支持特定语法,比如逻辑判断、循环每个用户都可以有自己特定的 shell还有其他 zsh 、 ksh 等CentOS7 默认的 shell 为 bash(Bourne Agin Shell)Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。 Shell 既是一种命令语言,又是一种程序设计语言。Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。shell 是一种解释型语言,这种语言经过编写后不经过任何编译就可以执行,是一种脚本语言。和编译型语言是执行前翻译不同,解释型语言的程序是执行时翻译,所以效率要差一些
编译器一般会有预编译的过程对代码进行优化。因为编译只做一次,运行时不需要编译,所以编译型语言的程序执行效率高。可以脱离语言环境独立运行。
编译之后如果需要修改就需要整个模块重新编译。编译的时候根据对应的运行环境生成机器码,不同的操作系统之间移植就会有问题,需要根据运行的操作系统环境编译不同的可执行文件。
代表语言:
C、C++、Pascal、Object-C、swift等。
[root@localhost ~]# cat /etc/shells
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
/bin/tcsh
/bin/csh
[root@localhost ~]#
解释性语言的程序不需要编译,相比编译型语言省了道工序,解释性语言在运行程序的时候才逐行翻译。每一个语句都是执行的时候才能翻译。这样解释性语言每执行一次要翻译一次,效率表较低
有良好的平台兼容性,在任何环境中都可以运行,前提是安装了解释器(虚拟机)。灵活,修改代码的时候直接修改就可以,可以快速部署,不用停机维护
缺点:
每次运行的时候都要解释一遍,性能上不如编译型语言
代表语言:
JavaScript、Python、Erlang、PHP、Perl、Ruby
bash shell 有两种工作模式:互动模式和脚本模式。脚本模式效率更高,可以实现自动化[root@localhost shell]# cat kang.sh #!/bin/bash //是一个标记,告诉系统执行这个文件需要的解释器 #this line is a comment // “#”号开头的行代表注释 echo "Hello world"
1.运行脚本有两种方法
使用bash命令执行
[root@localhost shell]# bash kang.sh
Hello world
// “.”命令也都可以执行脚本,且不需要可执行权限
[root@localhost shell]# . kang.sh
Hello world
2. 、给脚本添加可执行权限,然后直接就可以执行了
[root@localhost shell]# chmod +x kang.sh
[root@localhost shell]# ./kang.sh
Hello world
PS: 脚本是各种命令的集合,终究还是要执行服务的
查看命令储蓄路径
[root@localhost bin]# echo $PATH
/usr/lib64/qt-3.3/bin:/root/perl5/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@localhost bin]# cat test.sh
#!/bin/bash
ls /etc/passwd
mkdir /data
cp /etc/passwd /data/
[root@localhost bin]# chmod +x test.sh
[root@localhost bin]# test.sh
/etc/passwd
[root@localhost bin]#
是指在某个 shell 中生效的变量,对其他 shell 来说无效,局部变量的作用域被限定在声明它们的shell 中,可以使用 local 内建命令来 “ 显式” 的声明局部变量,但仅限于函数内使用
以区别于局部变量。在 shell 脚本中,变量默认就是全局的,为了让子shell 继承当前 shell 的变量,可以使用 export命令将其定义为环境变量
$PATH UID HOSTNAME PWD (存在内存中的)
[root@localhost shell]# declare -x class="Linux base"
[root@localhost shell]# echo $class
Linux base
[root@localhost shell]# export class1="Linux"
[root@localhost shell]# echo $class1
Linux
[root@localhost shell]# name="bj"
[root@localhost shell]# echo $name
bj
总结
总结: declare -x 和 export 这种设置变量的方式,是全局的环境变量,(全局环境变量的特点: 子进程会继承父进程的环境变量),第三种" 变量名= 变量值 " 的这种方式,默认只在当前进程有效,如果想要子进程也有效,可以使用前两种暴露的方式,或者,将变量到/etc/profile 文件中,
[root@localhost shell]# name=`cat /etc/fstab`
[root@localhost shell]# echo $name
# # /etc/fstab # Created by anaconda on Wed Nov 2 23:38:14 2022 # # Accessible filesystems, by reference, are maintained under '/dev/disk' # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info # /dev/mapper/centos-root / xfs defaults 0 0 UUID=1d919f48-cb52-43a9-bacb-9ea0e03a51b7 /boot xfs defaults 0 0 /dev/mapper/centos-swap swap swap defaults 0 0
[root@localhost shell]# echo "$name"
#
# /etc/fstab
# Created by anaconda on Wed Nov 2 23:38:14 2022
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/centos-root / xfs defaults 0 0
UUID=1d919f48-cb52-43a9-bacb-9ea0e03a51b7 /boot xfs defaults 0 0
/dev/mapper/centos-swap swap swap defaults 0 0
[root@localhost shell]#
[root@localhost shell]# name=bj
[root@localhost shell]# name2=zs
[root@localhost shell]# name3=$name
[root@localhost shell]# echo $name3
bj
[root@localhost shell]# name1=base
[root@localhost shell]# echo $name3
bj
[root@localhost shell]#
studentname====>大驼峰 S tudent N ame, 小驼峰: student N ame (单驼峰 双驼峰 三驼峰)
[root@localhost shell]# name=lisi
[root@localhost shell]# name= lisi
bash: lisi: 未找到命令...
[root@localhost shell]#
[root@localhost shell]# name=li lei
bash: lei: 未找到命令...
[root@localhost shell]#
[root@localhost shell]# echo $name
lisi
[root@localhost shell]# echo ${name}
lisi
[root@localhost shell]#
[root@localhost shell]# unset name
[root@localhost shell]# echo ${name}
上边我们接触到局部变量和环境(全局)变量,也知道了他们特点:局部变量只在当前shell 有效,环境变量的有效范围为当前 shell 和子 shell 。除了这些还有其他一些变量,也需要我们注意
[root@localhost shell]# readonly name1="wukong"
[root@localhost shell]# echo $name1
wukong
[root@localhost shell]# name1=bajie
-bash: name1: 只读变量
[root@localhost shell]#
[root@localhost shell]# declare -r name2="bajie"
[root@localhost shell]# echo $name2
bajie
[root@localhost shell]#
[root@localhost shell]# readonly -p
declare -r BASHOPTS="checkwinsize:cmdhist:expand_aliases:extglob:extquote:force_fignore:histappend:interactive_comments:login_shell:progcomp:promptvars:sourcepath"
declare -ir BASHPID
declare -r BASH_COMPLETION_COMPAT_DIR="/etc/bash_completion.d"
declare -ar BASH_REMATCH='()'
declare -ar BASH_VERSINFO='([0]="4" [1]="2" [2]="46" [3]="2" [4]="release" [5]="x86_64-redhat-linux-gnu")'
declare -ir EUID="0"
declare -ir PPID="4989"
declare -r SHELLOPTS="braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor"
declare -ir UID="0"
declare -r name1="wukong"
declare -r name2="bajie
小括号用法:一次性使用。不会对环境产生影响
[root@localhost shell]# (name=yjs;echo $name)
yjs
[root@localhost shell]# echo $name
[root@localhost shell]#
[root@localhost shell]# { name=adam; echo $name; }
adam
[root@localhost shell]# echo $name
adam
[root@localhost shell]#
$0 :代表脚本本身名字$1----$9 :第一个位置参数 ------- 第 9 个位置参数$# :脚本参数的个数总和$@ :表示脚本的所有参数$* : 表示脚本的所有参数
[root@localhost shell]# cat example.sh
#!/bin/bash
echo "这个脚本的名字是:$0"
echo "参数一共有:$#个"
echo "参数的列表是: $@"
echo "参数的列表是: $*"
echo "第一个参数是: $1"
echo "第二个参数是: $2"
echo "第三个参数是:$3"
[root@localhost shell]#
[root@localhost shell]# bash example.sh 1 2 3 4 5
这个脚本的名字是:example.sh
参数一共有:5个
参数的列表是: 1 2 3 4 5
参数的列表是: 1 2 3 4 5
第一个参数是: 1
第二个参数是: 2
第三个参数是:3
[root@localhost shell]# echo {1..15}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
[root@localhost shell]# echo {a..z}
a b c d e f g h i j k l m n o p q r s t u v w x y z
[root@localhost shell]#
[root@localhost shell]# cat example.sh
#!/bin/bash
echo "这个脚本的名字是:$0"
echo "参数一共有:$#个"
echo "参数的列表是: $@"
echo "参数的列表是: $*"
echo "第一个参数是: $1"
echo "第二个参数是: $2"
echo "第三个参数是:$3"
echo "第12个参数是:${12}"
[root@localhost shell]#
[root@localhost shell]# bash example.sh {1..15}
这个脚本的名字是:example.sh
参数一共有:15个
参数的列表是: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
参数的列表是: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
第一个参数是: 1
第二个参数是: 2
第三个参数是:3
第12个参数是:12
[root@localhost shell]#
[root@localhost shell]# cat /etc/redhat-release > mylrelease.txt
[root@localhost shell]# cat mylrelease.txt
CentOS Linux release 7.9.2009 (Core)
[root@localhost shell]#
$* 和 $@ 都代表了脚本的所有参数,但是, $* 它会把显示的结果当做一个整体显示,而$@ 会把收集到的结果分开来显示。不过要注意,如果$*和 $@ 有双引号的前提下,显示效果会做区分,如果都没有双引号,效果一样。
[root@localhost shell]# cat t1.sh
#!/bin/bash
echo "t1脚本所有参数是:$*"
bash t2.sh "$*"
[root@localhost shell]# cat t2.sh
#!/bin/bash
echo "t2脚本的第一个参数:$1"
[root@localhost shell]# bash t1.sh 1 2 3
t1脚本所有参数是:1 2 3
t2脚本的第一个参数:1 2 3
[root@localhost shell]#
[root@localhost shell]# sed -i '3s/\$\*/\$\@/' t1.sh
[root@localhost shell]# bash t1.sh 1 2 3
t1脚本所有参数是:1 2 3
t2脚本的第一个参数:1
[root@localhost shell]#
[root@localhost shell]# ln -s example.sh link.sh
[root@localhost shell]# bash link.sh
这个脚本的名字是:link.sh
参数一共有:0个
参数的列表是:
参数的列表是:
第一个参数是:
第二个参数是:
第三个参数是:
第12个参数是:
[root@localhost shell]#
[root@localhost shell]# cat example.sh
#!/bin/bash
echo "这个脚本的名字是:$0"
echo "参数一共有:$#个"
echo "参数的列表是: $@"
echo "参数的列表是: $*"
echo "第一个参数是: $1"
echo "第二个参数是: $2"
echo "第三个参数是:$3"
echo "第12个参数是:${12}"
shift
echo "这个脚本的名字是:$0"
echo "参数一共有:$#个"
echo "参数的列表是: $@"
echo "参数的列表是: $*"
echo "第一个参数是: $1"
echo "第二个参数是: $2"
echo "第三个参数是:$3"
echo "第12个参数是:${12}"
shift
echo "这个脚本的名字是:$0"
echo "参数一共有:$#个"
echo "参数的列表是: $@"
echo "参数的列表是: $*"
echo "第一个参数是: $1"
echo "第二个参数是: $2"
echo "第三个参数是:$3"
echo "第12个参数是:${12}"
[root@localhost shell]#
PS : 当然这是默认的移动一位,当然也可以通过设置决定移动多少位,在shift 后边直接加上想要移动的位数即可。
[root@localhost shell]# ls /tmp/
systemd-private-5d5242bfa7a445ff929e39dfdd38104b-bolt.service-eJViXd
systemd-private-5d5242bfa7a445ff929e39dfdd38104b-chronyd.service-AhBuTC
systemd-private-5d5242bfa7a445ff929e39dfdd38104b-colord.service-IMbJvs
systemd-private-5d5242bfa7a445ff929e39dfdd38104b-cups.service-N5SsIj
systemd-private-5d5242bfa7a445ff929e39dfdd38104b-rtkit-daemon.service-63nbw5
systemd-private-e403b5d9448d4c048c3a7f654f134ba8-bolt.service-MNeFrF
systemd-private-e403b5d9448d4c048c3a7f654f134ba8-chronyd.service-A8qNGd
systemd-private-e403b5d9448d4c048c3a7f654f134ba8-colord.service-WUjrtE
systemd-private-e403b5d9448d4c048c3a7f654f134ba8-cups.service-eCfKFF
systemd-private-e403b5d9448d4c048c3a7f654f134ba8-rtkit-daemon.service-IQMGcU
yum_save_tx.2023-07-06.15-27.Jcn602.yumtx
[root@localhost shell]# echo $?
0
[root@localhost shell]# ls /apc
ls: 无法访问/apc: 没有那个文件或目录
[root@localhost shell]# echo $?
2
[root@localhost shell]# id test &> /dev/null
[root@localhost shell]# echo $?
1
[root@localhost shell]#
当然判断命令是否执行成功,不仅仅是简单的判断$? 还有更严谨的判断语句,这个我们以后会讲,现在先知道就可以了。那么在这里还需要知道一点。我们的脚本里边,往往是大于一条命令的,这个$? 返回的 0 值,如果返回的是0, 那么这个 0值到底是返回的哪一条命令的值那?
[root@localhost shell]# cat test1.sh
#!/bin/bash
hostname
[root@localhost shell]# bash test1.sh
localhost.localdomain
[root@localhost shell]# echo $?
0
[root@localhost shell]#
[root@localhost shell]# cat test1.sh
#!/bin/bash
hostnam
[root@localhost shell]# bash test1.sh
test1.sh:行2: hostnam: 未找到命令
[root@localhost shell]# echo $?
127
[root@localhost shell]# cat test1.sh
#!/bin/bash
hostnam
ls
[root@localhost shell]# bash test1.sh
test1.sh:行2: hostnam: 未找到命令
example.sh kang.sh link.sh mylrelease.txt t1.sh t2.sh test1.sh
[root@localhost shell]# echo $?
0
[root@localhost shell]#
[root@localhost shell]# cat test1.sh
#!/bin/bash
if
ls
[root@localhost shell]# bash test1.sh
test1.sh:行4: 语法错误: 未预期的文件结尾
[root@localhost shell]# echo $?
2
[root@localhost shell]#
[root@localhost shell]# cat test1.sh
#!/bin/bash
ls
[root@localhost shell]# bash test1.sh
example.sh kang.sh link.sh mylrelease.txt t1.sh t2.sh test1.sh
[root@localhost shell]# echo $?
0
[root@localhost shell]#
[root@localhost shell]# cat test1.sh
#!/bin/bash
ls
exit 10
[root@localhost shell]# bash test1.sh
example.sh kang.sh link.sh mylrelease.txt t1.sh t2.sh test1.sh
[root@localhost shell]# echo $?
10
[root@localhost shell]#
PS : 那么我们就要考虑,根据不同的返回码,我们是不是就可判断出系统的运行状态啊? 假设说,我们规定了计算机会有几种情况,如果说一种情况返回10 ,另一种情况返回 20 ,还有 30 ,那么我们就可根据系统返回的值的不同,来判断出,系统肯定是满足了某种条件。这样就可以作为定位判断系统状态的依据,其实在我们上网的时候有返回发 404 ,其实也是类似这种方法的。200 OK 404 Not Found3xx重定向 4xx 客户端错误 5xx 服务器错误当然exit 命令在外部也可以使用,意思是退出 bash