Linux实战笔记(五) shell

大家好,我是半虹,这篇文章我们介绍一下 shell


1、Shell

Shell 通常泛指系统提供给用户的操作界面,是系统内核与用户之间的连接

Shell 这个名字其实还挺形象的,中文翻译是壳,什么的壳呢,自然是系统内核的壳

操作界面可以分为两种,分别是命令行接口 (CLI) 和图形用户接口 (GUI)

现在一般说的 Shell 通常都是指命令行接口 ,也可以理解成是终端

在 Linux 上的 Shell 种类很多,下面来介绍一些常见的:

  • Bourne Shell (sh):Unix 系统中最早的 Shell 之一 ,功能较为基础,用户交互较弱
  • Bourne Again Shell (bash):sh 的拓展,提供更多新特性,是大多数 Linux 默认的 Shell
  • Z Shell (zsh ):功能更强大但配置较复杂,搭配 oh-my-zsh 还是非常推荐的

下面这些命令可以用来查看和修改用户 Shell:

  • 查看所有可用 Shell
shell 复制代码
cat /etc/shells

# /bin/sh
# /bin/bash
# /bin/dash
  • 查看默认登录 Shell
shell 复制代码
cat /etc/passwd

# root:x:0:0:root:/root:/bin/bash
# ...
# ...
# 输出信息以 : 为分割,其中第一项为用户名,最后一项为该用户的默认登录 Shell
  • 修改默认登录 Shell
shell 复制代码
chsh

# Password: 
# Changing the login shell for <当前用户>
# Enter the new value, or press ENTER for the default
# 	Login Shell [/bin/bash]: 

2、配置文件

不同的 Shell 会有不同的配置文件,这些配置文件可以用来设置环境变量、定义别名等等

下面以 Ubuntu 18.04.6 系统下的 Bash 为例进行介绍:

文件路径 影响范围 一般作用 执行时机 修改后如何生效
/etc/profile 所有用户 完成系统级初始化任务 用户登陆 使用 source,或重新登录
/etc/bash.bashrc 所有用户 设置系统级自定义终端 打开终端 使用 source,或新开终端
~/.profile 当前用户 完成用户级初始化任务 用户登陆 使用 source,或重新登录
~/.bashrc 当前用户 设置用户级自定义终端 打开终端 使用 source,或新开终端

这四个配置文件有着密切关联,下面会从 login shell 和 non-login shell 的角度切入分析

login shell 意味着需要通过密码登录进入 shell,反之,non-login shell 则无需重复登录

无论我们通过图形化界面,还是通过命令行界面登录 shell ,这些都属于 login shell

而在登录后的图形化界面打开终端,或者通过 su 切换用户,这些则属于 non-login shell

login shell 配置文件读取流程如下:

  1. login 进程 调用 /etc/profile/etc/profile 调用 /etc/bash.bashrc

    shell 复制代码
    # /etc/profile
    # 包含调用 /etc/bash.bashrc 的关键代码
    
    if [ "${PS1-}" ]; then
      if [ "${BASH-}" ] && [ "$BASH" != "/bin/sh" ]; then
        # The file bash.bashrc already sets the default PS1.
        # PS1='\h:\w\$ '
        if [ -f /etc/bash.bashrc ]; then
          . /etc/bash.bashrc # 调用 /etc/bash.bashrc【关键代码】
        fi
      else
        if [ "`id -u`" -eq 0 ]; then
          PS1='# '
        else
          PS1='$ '
        fi
      fi
    fi
    
    if [ -d /etc/profile.d ]; then
      for i in /etc/profile.d/*.sh; do
        if [ -r $i ]; then
          . $i # 调用 /etc/profile.d/ 下的所有脚本
        fi
      done
      unset i
    fi
  2. login 进程 调用 ~/.profile~/.profile 调用 ~/.bashrc

    shell 复制代码
    # ~/.profile
    # 包含调用 ~/.bashrc 的关键代码
    
    # if running bash
    if [ -n "$BASH_VERSION" ]; then
        # include .bashrc if it exists
        if [ -f "$HOME/.bashrc" ]; then
            . "$HOME/.bashrc" # 调用 ~/.bashrc【关键代码】
        fi
    fi
    
    # set PATH so it includes user's private bin if it exists
    if [ -d "$HOME/bin" ] ; then
        PATH="$HOME/bin:$PATH" # 设置环境变量
    fi
    
    # set PATH so it includes user's private bin if it exists
    if [ -d "$HOME/.local/bin" ] ; then
        PATH="$HOME/.local/bin:$PATH" # 设置环境变量
    fi

non-login shell 配置文件读取流程如下:

  1. non-login 进程 调用 /etc/bash.bashrc

  2. non-login 进程 调用 ~/.bashrc

    关于 non-login shell 配置文件的读取,其实还有些微妙

    现在网上大多数博客的写法是 non-login shell 只会读取 ~/.bashrc

    但是经过测试后发现,/etc/bash.bashrc 也会被执行

    当然还有一部分博客,包括 ChatGPT 都说是因为 ~/.bashrc 调用的 /etc/bash.bashrc

    但是经过测试后发现,/etc/bash.bashrc 是在 ~/.bashrc 之前被执行的,这就不可能是调用了


    怎么测试的呢,也比较简单

    在 /etc/bash.bashrc 文件可执行的第一行和最后一行分别加上:
    echo "-> /etc/bash.bashrc start"
    echo "-> /etc/bash.bashrc end"

    在 ~/.bashrc 文件可执行的第一行和最后一行分别加上:
    echo "-> ~/.bashrc start"
    echo "-> ~/.bashrc end"

    然后登录 root 用户,再用 su username 切换回设置的用户,输出顺序如下:
    -> /etc/bash.bashrc start
    -> /etc/bash.bashrc end
    -> ~/.bashrc start
    -> ~/.bashrc end


    现在可以确定的一点是,至少在 Ubuntu 18.04.6 系统下,non-login shell 会执行 /etc/bash.bashrc 和 ~/.bashrc

    但是其中具体的细节目前还不是很清楚,如果有朋友对这块比较了解,还请不吝赐教!

说到这里,或许你就能理解为啥有时候使用 su 切换用户后,某些环境变量没有生效

因为这时候登录的是 non-login shell,不会执行 /etc/profile 以及 ~/.profile

如果有一些环境变量写在这两个文件,文件没有被执行,那么自然也就没有进行设置

其实, su 是能够以 login shell 的方式切换用户的

只需要加上 -l 参数即可,例如 su -l username

这时候就能读取完整配置,正确设置所有环境变量,这是一个常常被大家忽视的技巧

3、环境变量

在使用 Shell 的时候,一个最常见的需求就是为各种软件去设置环境变量

环境变量有很多,下面分类介绍下:

  • 配置系统信息,例如
    • PATH:指定可执行文件的搜索路径
    • LANG:设置默认语言环境
  • 定义用户环境,例如
    • PS1 :定制命令行提示符
    • HOME:指定用户的主目录
  • 控制应用行为,例如
    • NVM_ 开头的变量:定义 nvm 相关信息
    • CONDA_ 开头的变量:定义 conda 相关信息

一般来说,安装软件的时候会自动配置环境变量,如果没有,那就需要我们手动配置

下面就以配置可执行文件的搜索路径 PATH 为例来进行讲解,通常有两种不同的方式

  1. 临时生效:在当前终端配置,在当前终端生效
  2. 永久生效:在配置文件配置,对所有终端有效

(1)临时生效

查看所有环境变量:

shell 复制代码
env

输出指定环境变量:

shell 复制代码
echo $PATH

设置临时环境变量:

shell 复制代码
export PATH=$PATH:/new/path # 注意这里赋值 PATH 时,需要拼接上原来 PATH 的值

(2)永久生效

因为每次登录或者打开终端都会执行配置文件,所以写在其中的命令对所有终端生效

这样就能避免对每一个终端都要手动进行设置,达到永久有效的目的

对于用户级配置,一般都会写在 ~/.bashrc ,具体设置的步骤如下:

  1. 打开配置文件
shell 复制代码
vi ~/.bashrc
  1. 在文件的最后写入配置命令,保存并关闭文件
shell 复制代码
export PATH=$PATH:/new/path
  1. 激活配置文件
shell 复制代码
source ~/.bashrc

好啦,本文到此结束,感谢您的阅读!

如果你觉得这篇文章有需要修改完善的地方,欢迎在评论区留下你宝贵的意见或者建议

如果你觉得这篇文章还不错的话,欢迎点赞、收藏、关注,你的支持是对我最大的鼓励 (/ω\)

相关推荐
A小辣椒15 小时前
TShark:Wireshark CLI 功能
linux
A小辣椒19 小时前
TShark:基础知识
linux
AlfredZhao21 小时前
OCI 明明分配了 200G 系统盘,为什么 df 只看到 30G?
linux·oci
AlfredZhao1 天前
vi 删除指定范围的行,不用再反复按 dd
linux·vi
用户9718356334662 天前
银河麒麟 KY10 申威(SW64) 安装 nginx-1.16.1-2.p01.ky10.sw_64.rpm 详细步骤
linux
猪脚踏浪2 天前
linux 拷贝文件或目录到指定的位置
linux
摇滚侠2 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
bush42 天前
嵌入式linux学习记录十四、术语
linux·嵌入式
载数而行5202 天前
Linux 11 动态监控指令top
linux
不会C语言的男孩3 天前
Linux 系统编程 · 第 8 章:进程基础
linux·c语言