美文网首页
Linux(一) shell基础 什么叫shell 为什么用sh

Linux(一) shell基础 什么叫shell 为什么用sh

作者: 石志不渝 | 来源:发表于2023-08-30 17:34 被阅读0次

    概要

    本文主要内容:

    1. linux的shell基础内容,包括为什么有shell、为什么学shell。
    2. bash的优势,包括history的原理、Tab补全的具体功能、环境变量概念的介绍。
    3. shell语法,及基本指令的使用。
    4. 介绍重定向的使用方法。
      文末附录中,包含了本文所用到的指令

    一 认识shell

    1.1 为什么叫shell

    shell 翻译为 。从操作系统结构来讲,系统从底层向上,依次为:硬件、内核、应用系统。其中硬件和内核对使用者而言,均无法直接使用;可直接使用的是位于最外层的应用系统,在最外层,就像是外壳,所以叫做shell,也就是下图红色区域。

    shell

    广义上来说,可以把所有用户使用的软件都叫做shell,它们都具有一定的与内核交互的能力。但一般而言,shell是指的命令窗口。某种意义上讲,命令窗口是真正的最外层,它可以启动所有应用。

    1.2 为什么要有shell

    其实应该问另一个问题,怎么能没有shell。我们说shell是系统的外壳,是用户界面。如果一个系统,没有用户界面,就像是我把一台主机放在你面前,插上电,不给你任何按钮,没任何对外的接口。我告诉你:“快用吧,抓紧用。” 请问你什么感觉?对于系统而言,也是一个道理,没有shell就没有了入口,就无法使用,所以说不能没有shell。

    1.3 这个时代shell还有什么用?

    我们此处先抛出AI的情况不谈,在如今具有界面的APP统一世界,很多人都不知道有命令窗这个东西的背景下,为什么还要用shell?这个答案其实很简单,有些情况下shell比界面操作方便的多。一个极端的例子,比如一个很简单的操作,帮我把文件夹里的jpeg(图像文件后缀之一)文件列个清单;如果文件夹里只有一个文件,那觉不出什么;如果里面有100个、1000个、100000个呢?随着量级的增加,在界面上去操作成了让人绝望的事情。然而量级的变化,对于使用shell的人来说,只是程序运行时间长短而已,对个人真正的工作量并不产生实质性的影响。

    for filename in `ls *.jpeg`
    do
    echo $filename >> ../list.txt
    done
    

    1.4 shell的版本

    序号 版本 描述
    1 sh sh是UNIX最初使用的shell,它在shell编程方面相当优秀,但在处理与用户的交互方面不如其他几种shell
    2 csh csh最初由Bill Joy编写,其更多地考虑了用户界面的友好性,支持命令补齐等一些sh所不支持的特性,但其编程接口不如sh
    3 ksh ksh集合了sh和csh的优点,并且与sh完全兼容
    4 bash bash是大多数Linux操作系统默认使用的shell,有灵活和强大的编程接口,同时又有很友好的用户界面
    5 tcsh tcsh是csh的一个扩展版本,与csh完全向后兼容
    6 pdksh pdksh是ksh的一个扩展版本。ksh是一个商用shell,不免费提供,而pdksh是免费的

    主流linux系统均选用bash作为shell终端

    二 bash的优势

    1. 使用\color{red}{上下方向键}的history功能
      历史执行过的命令,是存储在硬盘上的,电脑重启后依然有效。这个功能在bash处在运行状态时,是区分session的,也就是每个bash窗口都有它独立的history。当我们关闭bash窗口时,本窗口的history会被写入~/.bash_history,也就是说当再次启动bash窗口时,它调用的,是你\color{red}{最后一次关闭的}窗口的history
    2. 对命令、选项或文件名的\color{red}{Tab}键补全功能
      Tab补全功能,是根据你当前输入的情况,去做匹配补全的。如果你当前输入的内容,已经可以唯一性的匹配某一条指令(或者某一个选项、某一个参数)那么会给你自动补全,否则点击\color{red}{第一次}Tab时,不会有反应,说有要么\color{red}{没有}匹配、要么\color{red}{有多个}匹配结果
    3. 强大的环境变量功能
    4. shell编程方面较为优秀

    2.1 环境变量

    2.1.1 环境变量的解释

    环境变量可以理解为:软件运行环境中的变量。

    1. 变量
      首先我们需要知道什么叫变量,什么是变量的值。联想数学中,设:x=2那么x是变量,2是变量的值。
    2. 常量
      编程中,与变量对应的概念叫常量,在程序编译后、运行过程中变量的值是可以改变的;但常量的值是无法改变的。

    为什么需要无法改变值的常量呢?
    常量大多是需要重复使用的,在编译后无法改变,并不代表在开发阶段不会需要改变。有常量后,如果需要改变,只需要在声明常量的地方改一下就可以了。

    1. 软件运行的环境
      软件需要运行在系统(以及其自身)为其构建的环境中,就像学生学习是在教室中,教室中有白板、多媒体屏幕、桌椅,这些都是学生上课环境中的东西。

    2.1.2 ubuntu的部分环境变量

    环境变量,并不只有一个,而是有一组,很多。软件可以定义其本身需要的环境变量,比如我自己开发的软件名字是abc,我需要知道b软件包含的媒体文件的地址,那么我可以自己定义一个我需要的环境变量,比如b_media_path,用户想使用abc,则需要在环境变量中,设置b_media_path,并将其值设置为正确的b软件的地址。
    查看环境变量,可以直接执行命令env,简单摘录几个如下

    ubuntu@ubuntu2204:~$ env
    SHELL=/bin/bash
    LANGUAGE=en_US:
    HOME=/home/ubuntu
    USERNAME=ubuntu
    LANG=en_US.UTF-8
    PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin
    
    1. SHELL=/bin/bash 代表linux 系统所使用的shell是/bin/bash
    2. HOME=/home/ubuntu 代表系统的主目录,当你直接在bash中输入指令cd,不添加其他参数时,会调用HOME变量的值
    3. USERNAME=ubuntu 代表用户名
    4. PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin 表示路径匹配,当你在任意位置输入指令时,bash之所以可以调用到不在本目录下的可执行文件,就是使用了这个PATH的值,可以包含多个目录,目录和目录之间使用:进行分割。

    三 语法

    3.1 命令格式

    命令名 [参数] [对象1] [对象2]

    其中:

    1. 命令名 是一个可执行文件的文件名。比如ls指令,一般就是/usr/bin/目录下的可执行文件ls
    2. 命令格式中的[](中括号),代表此项是可选的,也就是说被中括号包围的内容,可以有也可以没有
      参见下述命令的比对
    3. 参数 表示将以何种功能执行命令名;选项均以-作为开始,参数命令名之间,需要有\color{red}{空格},多个参数可以连起来,也可以分开,分开始需要有\color{red}{空格}
    4. 对象 表示命令的操作对象,可以是文件、目录等等,与前面的内容之间需要有\color{red}{空格}
    5. 基础命令
      5.1. cd 用于切换目录。其英语全称是change directory
      5.2. ls 用于列出目录(文件夹)下包含的内容。其英语全称是 list directory content
    ls     # 仅显示【非隐藏】文件或文件夹的名称
    ls -l  # 显示【非隐藏】文件或文件夹详细的信息
    ls -l -h # 显示【非隐藏】文件或文件夹的详细信息,文件大小是人类可读的
    ls -lh # 与上面的命令相同
    ls -lh ./test.txt #仅显示 test.txt的信息
    

    3.2 输入和输出的概念

    这里讲输入和输出的概念,因为下面的指令需要用到。
    输入输出,在计算机中是一组配对的概念,一般叫做IO(Input Output);input即输入,output即输出
    输入: 可以简单的理解为,从键盘敲进去的。以一个软件程序为主体去理解,比如自己就是一个程序,自己揣到兜里的,都是自己的输入。一个软件程序,它从文件里读到的内容、从键盘里接收到的内容,都是输入。
    输出: 可以简单的理解为在输入完命令,按下Enter后,shell显示出来的内容。以一个软件程序为主体去理解,自己从兜里掏出来给别人的,都是输出。一个软件程序,它显示到屏幕上的结果,存放到文件中的,都是输出。

    四 命令的高级操作

    4.1 重定向

    重定向,可以想象河流,自东向西的河流,中间挡了太行山脉,就要改变流动方向,这就是重定向。
    在系统中,一系列的输入、输出,构成了信息流,每个应用程序,都可以对信息流的方向产生影响,比如本来是要输出到屏幕上显示的信息,经过应用"A"后,变成了保存到某个文件中,"A"就对这个信息流进行了重定向。

    4.1.1 cat 指令简介

    cat指令,英文全称为concatenate,意思为“连接”。用于连接文件,并输出到标准设备(屏幕)上。
    cat [参数] filename

    cat cat_txt.txt test.txt #会把这两个文件的内容都显示出来
    

    4.1.2 输出重定向

    将本来要显示在\color{red}{屏幕上}的内容,写入某个文件中,有四种

    序号 指令符号 描述
    1 > 写入文件并覆盖原来的内容
    2 >> 在文件末尾添加写入
    3 2> 将错误输出覆盖写入文件
    4 2>> 将错误输出增量写入文件

    > 为例,其前需要是一个可以执行的指令,这个指令的输出,会作为>的输入。后部为输出到的文件地址。
    比如echo a > ./test.txt:

    1. > 前部为 echo a,以a作为输出,如果单独执行echo a 则会在屏幕上显示出信息 a
      echo a
    2. 理解了上面的信息,在这条指令中,>的输入信息其实就是a
    3. >后部的 ./test.txt 是要输入的地址,是当前目录下的test.txt文件,也就是要把信息a 写入test.txt
    echo a > ./test.txt #在当前目录下创建一个test.txt,并写入内容a
    ls ./test.txt  # 输出test.txt的简要信息
    ls ./test.txt > ./ls_echo.txt # 把test.txt的简要信息写入ls_echo.txt,如果没有这个文件,会自动生成;如果有,则会覆盖原有内容
    cat ./ls_echo.txt # 输出ls_echo.txt里面的内容
    ls -lh ./test.txt > ./ls_echo.txt # 把test.txt的详细信息写入ls_echo.txt,会覆盖原有内容
    cat ./ls_echo.txt # 输出ls_echo.txt里面的内容
    ls -lh ./test.txt 2> ./ls_echo.txt # 因为目录下有test.txt文件,所以 ls -lh ./test.txt 不会产生错误信息,所以写入ls_echo.txt的是空白信息,ls_echo.txt被覆盖掉
    # 在确保当前目录下没有 test.none.txt文件的情况下,执行下面的语句
    ls test.none.txt #指令报错,无相关文件或目录
    ls test.none.txt 2> ./ls_echo.txt # 错误信息会写入并覆盖ls_echo.txt文件的原始信息
    cat ./ls_echo.txt # 显示的是之前的错误信息
    ls test.none.txt 2>> ./ls_echo.txt # 错误信息会增量写入ls_echo.txt文件
    cat ./ls_echo.txt # 显示两条错误信息
    
    # 对cat重定向
    cat > cat_file.txt # 此命令,cat后面没有接文件,则代表要从标准输入(键盘)上读取输入,然后覆盖写入到cat_file.txt。此命令需要Ctrl+D来结束
    

    4.1.3 输入重定向

    输入重定向,是把文件输入到命令中,可以想象为读取文件,有两个

    序号 指令符号 描述
    1 < 把文件输入到命令中
    2 << 从标准输入中读取,直到遇到分界符
    cat > cat_file.txt < ./ls_echo.txt #本来是以键盘作为输入,通过<符号,将输入重定向为ls_echo.txt
    cat cat_file.txt #查看cat_file中的内容,与ls_echo相同
    
    cat > cat_file.txt << 'eof' #将键盘输入的东西,覆盖存入cat_file.txt,当键入eof并回车后,输入结束
    

    附:文档使用的指令整理

    # 将当前文件夹下的 jpeg结尾的文件,拉一个清单到上级目录的 list.txt文件中
    for filename in `ls *.jpeg`
    do
    echo $filename >> ../list.txt
    done
    
    # 查看环境变量
    env
    
    # 命令的语法
    ls     # 仅显示【非隐藏】文件或文件夹的名称
    ls -l  # 显示【非隐藏】文件或文件夹详细的信息
    ls -l -h # 显示【非隐藏】文件或文件夹的详细信息,文件大小是人类可读的
    ls -lh # 与上面的命令相同
    ls -lh ./test.txt #仅显示 test.txt的信息
    
    # cat 测试
    cat cat_txt.txt test.txt #会把这两个文件的内容都显示出来
    
    # 输出重定向测试
    echo a > ./test.txt #在当前目录下创建一个test.txt,并写入内容a
    ls ./test.txt  # 输出test.txt的简要信息
    ls ./test.txt > ./ls_echo.txt # 把test.txt的简要信息写入ls_echo.txt,如果没有这个文件,会自动生成;如果有,则会覆盖原有内容
    cat ./ls_echo.txt # 输出ls_echo.txt里面的内容
    ls -lh ./test.txt > ./ls_echo.txt # 把test.txt的详细信息写入ls_echo.txt,会覆盖原有内容
    cat ./ls_echo.txt # 输出ls_echo.txt里面的内容
    ls -lh ./test.txt 2> ./ls_echo.txt # 因为目录下有test.txt文件,所以 ls -lh ./test.txt 不会产生错误信息,所以写入ls_echo.txt的是空白信息,ls_echo.txt被覆盖掉
    # 在确保当前目录下没有 test.none.txt文件的情况下,执行下面的语句
    ls test.none.txt #指令报错,无相关文件或目录
    ls test.none.txt 2> ./ls_echo.txt # 错误信息会写入并覆盖ls_echo.txt文件的原始信息
    cat ./ls_echo.txt # 显示的是之前的错误信息
    ls test.none.txt 2>> ./ls_echo.txt # 错误信息会增量写入ls_echo.txt文件
    cat ./ls_echo.txt # 显示两条错误信息
    # 对cat重定向
    cat > cat_file.txt # 此命令,cat后面没有接文件,则代表要从标准输入(键盘)上读取输入,然后覆盖写入到cat_file.txt。此命令需要Ctrl+D来结束
    
    
    # 输入重定向
    cat > cat_file.txt < ./ls_echo.txt #本来是以键盘作为输入,通过<符号,将输入重定向为ls_echo.txt
    cat cat_file.txt #查看cat_file中的内容,与ls_echo相同
    
    cat > cat_file.txt << 'eof' #将键盘输入的东西,覆盖存入cat_file.txt,当键入eof并回车后,输入结束
    

    相关文章

      网友评论

          本文标题:Linux(一) shell基础 什么叫shell 为什么用sh

          本文链接:https://www.haomeiwen.com/subject/vhgomdtx.html