【Linux】【Shell】Shell 基础与变量

news2024/11/21 23:14:34

Shell 基础

  • Shell 基础
    • 查看可用的 Shell
    • 判断当前 Shell 类型
  • 变量
  • 环境变量
    • 查看环境变量
    • 临时环境变量
    • 永久环境变量
    • PATH 变量
  • 自定义变量
    • 特殊赋值(双引号、单引号、反撇号)
  • 预定义变量
  • bashrc


Shell 基础


Shell 是一个用 C 语言编写的程序,相当于是一个翻译,把我们在计算机上的操作或我们的命令,翻译为计算机可识别的二进制命令,传递给内核(Kernal),以便调用计算机硬件执行相关的操作;同时,计算机执行完命令后,再通过Shell翻译成自然语言,呈现在我们面前。

Linux 中的各种命令其实都是独立的应用程序,通过操作系统提供的接口和 Kernal 进行交互,从实现某种操作。

【具体内部和操作系统相关,这里不在过多说明。】

简单来说,Shell 就是一种命令行解释器,它接受用户输入的命令,并将其转换为操作系统可以执行的指令。它不仅仅是一个简单的命令行界面,还是一个功能强大的脚本编程环境,可以编写自动化任务和复杂的工作流程。

Shell是用户和Linux(或者更准确的说,是用户和Linux内核)之间的接口程序。你在提示符下输入的每个命令都由 Shell 先解释然后传给Linux内核。

Shell 是一个命令语言解释器(command-language interpreter)。拥有自己内建的 Shell 命令集。此外,Shell 也能被系统中其他有效的Linux 实用程序和应用程序(utilities and application programs)所调用。

不论何时你键入一个命令,它都被 Linux Shell 所解释。一些命令,比如打印当前工作目录命令(pwd),是包含在Linux bash 内部的(就象DOS的内部命令)。其他命令,比如拷贝命令(cp)和移动命令(rm),是存在于文件系统中某个目录下的单独的程序。而对用户来说,你不知道(或者可能不关心)一个命令是建立在 Shell 内部还是一个单独的程序,因为使用方法都是一样的。

一般情况下,Linux 中的命令的按照如下顺序执行:

  1. 以相对/绝对路径执行指令,例如“ /bin/ls ”或“ ./ls ”;
  2. alias 找到该指令来执行;
  3. 由 bash 内置的 (builtin) 指令来执行;
  4. 通过 $PATH 这个变量的顺序搜寻到的第一个指令来执行。

查看可用的 Shell


由于早年的 Unix 年代,发展者众,所以由于 Shell 依据发展者的不同就有许多的版本,如 Bourne SHell (sh) 、C SHell、K SHell、 TCSH 等。

每一种 Shell 都各有其特点了,大多数 Linux 使用的默认版本为 “ Bourne Again SHell (简称 BASH) ”,这个 Shell 是 Bourne Shell 的增强版本。

在 Linux 系统中,使用 cat /etc/shells 可以查看查看当前系统中可用的 Shell 。

在这里插入图片描述

不同类型的 Shell 的语法及其包含的命令会有一定的不同,除非有特别说明,否则后续使用的命令都是 BASH 中命令。

Tips:

第一个流行的 shell 是由 Steven Bourne 发展出来的,为了纪念他所以就称为 Bourne shell ,或直接简称为 sh !而后来另一个广为流传的 shell 是由柏克莱大学的 Bill Joy 设计依附于 BSD 版的 Unix 系统中的shell ,这个 Shell 的语法有点类似 C 语言,所以才得名为 C shell ,简称为 csh。


判断当前 Shell 类型


Linux 中判断当前 Shell 的类型的方法有很多,部分方法如下所述。

方法1:

通过环境变量 SHELL 来查看:

echo $SHELL

方法2:

在 Terminal 输入命令 ps,查看当前运行的 shell 是什么。如下图所示,有一个进程是 csh,说明当前 shell 的类型是 csh。

在这里插入图片描述


变量


变量是 bash 环境中非常重要的一个内容。

Linux 是多用户多任务的环境,每个人登陆系统都能取得一个 bash shell, 每个人都能够使用 bash 下达 mail 这个指令来收受“自
己”的邮件等等。问题是, bash 是如何得知你的邮件信箱是哪个文件? 这就需要“变量”的帮助。

变量,简单的说,就是让某一个特定字串代表不固定的内容。

我们每个帐号的邮件信箱默认是以 MAIL 这个变量来进行存取的, 当 dmtsai 这个使用者登陆时,他便会取得 MAIL 这个变量,而这个变量的内容其实就是 /var/spool/mail/dmtsai, 那如果 vbird 登陆呢?他取得的 MAIL 这个变量的内容其实就是/var/spool/mail/vbird 。 而我们使用信件读取指令 mail 来读取自己的邮件信箱时,该程序可以直接读取 MAIL 这个变量的内容, 就能够自动的分辨出信箱的归属。


在 Linux Shell 中,变量主要有两大类:环境(系统)变量用户定义变量

每种类型的变量依据作用域不同,又分为全局变量局部变量。全局变量作用在整个 Shell 会话及其子 Shell,局部变量作用在定义它们的进程及其子进程内。

环境变量属于全局变量,它在任何的 Shell 中都可以使用。


环境变量


Linux是一个多用户的操作系统。多用户意味着每个用户登录系统后,都有自己专用的运行环境。而这个环境是由一组变量所定义,这组变量被称为环境变量。用户可以对自己的环境变量进行修改以达到对环境的要求。

一些常用的环境变量及其作用:

  • HOME

    用户的主工作目录,即为用户登录到Linux系统中时的默认目录。

  • PATH

    PATH 变量用于设置可执行程序的默认搜索路径。

    当我们输入一个指令时,Shell 会先检查命令是否是系统内部命令,如果不是则会再去检查此命令是否是一个应用程序,Shell会试着从PATH指定的路径下寻找这些应用程序。

    PATH 变量中可以指定多条路径,不同的路径使用 : 进行区分。

    # echo $PATH
    /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
    

    在 IC 的环境下,如果安装了一些 EDA 工具,这些 EDA 工具的启动程序的所在的路径就要放到 PATH 中,这样才能在 Terminal 中使用 dc_shell, vcs, verdi 等直接启动 EDA 工具。

  • HISTSIZE

    保存历史命令的条数。我们输入的指令都会被系统保存下来,这个环境变量记录的就是保持指令的条数。一般为1000。

    历史命令是被保存在内存中的,当退出或者登录shell时,会自动保存或读取我们可以通过history命令来查看。可以使用符号!执行指定序号的历史命令。例如,要执行第2个历史命令,则输入!2

  • LOGNAME、USER、HOSTNAME

    登录名、用户名和主机名。

  • SHELL

    当前使用的默认 Shell 解释器的名称。

  • PS1

    BASH 解释器的提示符。

    在这里插入图片描述
    【C shell 中 PS1 对应的变量名称为 prompt】

    CentOS 默认的 PS1 为 [\u@\h \W]$,在终端对应的提示信息为:[dmtsai@study ~]$


查看环境变量


echo 命令可以显示某个具体的环境变量的值,可用于快速检查一个变量的修改是否生效。

在这里插入图片描述

env 显示当前 shell 环境下的所有环境变量及其值。

BASH 中不只有环境变量,还有一些与 BASH的操作接口有关的变量,以及用户自己定义的变量。set 会显示当前 shell 的所有变量。


临时环境变量


环境变量和用户自定义变量之间的差异主要是“该变量是否会被子程序所继续引用”。

当你登陆 Linux 并取得一个 bash 之后,你的 bash 就是一个独立的程序,这个程序的识别使用的是一个称为程序识别码,被称为 PID 的就是。 接下来你在这个 bash 下面所下达的任何指令都是由这个 bash 所衍生出来的,那些被下达的指令就被称为子程序。

使用 export 命令将一个自定义变量变成环境变量,从而可以让该变量的值继续存在于子程序。

该命令设定的环境变量仅在当前窗口生效,关闭窗口或新建其他窗口,无法查看到之前设置的临时环境变量

在这里插入图片描述

export 命令也可以临时设置改变环境变量的值,相当于是给变量一个新的值,然后把之前的值覆盖了。


永久环境变量


使用 export 命令指定的环境变量仅在当前 Shell 及其子 Shell 中生效,如果像让变量永久生效,可以将其放到环境变量配置文件中。

在 Linux 系统中,环境变量的全局配置文件为 /etc/profile,在此文件中定义的变量作用于所有用户。除此之外,每个用户还有自己的独立配置文件(~/.bash_profile, ~/.profile,~/.bashrc等)。在这些文件中设置好环境变量之后,重新登录或者使用 source 命令之后,变量才能生效。

  • /etc/profile

    用于设置系统级的环境变量和启动程序,在这个文件下配置会对所有用户生效。当用户第一次登录时,该文件被执行,并从/etc/profile.d目录的配置文件中搜集shell的设置.

    一般用户不会对环境变量的全局配置文件进行修改,主要是对用户个人的配置文件进行修改。

  • ~/.bash_profile & ~/.profile

    在登录 Shell 时加载的配置文件。当你通过图形界面登录、通过SSH远程连接到系统或通过终端登录时,这些文件中的设置就会生效。

    ~/.profile 作用于所有类型的 Shell,而 ~/.bash_profile 只作用于 BASH Shell。

  • .bashrc

    ~/.profile~/.bash_profile 文件只会在用户登录的时候读取一次,而.bashrc在每次打开新的终端窗口或标签时都会读取。

    .bashrc 仅作用于 BASH Shell,C Shell 中与之对应的文件是 .cshrc

    /etc/bashrc 中的配置作用于所有用户,而 ~/.bashrc 中的配置仅作用于当前用户。

    .bashrc文件会在 bash shell 调用另一个bash shell时读取,也就是在shell中再键入bash命令启动一个新shell时就会去读该文件。这样可有效分离登录和子shell所需的环境。但一般 来说都会在.bash_profile里调用.bashrc脚本以便统一配置用户环境。


PATH 变量


PATH 变量用于设置可执行程序的默认搜索路径。当仅指定文件名称来执行命令程序时,Linux 系统将在 PATH 变量指定的目录范围查找对应的可执行文件,如果找不到则会提示“command not found”。

示例:

[root@localhost ~]# test.sh
bash: test.sh: Command not found.
[root@localhost ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@localhost ~]# pwd
/root

由于 test.sh 不在 PATH 目录中,所以系统无法识别这个命令,需要使用绝对路径来执行该脚本。

将脚本目录加入 PATH

方法一:将脚本的目录临时加入 PATH

[root@localhost ~]# PATH="$PATH:/root"
[root@localhost ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/root
[root@localhost ~]# test.sh 
hello world

方法二:将你自己写的脚本放到 PATH 中的某一个目录

[root@localhost ~]# mv test.sh /usr/local/bin/
[root@localhost ~]# test.sh
hello world

自定义变量


在 Bash 中,定义变量非常简单,不像其他高级编程语言(如 C/C++、Java 等)那么复杂。在定义一个新变量时,一般不需要提前声明,只需直接指定变量名称并赋值即可。

格式

name=value

Notes

  • 变量名需以字母或下划线开头,名称中不能包含特殊字符。
  • 等号两边不能有空格。
  • 新定义的变量只在当前的 Shell 环境中有效,因此称为局部变量。当进入子程序或新的子 Shell 环境时,局部变量将无法再使用。

特殊赋值(双引号、单引号、反撇号)


双引号主要起界定字符串的作用,特别是当要赋值的内容中包含空格时,必须以双引号括起来。其他情况下双引号通常可以省略。

当要赋值的内容中包含 $、"、\ 等具有特殊含义的字符时,应使用单引号括起来。在单引号的范围内,将无法引用其他变量的值,任何字符均作为普通字符看待,输入什么就显示什么。

test=123
echo "$test"  # 输出:123
echo '$test'  # 输出:$test

反撇号主要用于命令替换,允许将执行某个命令的屏幕输出结果赋值给变量。反撇号括起来的范围内必须是能够执行的命令行,否则将会出错。

time=`date +%T`

使用反撇号难以在一行命令中实现嵌套命令替换操作,这时可以改用 $() 来代替反撇号操作,以解决嵌套的问题。

ls -lh `which useradd`
# or
rpm -qc $(rpm -qf $(which useradd))

预定义变量


预定义变量是由 Bash 程序预先定义好的一类特殊变量,用户只能使用预定义变量,而不能创建新的预定义变量,也不能直接为预定义变量赋值。预定义变量使用 $ 符号和另一个符号组合表示。

  • $#:表示命令行中位置参数的个数。
  • $*:表示所有位置参数的内容,这些内容当做一个整体。
  • $@:表示列出所有位置参数,但是是以单个的形式列出。
  • $?:表示前一条命令执行后的返回状态,返回值为 0 表示执行正确,返回任何非 0 值均表示执行出现异常。
  • $0:表示当前执行的脚本或程序的名称。
  • $$:表示返回当前进程的进程号。
  • $!:返回最后一个后台进程的进程号。

bashrc


作为配置文件,bashrc 等文件不只是用于设置变量,还可以用于配置其他内容。

bashrc 文件中,# 表示的是注释。

1. 配置别名,简化指令

当我们想把一些常用的指令以及相关指令参数,定制为更加精简的指令,就可以用 alias 为命令设置别名。

alias ll = "ls -lha"

2. 配置函数,定制指令过程

除了缩短命名,也可以用bash函数组合多个命令到一个操作,这些命令大多遵循以下语法。

# Syntax 1
function function_name {
    command1
    <^>command2</^>

# Syntax 2
function_name () {
	command_1
	command_2
}

# Syntax 3
function_name () { commmand1; command2; }

示例:

下面的命令组合了 mkdircd 命令,输入md folder_name会在你的工作目录创建一个名为"folder_name"的目录并且进入其中。

md () {
	mkdir -p $1
	cd $1
}
# or
md () { mkdir -p $1; cd $1;}

3. 设置变量

在原来PATH的后面继续添加了新的路径:

# Syntax 1
PATH=$PATH:new_path
export PATH
 
# Syntax 2
export PATH=$PATH:new_path

export 是让变量可以作用域子 Shell。

示例:

user@pc:~$ echo 'VAL_TS="hello, no export"' >> ~/.bashrc            #添加非export变量赋值到.bashrc
user@pc:~$ source ~/.bashrc                                         #使.bashrc生效
user@pc:~$ echo $VAL_TS                                             #输出变量 VAL_TS 值
#结果
hello, no export
 
user@pc:~$ echo 'echo "val is :" $VAL_TS' > test.sh                 #添加脚本语句到脚本 test.sh
user@pc:~$ ./test.sh                                                #执行脚本 test.sh
#结果
val is :                                                            #脚本中并没有变量值
 
user@pc:~$ echo 'export EX_VAL_TS="hello, export"' >> ~/.bashrc     #添加export变量赋值
user@pc:~$ source ~/.bashrc                                         #使.bashrc生效
user@pc:~$ echo $EX_VAL_TS                                          #输出变量 EX_VAL_TS 值
#结果
hello, export
 
user@pc:~$ echo 'echo "export val is :$EX_VAL_TS' >> test.sh        #添加脚本语句到脚本
user@pc:~$ ./test.sh                                                #执行脚本 test.sh
#结果
export val is :hello, export                                        #脚本中获取到了变量值

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2244942.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【SpringBoot】26 实体映射工具(MapStruct)

Gitee 仓库 https://gitee.com/Lin_DH/system 介绍 现状 为了让应用程序的代码更易于维护&#xff0c;通常会将项目进行分层。在《阿里巴巴 Java 开发手册》中&#xff0c;推荐分层如下图所示&#xff1a; 每层都有对应的领域模型&#xff0c;即不同类型的 Bean。 DO&…

理解和选择Vue的组件风格:组合式API与选项式API详解

目录 前言1. Vue 的两种组件风格概述1.1 选项式 API&#xff1a;直观且分块清晰1.2 组合式 API&#xff1a;灵活且逻辑集中 2. 深入理解组合式 API 的特点2.1 响应式变量与函数式编程2.2 逻辑组织更清晰2.3 更好的代码复用 3. 应用场景分析&#xff1a;如何选择 API 风格3.1 适…

Windows和mac OS共用VMware虚拟机

在Windows下使用VMware Workstation Pro创建的虚拟机&#xff0c;是以文件夹形式存储在硬盘中的&#xff0c;在mac OS中对应的虚拟机产品是VMware Fusion&#xff0c;那么在Windows下创建的虚拟机怎么在mac OS中使用呢&#xff1f; 在下图中我们可以看到&#xff0c;Windows 1…

【K8S系列】Kubernetes Pod节点ImagePullBackOff 状态及解决方案详解【已解决】

在 Kubernetes 中,当某个 Pod 的容器无法从指定的镜像仓库拉取镜像时,Pod 的状态会变为 ImagePullBackOff。这通常是因为指定的镜像不存在、镜像标签错误、认证失败或网络问题等原因。 以下是关于 ImagePullBackOff 的详细分析及解决方案。 1. ImagePullBackOff 状态分析 1.…

04 —— Webpack打包CSS代码

加载器css-loader &#xff1a;解析css代码 webpack 中文文档 | webpack中文文档 | webpack中文网 加载器style-loader&#xff1a;把解析后的css代码插入到DOM style-loader | webpack 中文文档 | webpack中文文档 | webpack中文网 准备css代码&#xff0c;放到src/login目…

单元测试框架gtest学习(二)—— 认识断言

前言 我们在上一篇文章中&#xff0c;简要介绍了gtest是如何使用的 单元测试框架gtest学习&#xff08;一&#xff09;——初始gtest-CSDN博客 这篇文章我们主要总结gtest中的所有断言相关的宏。首先需要明确的是&#xff0c;gtest是通过各种断言宏进行测试的&#xff0c;而这…

网安瞭望台第2期:零日漏洞密集爆发、2024年常见网络安全漏洞类型及分析

国内外要闻 Ubuntu 服务器 Needrestart 软件包惊现严重安全漏洞 近日&#xff0c;Ubuntu 服务器&#xff08;自 21.04 版本起默认安装&#xff09;的 Needrestart 软件包被曝存在多个可追溯至数十年前的安全漏洞。这些漏洞允许本地攻击者在无需用户交互的情况下获取根…

PDF内容提取,MinerU使用

准备环境 # python 3.10 python3 -m pip install huggingface_hub python3 -m pip install modelscope python3 -m pip install -U magic-pdf[full] --extra-index-url https://wheels.myhloli.com下载需要的模型 import json import osimport requests from huggingface_hub…

【TDOA最小二乘解算】两步最小二乘迭代的TDOA解算方法,适用于二维平面、自适应锚点(附MATLAB代码)

本文所述的MATLAB代码实现了一个基于两步加权最小二乘法的二维目标定位算法&#xff0c;利用多个锚点&#xff08;基站&#xff09;和时间差到达&#xff08;TDOA&#xff09;数据来估计未知目标的位置。 文章目录 运行结果代码代码功能概述代码结构和详细说明初始化部分参数和…

Comfy UI 工作流(三)高清修复 - 低显存放大

前面提到的几种高清修复、高清放大都会占用&#xff0c;较多的现存。 和 Sd Web UI 中的 SD Upscale 放大一样&#xff0c;Comfy UI 中也提供有类似的自定义节点&#xff0c;通过分块的方式进行图片放大&#xff0c;从而减少现、显存的占用&#xff0c;该方式也经常用于 Com…

形态学图像处理(Morphological Image Processing)

形态学图像处理(Morphological Image Processing) 前言 ‍ 本博客为个人总结数字图像处理一课所写&#xff0c;并给出适当的扩展和相应的demo。 写博客跟做 checkpoint​ 很像&#xff0c;毕竟个人还不能达到那种信手拈来的境界&#xff0c;忘了就是从零开始训练&#xff0…

数据库迁移--laravel进阶篇

本地开发中的数据库和线上发布的数据库是不一样的,每进行一个线上版本的更新,很可能也涉及大量数据库的改动,那么这些数据库的改动在laravel中可以使用数据库迁移来处理。 比如我想创建一张flights数据表 执行php artisan make:migration create_flights_table命令就能自动生…

正则表达式完全指南,总结全面通俗易懂

目录 元字符 连接符 限定符 定位符 修饰符&#xff08;标记&#xff09; 运算符优先级 普通字符集及其替换 零宽断言 正向先行断言 负向先行断言 正向后发断言 负向后发断言 捕获组 普通捕获组 命名捕获组 PS:非捕获组 正则表达式在线测试: 正则在线测试工具 …

vulfocus在线靶场:CVE-2018-7600 速通手册

目录 一、启动环境&#xff0c;访问页面&#xff0c;语言选择中文&#xff0c;打开phpmyadmin 二、phpmyadmin中打开小房子 三、选择显示php信息 四、ctrlF&#xff0c;搜索flag&#xff0c;复制粘贴到任务中&#xff0c;通关 一、启动环境&#xff0c;访问页面&#xff0c;…

springboot实战(13)(@PatchMapping、@RequestParam、@URL、ThreadLocal线程局部变量)

目录 一、PATCH请求方式。 二、实现用户更新头像功能。 三、注解RequestParam。 四、注解URL。&#xff08;对传来的参数是否是合法地址进行校验&#xff09; 一、PATCH请求方式。 patch中文翻译&#xff1a;局部、小块。PATCH 请求主要用于对已存在的资源进行局部修改&#xf…

记录下,用油猴Tampermonkey监听所有请求,绕过seesion

油猴Tampermonkey监听所有请求&#xff0c;绕过seesion 前因后果脚本编写 前因后果 原因是要白嫖一个网站的接口&#xff0c;这个接口的页面入口被隐藏掉了&#xff0c;不能通过页面调用&#xff0c;幸好之前有想过逆向破解通过账号密码模拟登录后拿到token&#xff0c;请求该…

Spring Cloud Hystrix 豪猪哥 服务容错与保护组件

Spring Cloud Hystrix 豪猪哥 服务容错与保护组件 一、Spring Cloud Hystrix概述1.简介2.核心功能3.雪崩效应 二、Hystrix服务降级1.服务降级简介2.样例准备3.服务提供者降级4.服务消费者降级5.全局降级方法6.对API接口降级方法 三、Hystrix服务熔断1.服务熔断机制简介2.熔断工…

Facebook商城号封号的原因是什么?

Facebook商城作为一个重要的销售平台&#xff0c;不仅为商家提供了巨大的市场机会&#xff0c;也带来了一系列需要警惕的风险&#xff0c;其中包括账号被封的风险。本文将从环境异常、频繁操作和违规行为三个主要方面深入探讨&#xff0c;解析导致Facebook商城账号被封禁的具体…

Android okhttp 网络链接各阶段监控

步骤 1: 添加依赖 在项目的 build.gradle 文件中&#xff0c;添加 OkHttp 依赖&#xff1a; implementation com.squareup.okhttp3:okhttp:4.11.0 步骤 2: 创建自定义的 EventListener 创建一个自定义的 EventListener 类&#xff1a; import android.util.Log import okht…

MyBatis——#{} 和 ${} 的区别和动态 SQL

1. #{} 和 ${} 的区别 为了方便&#xff0c;接下来使用注解方式来演示&#xff1a; #{} 的 SQL 语句中的参数是用过 ? 来起到类似于占位符的作用&#xff0c;而 ${} 是直接进行参数替换&#xff0c;这种直接替换的即时 SQL 就可能会出现一个问题 当传入一个字符串时&#xff…