Shell与Bash学习

1.什么是Shell

什么是shell呢?shell的作用,在我看来就是建立一个我们(用户)与计算机内核之间的桥梁。计算机的内核通过操作系统控制,而用户通过操作系统上发展的应用程序来控制计算机工作。简而言之就是通过shell将我们输入的命令与内核进行通信。
在这里插入图片描述
值得注意的是,在Linux系统下,当我们打开一个终端的时候,这个终端并不是shell。但是终端将我们(用户)和shell连接起来,终端会连接到shell。

1.1.查看Linux下的shell

zhangsan@Aliyun:~$ cat /etc/shells

该命令可以查看我们当前在Linux里安装的shell内容。

1.2.判断bash,shell的内置命令

zhangsan@Aliyun:~$ type [-tpa] name

通过type命令我们可以知道一个命令是否为bash的内置命令。这个type也可以用来作为类似which命令的用途。

2.Shell的变量

Shell中的变量是Shell的重要内容。Shell中的变量包括了环境变量本地变量位置变量,通过修改变量可以使自己的Linux系统个性化。

2.1.变量的显示与设置

如何去设置一个变量呢?在我们打开我们的终端机时,就意味着终端机已经打开了一个shell了。当我们想要定义,修改,取消这个变量时,可以用如下的方式。

zhangsan@Aliyun:~$ echo $myname
  #(这里的显示是空的,表示没有定义这个变量)
zhangsan@Aliyun:~$ myname=Vbird
zhangsan@Aliyun:~$ echo $myname
Vbird

在这里,需要提到变量设置所需要注意的事项:

  1. 转义字符:转义字符是给一些特殊字符变成一般字符用的。([Enter]、$、\、空格、!)
  2. 双引号字符 :双引号能够保持特殊字符的意义若“var=“lang is $LANG””,则我们输出时,可以输入echo $var,输出值为:lang is en_US
  3. 单引号字符: 单引号不能够保持特殊字符的意义若“var=“lang is $LANG””,则我们输出时,可以输入echo $var,输出值为:lang is $LANG
  4. 反引号:反单引号“`命令`”,可以在一串命令中加入其他的命令信息。举例: ls -l `locate crontab`,鸟哥推荐使用$(命令)模式

2.2.环境变量的设置

在我目前的这个shell下,继续打开一个新的shell,那么新的shell就是原先的子进程,子进程与父进程的变量没有任何关系,如何让一个变量在子进程中有效,需要将其变成环境变量。在切换用户的的时候,输入root的瞬间,给环境变量赋值了

#查看环境变量
zhangsan@Aliyun:~$ env
#查看环境变量以及自己定义的变量
zhangsan@Aliyun:~$ set

关于环境变量与自定义变量之间的关系,可以理解为:

环境变量=全局变量
自定义变量 = 局部变量

2.3.几个比较重要的环境变量

在这么多的环境变量中,哪些是比较重要的?

  1. PS1(提示符的设置)(提示符的设置)
zhangsan@Aliyun:~$ #就是命令提示符,这个提示符是可以更改的
  1. $(关于本shell的PID) 代表了目前这个Shell的线程代号
  2. 关于上一个执行命令的回传码

2.4.父进程与子进程之间的关系

环境变量与自定义变量的差异在于变量是否会被子进程继续引用。两者之间的关系可以用图片来说明:
在这里插入图片描述
进入子进程后,父进程就会中断。

2.5.变量键盘读取、数组与声明:read,array,declare

如果需要读取来自键盘的命令,那么就需要read函数,这里只给出一例。

zhangsan@Aliyun:~$ read -p "please keyin your name" -t 30 named
zhangsan@Aliyun:~$ echo $named

declare/typeset(声明变量的类型)

#将sum声明为环境变量
zhangsan@Aliyun:~$ declare -x sum
#让sum只可读
zhangsan@Aliyun:~$ declare -r sum #(sum这个变量不可以改动了)
#让sum变为非环境的变量 
zhangsan@Aliyun:~$ declare +x sum

数组的定义与读取

zhangsan@Aliyun:~$ var[1]="small min"
zhangsan@Aliyun:~$ var[2]="big min"
zhangsan@Aliyun:~$ var[3]="nice min"
zhangsan@Aliyun:~$ echo "$ {var[1]} ,$ {var[2]} ,$ {var[3]}"

2.6.变量内容的删除、替代与替换

通过命令将简单的变量进行微调。

zhangjie@Aliyun:~$ path=${PATH}
zhangjie@Aliyun:~$ echo $path
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
# 假设我需要将games删掉
zhangjie@Aliyun:~$ echo ${path#/*games:}
/usr/local/games:/snap/bin
# 一个#的作用就是找到符合的*games:的最短的内容,并其前面的所有都删掉,最短的就是/usr/games:了。
zhangjie@Aliyun:~$ echo ${path##/*games:}
/snap/bin
# 两个##就是找到最长的,把前面的都删掉,顺序是从左往右
# 如果要从右往前,那么就需要将#改成%

关于这部分有个小应用,在这里打一下:

zhangjie@Aliyun:~$ mail=/var/spool/mail/root
zhangjie@Aliyun:~$ echo $mail
/var/spool/mail/root
zhangjie@Aliyun:~$ echo ${mail#/*/}  #这里找最小的就是/var/
spool/mail/root
zhangjie@Aliyun:~$ echo ${mail##/*/} #这里最大的竟然是/var/spool/mail/ 有种恍然大悟的感觉
root
zhangjie@Aliyun:~$ echo ${mail%/*}  #因为为%,从右向左
/var/spool/mail

变量的替换内容比较简单,这里就不做笔记了。包含两类内容,一类是第一个替换,另一个是符合要求的全部替换。

zhangjie@Aliyun:~$ echo ${path/old/new} #只替换第一个
zhangjie@Aliyun:~$ echo ${path//old/new} #全部替换

变量的测试与内容的替换,这部分属于记忆内容。

zhangjie@Aliyun:~$ username=${username-root}
#首先判度username这个变量是否被定义过,如果被定义过了,那么就不变。如果没有被定义过,那username就是root
zhangjie@Aliyun:~$ echo ${path//old/new} #全部替换

还有很多内容,知道这个点,以后要学会回来查。

3.命令与历史命令

3.1.别名的设置

有些命令会特别长,可以将一些命令定义为自己熟悉的命令,采用alias这个方法

zhangjie@Aliyun:~$ alias lm='ls -l | more '
zhangjie@Aliyun:~$ alias rm='rm -i'

如何知道目前已经有哪些别名了呢?

zhangjie@Aliyun:~$ alias 
alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l='ls -CF'
alias la='ls -A'
alias ll='ls -alF'
alias lm='ls -l | more '
alias ls='ls --color=auto'
alias rm='rm -i'

这些就是我目前已经存在的别名。

3.2.历史命令:history

当我们以bash登陆Linux的主机后,系统会主动由文件夹的~/.bash_history读取以前曾经下过的命令。当然,history的功能不只查询命令,还可以执行!

zhangjie@Aliyun:~$ !888  #执行第888条历史命令
date --utc
2020年 02月 08日 星期六 12:24:39 UTC
zhangjie@Aliyun:~$ !!  #执行上一个命令
date --utc
2020年 02月 08日 星期六 12:25:44 UTC
zhangjie@Aliyun:~$ !ec  #执行最近的一个以ec开头的命令
echo $MAIL
/var/mail/root

4.通配符

在bash的操作环境中存在一个有用的功能就是通配符(wildcard)

符号意义
*代表0到无穷多个任意字符
代表一定有一个任意字符
[ ]代表一定有一个在括号内的字符,例如[abcd] 代表一定有一个字符,可能是a,b,c,d四个中的任意一个
[-]代表顺序编码,[0-9]代表了0到9之间的所有数字
[^]代表顺序编码,[^abv]代表不是abc都可以接受

利用通配符,可以快速查找文件。

# 查找eron开头的文件
zhangjie@Aliyun:~$ ll -d /etc/cron* 
drwxr-xr-x 2 root root 4096 1月  27 15:34 /etc/cron.d/
drwxr-xr-x 2 root root 4096 1月  27 15:36 /etc/cron.daily/
drwxr-xr-x 2 root root 4096 6月  24  2019 /etc/cron.hourly/
drwxr-xr-x 2 root root 4096 1月  27 15:34 /etc/cron.monthly/
-rw-r--r-- 1 root root  722 11月 16  2017 /etc/crontab
drwxr-xr-x 2 root root 4096 1月  27 15:34 /etc/cron.weekly/
# 查找5个字母的文件
zhangjie@Aliyun:~$ ll -d /etc/?????
drwxr-xr-x 3 root root 4096 1月  27 15:36 /etc/avahi/
drwxr-xr-x 4 root root 4096 6月  24  2019 /etc/cloud/
drwxr-xr-x 4 root root 4096 1月  27 15:32 /etc/dconf/
drwxr-xr-x 3 root root 4096 1月  27 15:33 /etc/emacs/
drwxr-xr-x 4 root root 4096 1月  27 15:34 /etc/fonts/
-rw-r--r-- 1 root root  625 6月  24  2019 /etc/fstab
drwxr-xr-x 3 root root 4096 1月  27 15:37 /etc/fwupd/
drwxr-xr-x 3 root root 4096 1月  27 15:31 /etc/glvnd/
drwxr-xr-x 2 root root 4096 1月  27 15:34 /etc/gnome/
drwxr-xr-x 2 root root 4096 6月  24  2019 /etc/groff/
-rw-r--r-- 1 root root 1006 2月   1 18:36 /etc/group
-rw-r--r-- 1 root root  231 10月 30 14:42 /etc/hosts
-rw-r--r-- 1 root root   57 2月   6 19:24 /etc/issue
-rw-r--r-- 1 root root  267 4月   9  2018 /etc/legal
-rw-r--r-- 1 root root  111 2月  14  2018 /etc/magic
drwxr-xr-x 3 root root 4096 6月  24  2019 /etc/mysql/
drwxr-xr-x 2 root root 4096 1月  27 15:38 /etc/pam.d/
# 查找含有数字的文件
zhangjie@Aliyun:~$ ll -d /etc/*[0-9]*
drwxr-xr-x  4 root root  4096 6月  24  2019 /etc/dbus-1/
drwxr-xr-x  8 root root  4096 1月  27 15:38 /etc/gdm3/
drwxr-xr-x  2 root root  4096 1月  27 15:38 /etc/gtk-3.0/
drwxr-xr-x  2 root root  4096 1月  27 15:33 /etc/ImageMagick-6/
drwxr-xr-x  4 root root  4096 6月  24  2019 /etc/iproute2/
drwxr-xr-x  2 root root  4096 6月  24  2019 /etc/libnl-3/
-rw-r--r--  1 root root   812 3月  25  2018 /etc/mke2fs.conf
-rw-r--r--  1 root root  7649 1月  27 15:37 /etc/pnm2ppa.conf
drwxr-xr-x  5 root root  4096 1月  27 15:31 /etc/polkit-1/
drwxr-xr-x  2 root root  4096 6月  24  2019 /etc/python2.7/
drwxr-xr-x  2 root root  4096 6月  24  2019 /etc/python3/
drwxr-xr-x  2 root root  4096 6月  24  2019 /etc/python3.6/
drwxr-xr-x  2 root root  4096 2月   1 16:56 /etc/rc0.d/
drwxr-xr-x  2 root root  4096 2月   1 16:56 /etc/rc1.d/
drwxr-xr-x  2 root root  4096 2月   1 16:56 /etc/rc2.d/
drwxr-xr-x  2 root root  4096 2月   1 16:56 /etc/rc3.d/
drwxr-xr-x  2 root root  4096 2月   1 16:56 /etc/rc4.d/
drwxr-xr-x  2 root root  4096 2月   1 16:56 /etc/rc5.d/
drwxr-xr-x  2 root root  4096 2月   1 16:56 /etc/rc6.d/

5.数据流重定向

某个命令执行后要输出在屏幕的数据输出到其他地方,我们可以通过数据重定向实现数据的保留。

5.1.什么是数据流重定向

如下图所示,当我们在执行一个命令时,这个命令可能由文件读入数据,经过处理后,输出到屏幕上。输出有两种,一种是标准输出,一种是标准错误输出。标准输出就是命令执行回传的正确的信息,而标准错误输出可理解为命令执行失败后,所传回的输出。标准输出与标准错误输出都会输出到屏幕上。
在这里插入图片描述

  1. 标准输入(stdin):代码为0,使用<或<<;
  2. 标准输出(stdout):代码为1,使用>或者>>
  3. 标准错误输出(stderr):代码为2,使用2>或2>>

5.2.标准输出

关于这个输出,有一个小的例子。

zhangjie@Aliyun:~$ 11 / > ~/zhangjie_file 
# 将输出的内容放到zhangjie_file这个文件夹
# 若zhangjie_file这个文件夹不存在,创建
# 若zhangjie_file这个文件夹存在,覆盖
# 用>>时,zhangjie_file 不会被覆盖,而是叠加上去
zhangjie@Aliyun:~$ ll ~
drwxrwxr-x  2 zhangjie     zhangjie  4096 1月  30 16:37 zhangsan_file/

当然,我们可以将正确信息与错误信息都输出到文件上。用下面的方式:

# 将stdout 与 stderr 分别存到不同的文件中去
zhangjie@Aliyun:~$ find /home -name .bashrc > ~/list_right 2> ~/list_error
zhangjie@Aliyun:~$ cat ~/list_right
/home/zhengxianjun/.bashrc
/home/zhangjie/.bashrc
zhangjie@Aliyun:~$ 

5.3.标准输入

标准输入就是可以用文件输入来代替键盘是输入。首先是<代表的输入值。

zhangjie@Aliyun:~$ cat > catfile < ~/.bashrc
zhangjie@Aliyun:~$ ll catfile ~/.bashrc
-rw-rw-r-- 1 zhangjie zhangjie 3771 2月   8 22:51 catfile
-rw-r--r-- 1 zhangjie zhangjie 3771 11月 10 15:51 /home/zhangjie/.bashrc

之后是符合<<的意义,<<代表的是结束输入的意思。

zhangjie@Aliyun:~$ cat > catfile << "eof"
> This is a test
> OK is now
> eof  #这里就输入终止了

那么<<的作用就是可以终止一次输入。

5.4.命令执行的判断依据

需要连续执行多个命令的操作。

zhangjie@Aliyun:~$  sync; sync; shutdown -h now
User root is logged in on sshd.
Please retry operation after closing inhibitors and logging out other users.
Alternatively, ignore inhibitors and users with 'systemctl poweroff -i'.

命令的回传码$?与&&或者||

命令执行情况说明
cmd1&&cmd2若cmd1执行完毕且正确执行($?=0),则开始执行cmd2 若cmd1执行完毕且错误( $? !=0),则不执行cmd2
cmd1||cmd2若cmd1执行完毕且正确执行($?=0),则不执行cmd2 若cmd1执行完毕且错误( $? !=0),则执行cmd2

这个命令可以这样理解,&&代表与命令,只有cmd1与cmd2均为真,才是真,所以cmd1正确,就会执行cmd2。当cmd1假的时候,就没必要执行cmd2了。
而||代表了或命令,cmd1与cmd2其中一个为真就是真。当cmd1为真,没必要执行cmd2了。当cmd1为假,则可执行cmd2判度。
这里举一个例子。

zhangjie@Aliyun:~$ ls /tmp/abc || mkdir /tmp/abc && touch /tmp/abc/hello
ls: cannot access '/tmp/abc': No such file or directory
zhangjie@Aliyun:~$ tree /tmp/abc
/tmp/abc
└── hello

在这段代码中,若/abc存在,则不创建。若/abc不存在,则创建/abc。由于命令是一个一个执行的,因此第二段若执行成功,第三段代码不会执行。若第二段执行失败,第三段执行。

6.管道命令

管道命令仅仅能够执行由前面一个 命令传来的正确的信息,也就是standard output的信息,对于standard error的信息没有直接处理的能力。用下图来表示管道命令。
在这里插入图片描述
也就说,管道进能够处理standard output,对于standard error output 会予以忽略。

6.1.选取命令:cut,grep

cut命令就是将一段信息的某一段"切"出来,处理的信息是以行为单位的。下面选取一个例子:

zhangjie@Aliyun:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
zhangjie@Aliyun:~$ echo $PATH | cut -d":" -f1,5
# 将第三段与第五段切出来
/usr/local/sbin:/sbin
# 将export 输出的12字符以后的所有字符串进行输出
zhangjie@Aliyun:~$ export | cut -c 12-
LANG="en_US.UTF-8"
LC_ADDRESS="zh_CN.UTF-8"
LC_IDENTIFICATION="zh_CN.UTF-8"
LC_MEASUREMENT="zh_CN.UTF-8"
LC_MONETARY="zh_CN.UTF-8"
LC_NAME="zh_CN.UTF-8"
LC_NUMERIC="zh_CN.UTF-8"
LC_PAPER="zh_CN.UTF-8"
LC_TELEPHONE="zh_CN.UTF-8"
LC_TIME="zh_CN.UTF-8"
LESSCLOSE="/usr/bin/lesspipe %s %s"
LESSOPEN="| /usr/bin/lesspipe %s"

grep命令就是在一行的信息中提取出关键字,当然,也可以反向提取(就是删除关键字)

zhangjie@Aliyun:~$ cat /etc/passwd | grep "root"
root:x:0:0:root:/root:/bin/bash
# 以:为分割,提取第一个,即为root
zhangjie@Aliyun:~$ cat /etc/passwd | grep "root" | cut -d ':' -f1
root

6.2.排序命令:sort,wc,uniq

sort命令:sort命令可以帮助计算器排序,内置了很多的排序方法。

zhangjie@Aliyun:~$ last | cut -d " " -f1 | sort
root
root
root
root
root
root
root
root
root
root
root

uniq 将重复是删掉只显示一个

zhangjie@Aliyun:~$ last | cut -d " " -f1 | sort | uniq -c
      1 
     19 root
      1 wtmp
     19 zhangjie

从这里可以显示每个用户登陆的次数。我登陆的次数就是那么多哈哈哈。
wc:该命令为word+count的简称

zhangjie@Aliyun:~$ cat /etc/manpath.config  |wc
131     715    5174  #代表了行数,字数,字符数

6.3.数据的重定向:tee

tee可以将数据了传送到文件和屏幕(screen),传输到屏幕的就是stdout。这里不再详细介绍。

6.4.字符转换命令

  1. **tr:**删除一段文字中的信息
  2. col将tab键变为空格键
  3. join将两个文件中有相同数据的一行加在一起
  4. paste将两个文件的数据无脑粘贴
  5. expand将tab转化为空格
  6. split将大文件切割为小文件
  7. xrage参数代换
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值