目录

  • 一、Shell概念
    • 1.定义
    • 2.分类和使用场景
      • 2.1.分类和切换
      • 2.2.使用场景
    • 3.特性
      • 3.1.文件描述符与输出重定向
      • 3.2.历史命令—history
      • 3.3.别名 –alias
      • 3.4.命令排序执行
      • 3.5.部分快捷键
      • 3.6.通配符置换
    • 4.脚本规范
    • 5.脚本运行方式
      • 5.1.bash脚本执行
      • 5.2.bash脚本测试
  • 二、bash配置文件
    • 1.全局配置文件
    • 2.个人配置文件

一、Shell概念

1.定义

  • 程序 语言 编程
  • 语言:自然语言(汉语 英语)、计算机语言(c语言、c++、java、php、python、go、shell)
  • 编译型语言:c、c++、java
  • 解释型语言:php、python、bash(shell)

编译型语言:编译型语言的首先将源代码编译生成机器语言,再由机器运行机器码(二进制)。像C/C++等都是编译型语言。
解释型语言:源代码不是直接翻译成机器语言,而是先翻译成中间代码,再由解释器对中间代码进行解释运行。比如Python/JavaScript/Shell等都是解释型语言

c 编译型执行代码需要编译成cpu能认识的二进制码 x86指令集
java 编译型执行编译–>字节码,cpu不能直接运行,只能被Java虚拟机执行
shell 解释型语言执行 慢

编译型语言的执行方式

解释型语言的执行方式

Shell定义

Shell 也是一种程序设计语言,它有变量,关键字,各种控制语句,有自己的语法结构,利用shell程序设计语言可以编写功能很强、代码简短的程序。
shell是外壳的意思,就是系统的外壳,我们可以通过shell的命令来控制和操作操作系统,比如linux中的shell命令就包括ls、cd、pwd等等,总结来说shell就是一个命令解释器,他通过接收用户输入的shell命令来启动、停止程序的运行或者对计算机进行控制。

2.分类和使用场景

2.1.分类和切换

[root@localhost ~]# cat /etc/shells//查看所有shell/bin/sh/bin/bash//默认的shell/usr/bin/sh//centos中脚本使用的默认shell/usr/bin/bash[root@localhost ~]# echo $SHELL//查看当前正在使用的shell/bin/bash[root@localhost ~]# vim /etc/passwd//编辑登录shell

2.2.使用场景

Shell 能做什么” />3.特性

3.1.文件描述符与输出重定向

在 shell程序中,最常使用的FD (file descriptor) 大概有三个,分别是:
0: Standard Input (STDIN)
1: Standard Output (STDOUT)
2: Standard Error Output (STDERR)
在标准情况下, 这些FD分别跟如下设备关联:
stdin(0): keyboard 键盘输入,并返回在前端
stdout(1): monitor 正确返回值 输出到前端
stderr(2): monitor 错误返回值 输出到前端

将程序的标准输出(stdout)和标准错误(stderr)一起重定向到一个文件(该用法最常用):&> a.txt
将标准输出(stdout)重定向到标准错误(stderr),用的较少(了解即可):1 >&2
将标准错误(stderr)重定向到标准输出(stdout),用的较少(了解即可):2 >&1
一般来说, “1>” 通常可以省略成 “>”

1.例子,当前目录下只有a.txt,没有b.txt[root@localhost ~]# touch a.txt[root@localhost ~]# ls a.txt b.txt>file.out2>&1[root@localhost ~]# cat file.out ls: cannot access b.txt: No such file or directorya.txt2.或者也可以:[root@localhost ~]# ls a.txt b.txt &>cat.txt[root@localhost ~]# cat cat.txtls: 无法访问b.tx: 没有那个文件或目录a.txt 3.通过cat的方式将内容写入到文件中[root@localhost ~]# cat >> b.txt <<eof> ni hao a haha> eof[root@localhost ~]# cat b.txt ni hao a haha//注:这里也可以使用EOF需要成对使用即可!

3.2.历史命令—history

上下健
! 关键字
! 历史命令行号
!! 执行上一条命令
!$ 上一条命令的最后一个参数
esc . 上一条命令的最后一个参数
Ctrl+r 在历史命令中查找,输入关键字调出之前的命令

3.3.别名 –alias

[root@localhost ~]# alias//查看别名alias cp='cp -i'alias egrep='egrep --color=auto'alias fgrep='fgrep --color=auto'alias grep='grep --color=auto'alias l.='ls -d .* --color=auto'alias ll='ls -l --color=auto'alias ls='ls --color=auto'alias mv='mv -i'alias rm='rm -i'alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'设置别名 1.临时设置[root@localhost ~]# aa=88[root@localhost ~]# echo $aa882.永久设置[root@localhost ~]# vim /root/.bashrcaa=88[root@localhost ~]# source /root/.bashrc//让文件生效

3.4.命令排序执行

&& 逻辑与,前面执行成功,后面才执行。前面命令执行失败,后面命令也不执行
|| 逻辑或,前面执行失败,后面执行,前面命令执行成功,后面不执行。
; 从左往右按顺序执行,不管前面执行成功与否,后面都执行

3.5.部分快捷键

Ctrl+a 切换到命令行开始(跟home一样,但是home在某些unix环境下无法使用)
Ctrl+u 清除剪切光标之前的内容
Ctrl+k 清除剪切光标之后的内容
ctrl+y 粘贴刚才所删除的字符
Ctrl+r 在历史命令中查找,输入关键字调出之前的命令
Ctrl+l 清屏
Ctrl+c 终止
Ctrl+e 切换到命令行末尾

3.6.通配符置换

在 Shell命令中,通常会使用通配符表达式来匹配一些文件
*?[]{}

字符含义实例
*匹配 0 或多个字符a*b a与b之间可以有任意长度的任意字符,也可以一个也没有, 如aabcb, axyzb, a012b, ab
?匹配任意一个字符a?b a与b之间必须也只能有一个字符,可以是任意字符, 如aab, abb, acb, a0b
[list]匹配 list 中的任意单一字符a[xyz]b a与b之间必须也只能有一个字符,但只能是 x 或 y 或 z, 如: axb, ayb, azb
[!list]匹配 除list 中的任意单一字符a[!0-9]b a与b之间必须也只能有一个字符,但不能是阿拉伯数字, 如axb, aab, a-b
[c1-c2]匹配 c1-c2 中的任意单一字符[0-9] [a-z] a[0-9]b 0与9之间必须也只能有一个字符 如a0b, a1b… a9b
{string1,string2,…}匹配 sring1 或 string2 (或更多)其一字符串a{abc,xyz,123}b a与b之间,只能是abc或xyz或123这三个字符串之一
[root@localhost tmp]# rm -rf *[root@localhost tmp]# touch aabcb axyzb a012b ab acb[root@localhost tmp]# lsa012baabcbabacbaxyzb[root@localhost tmp]# ls a*ba012baabcbabacbaxyzb[root@localhost tmp]# ls a?bacb[root@localhost tmp]# rm -rf *[root@localhost tmp]# touch axb ayb azb axyb[root@localhost tmp]# lsaxbaxybaybazb[root@localhost tmp]# ls a[xy]baxbayb[root@localhost tmp]# ls a[!xy]bazb[root@localhost tmp]# ls a[!x]baybazb[root@localhost tmp]# rm -rf *[root@localhost tmp]# touch a0b a1b a9b[root@localhost tmp]# ls a[0-9]ba0ba1ba9b[root@localhost tmp]# rm -rf *[root@localhost tmp]# touch aabcb axyzb a012b ab[root@localhost tmp]# ls a{abc}b//a{abc}b被当作文件名ls: cannot access a{abc}b: No such file or directory[root@localhost tmp]# ls a{abc,}baabcbab[root@localhost tmp]# ls a{abc,xyz}baabcbaxyzb[root@localhost tmp]# ls a{abc,xyz,012}ba012baabcbaxyzb//拓展[root@localhost tmp]# ls a[0-9a-z][0-9a-z][0-9a-z]ba012baabcbaxyzb

4.脚本规范

[root@localhost ~]# vim helloworld.sh //.sh代表这个文件是个shell脚本,拓展名后缀,如果省略.sh则不易判断该文件是否为shell脚本1. #!/usr/bin/env bash//shebang蛇棒, 解释器, 翻译 2. #3. # Author: soso6664. # Email: soso666@163.com //一些注释,可以解释一下脚本作用5. # Github: https:github.com/soso6666. # Date: 2019/12/247. printf "hello world"//功能说明:打印hello world[root@localhost ~]# sh helloworld.sh hello world

5.脚本运行方式

5.1.bash脚本执行

[root@localhost ~]# vim /opt/test/script/test.sh#!/bin/bash# 获取主机基本信息time=`date +%F-%T`#等同于 $(date +%F-%T)#ifconfig命令需要安装net-tools工具包ip=`ifconfig |grep broadcast|awk '{print $2}'`echo "现在的时间是:" $timeecho "当前的用户是:" $USERecho "当前的用户标识:" $UIDecho "当前的主机名称是:" $HOSTNAMEecho "当前可用网卡IP是:" $ip[root@localhost ~]# cd /opt/test/script/

1.source 文件名
使用当前shell(父shell)执行 比如cd /tmp会改变当前shell环境,但是其他的方式不会

[root@localhost script]# source test.sh现在的时间是: 2023-09-07-19:52:54当前的用户是: root当前的用户标识: 0当前的主机名称是: localhost.localdomain当前可用网卡IP是: 192.168.221.136

2.bash或者sh 文件名

[root@localhost script]# bash test.sh现在的时间是: 2023-09-07-19:53:03当前的用户是: root当前的用户标识: 0当前的主机名称是: localhost.localdomain当前可用网卡IP是: 192.168.221.136[root@localhost script]# sh test.sh现在的时间是: 2023-09-07-19:53:09当前的用户是: root当前的用户标识: 0当前的主机名称是: localhost.localdomain当前可用网卡IP是: 192.168.221.136

3.相对路径或者绝对路径
需要提前授权

[root@localhost script]# ./test.sh-bash: ./test.sh: 权限不够[root@localhost script]# chmod +x ./test.sh[root@localhost script]# ./test.sh现在的时间是: 2023-09-07-19:56:25当前的用户是: root当前的用户标识: 0当前的主机名称是: localhost.localdomain当前可用网卡IP是: 192.168.221.136[root@localhost script]# /opt/test/script/test.sh现在的时间是: 2023-09-07-19:56:36当前的用户是: root当前的用户标识: 0当前的主机名称是: localhost.localdomain当前可用网卡IP是: 192.168.221.136

5.2.bash脚本测试

1.这将执行该脚本并显示所有变量的值

[root@localhost ~]# sh -x /root/helloworld.sh+ printf 'hello world'hello world

2.不执行脚本只是检查语法模式,将返回所有错误语法

[root@localhost ~]# sh -n /root/helloworld.sh

3.执行脚本前把脚本内容显示在屏幕上

[root@localhost ~]# sh -v /root/helloworld.sh#!/usr/bin/env bash## Author: soso666# Email: soso666@163.com# Github: https:github.com/soso666# Date: 2019/12/24printf "hello world"hello world

二、bash配置文件

1.全局配置文件

/etc/bashrc、/etc/profile、/etc/profile.d/*.sh

如果修改/etc/profile文件修改出错,导致无法敲系统命令,例如:ls,怎么解决呢?
在命令行中输入
export PATH=$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/bin
然后将该命令【追加】到/etc/profile文件中,修改完后
source /etc/profile

2.个人配置文件

~/.bash_profile、~/.bashrc

profile类的文件:设定环境变量,运行命令或脚本,用户在登录的时候会自动生效
bashrc类的文件:定义命令别名

用户登录时加载bash配置文件的过程:
登录式shell加载配置文件过程:先个人,再公共;先局部,再全局
~/.bash_profile –> ~/.bashrc –> /etc/bashrc —> /etc/profile –> /etc/profile.d/*.sh
这里的优先级是影响范围最小的优先级最高

非登录式shell加载配置文件过程
~/.bashrc –> /etc/bashrc –> /etc/profile.d/*.sh

下面的文件为系统的每个用户设置环境信息Shell设置文件:
/etc/profile(系统级)启动时执行
这是系统最主要的shell设置文件,也是用户登陆时系统最先检查的文件,有关重要的【环境变量】都定义在此,其中包括 PATH,USER,MAIL,HOSTNAME,HISTSIZE,INPUTRC等。而在文件的最后,它会检查并执行/etc/profile.d/*.sh的脚本。
~/.bash_login(用户级)登录时执行,默认不存在
如果~/.bash_profile文件不存在,则系统会转而读取.bash_login这个文件内容。这是用户的登陆文件,在每次用户登陆系统时,bash都会读此内容,所以通常都会将登陆后必须执行的命令放在这个文件中。
~/.bash_logout 离开时执行如果想在注销shell前执行一些工作,都可以在此文件中设置。
例如:vi ~.bash_logout
clear #仅执行一个clear命令在你注销的时候
~/.bash_history(用户级) 这个文件会记录用户先前使用的历史命令。