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

2023-08-30  本文已影响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并回车后,输入结束
上一篇下一篇

猜你喜欢

热点阅读