07_学习Bash

硬件、内核和Shell

在计算机系统重,Shell是一个很常见的词汇,甚至很多软件就以shell命名。比如微软的PowerShell等。那到底什么是shell呢。

首先我们的电脑操作系统其实是一组软件,用户通过这些软件来操作电脑上的硬件。我们通过shell将命令输入给操作系统,操作系统与内核进行沟通,最终去调动我们想操作的硬件。

这样一来,shell就是在整个系统的最外层,像一个壳一样保护着系统的内核。

为什么要学习shell

首先,Linux系统虽然也有桌面操作系统,但是一般为了服务器的效率和轻量化,只会安装Linux的核心程序,大多数情况下我们需要用shell和系统进行交互。

其次,一些复杂的操作,和一些软件的设置,也确实需要通过shell。

Bash shell的功能

shell曾经有很多版本,不过现在默认用的是/bin/bash,它有很多很棒的功能。

  • 记录历史命令:通过键盘上的↑↓键,我们可以很轻松的翻看之前执行过的命令,这是一个很实用的功能

  • 命令与文件补全:tab键可以补全命令和文件名

  • 命令别名设置alisa:可以输入alias看看默认有哪些设置,这个功能类似于python里的import pandas as pd

    python 复制代码
    [root@node4 ~]# alias
    alias cp='cp -i'
    alias egrep='egrep --color=auto'
    alias fgrep='fgrep --color=auto'
    alias grep='grep --color=auto'
    ...
  • 支持通配符和脚本编程

查看bash命令type

通过type可以查看某个命令是否是bash内置的

python 复制代码
[root@node4 ~]# type -a ls
ls 是 `ls --color=auto' 的别名
ls 是 /usr/bin/ls

Shell中的变量

举例来说,用户a的邮件存储在/var/spool/mail/usera,用户b登录系统后,他的邮件存储在/var/spool/mail/userb。在使用mail命令收发邮件时,它自动会替换变量为用户名,就不会出现a的邮件和b混在一起的情况了

环境变量PATH,这个前面了解过了。我们之所以能在各个路径下执行系统命令,就是因为这个PATH

  • 使用echo查看变量:

    python 复制代码
    [root@node4 ~]# echo $PATH
    /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/java/default/bin:/usr/java/default/bin:/opt/zookeeper-3.4.6/bin:/opt/hadoop-2.6.5/bin:/opt/hadoop-2.6.5/sbin:/opt/nginx/sbin:/root/bin
    
    [root@node4 ~]# echo $HOME
    /root
  • 使用echo设定变量:

    python 复制代码
    # myname还未赋值
    [root@node4 ~]# echo $myname
    
    # 赋值过程,注意不能有空格
    [root@node4 ~]# myname=kayotin
    # 赋值后
    [root@node4 ~]# echo $myname
    kayotin
  • 双引号中的特殊字符可以保有原始特效

    python 复制代码
    [root@node4 ~]# myvar="lang is $LANG"
    [root@node4 ~]# echo $myvar
    lang is zh_CN.UTF-8
  • 单引号中的字符是纯文本

    python 复制代码
    [root@node4 ~]# myvar='lang is $LANG'
    [root@node4 ~]# echo $myvar
    lang is $LANG
  • 取消变量内容

    python 复制代码
    [root@node4 ~]# unset myvar

环境变量的功能

用env命令可以看到当前的环境变量:

python 复制代码
[root@node4 ~]# env
XDG_SESSION_ID=1
HOSTNAME=node4
TERM=xterm
SHELL=/bin/bash
HADOOP_HOME=/opt/hadoop-2.6.5
HISTSIZE=1000
SSH_CLIENT=192.168.32.1 10043 22
SSH_TTY=/dev/pts/0
USER=root
......

set命令可以显示所有变量,包括我们自己设置的

python 复制代码
[root@node4 ~]# set
BASH=/bin/bash
......
colors=/root/.dircolors
myname=kayotin

**$**本身也是一个变量,代表当前shell的pid

python 复制代码
[root@node4 ~]# echo $$
1974

?也是一个变量,代表上一个指令的执行结果

python 复制代码
# 代表上一个指令执行成功
[root@node4 ~]# echo $?
0
[root@node4 ~]# 12name=123
-bash: 12name=123: 未找到命令
# 上一个命令执行错误,返回错误代码
[root@node4 ~]# echo $?
127

从键盘输入变量read

通过read命令,我们将输入内容作为赋值给了变量atest。read命令常用来做用户输入,有点像python的input方法。

python 复制代码
[root@node4 ~]# read atest
this is a test
[root@node4 ~]# echo $atest
this is a test

声明变量类型declare,typeset

declare和typeset这两个命令用来声明变量的类型,如下例子

python 复制代码
# 默认是字符串
[root@node4 ~]# sum=100+200
[root@node4 ~]# echo $sum
100+200
# 声明sum是int类型后,就能正确计算结果了
[root@node4 ~]# declare -i sum=100+200
[root@node4 ~]# echo $sum
300
# 常用参数
-i 指定为int
-a 定义为数组类型
-x 与export类似,将变量定义为环境变量
-r 将变量定义为只读,值不可修改

数组

python 复制代码
[root@node4 ~]# my_arr[1]=alice
[root@node4 ~]# echo ${my_arr[1]}
alice
[root@node4 ~]# my_arr[2]=giri
[root@node4 ~]# echo ${my_arr[2]}
giri

文件系统限制-ulimit

为了防止多人登录时,系统加载太多资源挂掉,可以用ulimit命令设置一些限制

python 复制代码
# 打印当前设置
[root@node4 ~]# ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited

变量的删除替换操作

#符合替换文字【最短的】一个

##符合替换文字【最长的】那一个

python 复制代码
[root@node4 ~]# echo ${MAIL##/*/}
root
[root@node4 ~]# echo ${MAIL%/*}
/var/spool/mail

历史命令history

前面说过,linux默认最多记录1000个历史命令,通过history就可以看到这些历史命令

python 复制代码
[root@node4 ~]# history
    1  vi /etc/hosts
    2  date
    3  vim /etc/hosts
    4  vim /etc/profile
    5  chkconfig
    ......

数据流向>

python 复制代码
# 将ll打印的信息,输出到myfile这个文件里
[root@node4 ~]# ll > myfile
[root@node4 ~]# ls
anaconda-ks.cfg  backups  hello.txt  myfile  newfile  newslink  zookeeper.out
[root@node4 ~]# cat myfile
  • 1>:默认方式,以覆盖方式将正确数据输出到指定文件或设备
  • 1>>:以累加方式将正确数据输出到指定文件或设备
  • 2>:以覆盖方式将错误数据输出到指定文件或设备
  • 2>>:以累加方式将错误数据输出到指定文件或设备
python 复制代码
# 将键盘输入数据增量保存在刚刚的myfile
[root@node4 ~]# cat >> myfile
ceshi ceshi ceshi
[root@node4 ~]# cat myfile
总用量 28
-rw-------. 1 root root  1338 6月  25 2022 anaconda-ks.cfg
drwx------  2 root root     6 3月  31 17:32 backups
-rw-r--r--  1 root root     7 4月   8 20:10 hello.txt
-rw-r--r--  1 root root     0 4月  10 20:29 myfile
-rw-r--r--  2 root root     0 3月  28 21:00 newfile
lrwxrwxrwx  1 root root    12 3月  28 21:10 newslink -> /opt/newfile
-rw-r--r--  1 root root 19489 11月  9 2022 zookeeper.out
ceshi ceshi ceshi

可以使用反向的<和<<从文件读取数据

如果想要保存到文件的同时在屏幕上输出,可以使用tee命令

一次执行多个命令; && ||

想要在一次输入后,执行多个命令,有以下几种方式

  • 命令;命令:此种方式不考虑多个命令之间的关联性,也就是不管前面的命令是成功或者失败,都会继续执行,例如

    python 复制代码
    sync; shutdown -h now
  • 命令1&&命令2:如果命令1正确执行(也就是读取到$?=0),才会执行命令2;否则不执行命令2

    python 复制代码
    [root@node4 ~]# ls testfile && touch testfile
    ls: 无法访问testfile: 没有那个文件或目录
  • 命令1||命令2:如果命令1正确执行,那就不执行命令2;否则执行命令2

    python 复制代码
    # 可以看到虽然报错了,但这个file已经建立了,也就是命令2执行了
    [root@node4 ~]# ls testfile || touch testfile
    ls: 无法访问testfile: 没有那个文件或目录
    [root@node4 ~]# ll testfile
    -rw-r--r-- 1 root root 0 4月  10 20:56 testfile

管道命令|和选取命令:cut、grep

有时候我们需要命令1的结果去作为命令2的输入,这时候就要用管道命令。

也正因为如此,它常常和切片命令cut、grep一起使用,因为往往前一个命令的输出只有一部分是我们需要的。

  • cut命令对输入字符进行切片

    python 复制代码
    # 以:分隔,输出第一个结果
    [root@node4 ~]# echo $PATH | cut -d ':' -f 1
    /usr/local/sbin
    # 支持多个,比如输入1和3
    [root@node4 ~]# echo $PATH | cut -d ':' -f 1,3
    /usr/local/sbin:/usr/sbin
    
    # 切片,保留[12:]
    [root@node4 ~]# export
    declare -x HADOOP_HOME="/opt/hadoop-2.6.5"
    declare -x HISTCONTROL="ignoredups"
    [root@node4 ~]# export | cut -c 12-
    HADOOP_HOME="/opt/hadoop-2.6.5"
    HISTCONTROL="ignoredups"
  • grep分析一行信息,如果有我们需要的,就拿出来,有点像筛选

    python 复制代码
    # 筛选包含root的行
    [root@node4 ~]# last | grep root
    root     pts/0        192.168.32.1     Wed Apr 10 19:37   still logged in   
    root     pts/0        192.168.32.1     Tue Apr  9 20:56 - down   (01:01) 
    # 不包含root的行
    [root@node4 ~]# last | grep -v root
    reboot   system boot  3.10.0-1160.108. Wed Apr 10 19:34 - 21:10  (01:35)    
    reboot   system boot  3.10.0-1160.108. Tue Apr  9 20:42 - 21:57  (01:14) 

排序命令:sort、wc、uniq

  • 使用sort进行排序

    python 复制代码
    # 对用户信息按字母顺序排序
    [root@node4 ~]# cat /etc/passwd | sort
    adm:x:3:4:adm:/var/adm:/sbin/nologin
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
  • uniq,进行重复

    python 复制代码
    # uniq不显示重复数据
    [root@node4 ~]# last | cut -d ' ' -f1 | sort | uniq 
    
    reboot
    root
    wtmp
    
    # 统计每个用户登录次数
    [root@node4 ~]# last | cut -d ' ' -f1 | sort | uniq -c
          1 
         40 reboot
         42 root
          1 wtmp
  • wc:统计字数

    python 复制代码
    [root@node4 ~]# last | wc
         84     865    6352
    # 分别代表行 字数 字符数
    # 计算历史登录总人数
    [root@node4 ~]# last | grep [a-zA-Z] | grep -v 'reboot'| wc -l
    43

字符转换命令 tr/col/join/paste/expand

  • tr

    python 复制代码
    # 替换成大写
    [root@node4 ~]# last | tr '[a-z]' '[A-z]'
    ROOT     PTS/0        192.168.32.1     WED APR 10 19:37   STILL LOGGED IN 
  • col 多用来将tab替换为空格

    python 复制代码
    [root@node4 ~]# cat /etc/man_db.conf  | col -x | cat -A |more
  • join处理相关数据

    python 复制代码
    # 比如passwd和shadow这两个文件,他们的签名都是用户名
    [root@node4 ~]# head -n 3 /etc/passwd /etc/shadow
    ==> /etc/passwd <==
    root:x:0:0:root:/root:/bin/bash
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    
    ==> /etc/shadow <==
    root:$6$Rj7coYh/STyMcxjn$ZY.l1SDPcsJv1NUwiA.INYB7Q/bTxAXHFyRTm42M/qxdPWAt9Ly3eQSpu1Xn5v9LkxLJITwb6igAUPMOD.mBj/::0:99999:7:::
    bin:*:18353:0:99999:7:::
    daemon:*:18353:0:99999:7:::
    
    # 将相同用户名数据拼起来
    [root@node4 ~]# join -t ':' /etc/passwd /etc/shadow | head -n 3
    root:x:0:0:root:/root:/bin/bash:$6$Rj7coYh/STyMcxjn$ZY.l1SDPcsJv1NUwiA.INYB7Q/bTxAXHFyRTm42M/qxdPWAt9Ly3eQSpu1Xn5v9LkxLJITwb6igAUPMOD.mBj/::0:99999:7:::
    bin:x:1:1:bin:/bin:/sbin/nologin:*:18353:0:99999:7:::
    daemon:x:2:2:daemon:/sbin:/sbin/nologin:*:18353:0:99999:7:::
  • paste 直接将两行粘在一起,中间用tab分隔

    python 复制代码
    [root@node4 ~]# paste /etc/passwd /etc/shadow
    root:x:0:0:root:/root:/bin/bash	root:$6$Rj7coYh/STyMcxjn$ZY.l1SDPcsJv1NUwiA.INYB7Q/bTxAXHFyRTm42M/qxdPWAt9Ly3eQSpu1Xn5v9LkxLJITwb6igAUPMOD.mBj/::0:99999:7:::
  • expand也是转换tab为空格

相关推荐
代码雕刻家3 分钟前
课设实验-数据结构-单链表-文教文化用品品牌
c语言·开发语言·数据结构
一个闪现必杀技6 分钟前
Python入门--函数
开发语言·python·青少年编程·pycharm
Fan_web9 分钟前
jQuery——事件委托
开发语言·前端·javascript·css·jquery
龙图:会赢的13 分钟前
[C语言]--编译和链接
c语言·开发语言
韩楚风1 小时前
【linux 多进程并发】linux进程状态与生命周期各阶段转换,进程状态查看分析,助力高性能优化
linux·服务器·性能优化·架构·gnu
陈苏同学1 小时前
4. 将pycharm本地项目同步到(Linux)服务器上——深度学习·科研实践·从0到1
linux·服务器·ide·人工智能·python·深度学习·pycharm
Ambition_LAO1 小时前
解决:进入 WSL(Windows Subsystem for Linux)以及将 PyCharm 2024 连接到 WSL
linux·pycharm
Pythonliu71 小时前
茴香豆 + Qwen-7B-Chat-Int8
linux·运维·服务器
你疯了抱抱我1 小时前
【RockyLinux 9.4】安装 NVIDIA 驱动,改变分辨率,避坑版本。(CentOS 系列也能用)
linux·运维·centos
追风赶月、1 小时前
【Linux】进程地址空间(初步了解)
linux