Zhonghui

每个不曾起舞的日子,都是对生命的辜负

User Tools

Site Tools


程序:shell:shell

Shell

「个人理解」:Shell就是我们平时用的“命令行”,它就是一个解释器,既然有一个解释器,那也就能当成一门变成语言,写代码(或者说脚本)来交给解释器运行(like Python)

Linux关系密切

关于系统命令Shell 语法
什么是系统命令?系统的指令,不管使用什么 Shell 都可以执行的命令
什么是和 Shell 相关的?(切换 Shell 会影响什么?)不同的 Shell 读取设定变量的语法、外观等都可能不同


Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。
Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。
Ken Thompson 的 sh 是第一种 Unix Shell,Windows Explorer 是一个典型的图形界面 Shell

Linux 的 Shell 种类众多,常见的有:

  • Bourne Shell(/usr/bin/sh或/bin/sh)
  • Bourne Again Shell(/bin/bash)(常用)
  • C Shell(/usr/bin/csh)
  • K Shell(/usr/bin/ksh)
  • Shell for Root(/sbin/sh)

Shell的种类(AI生成)

Q:有很多中shell的种类(sh,bash…),我怎么知道我的系统正在用的是哪一种呢?不同的shell之间有什么区别吗?

如何确认系统正在使用的 Shell 类型

你可以通过以下方法确认当前使用的 Shell:

  1. 检查当前 Shell 的类型: 输入以下命令:

    echo $0

    这会显示当前正在使用的 Shell 名称,如 bashzshsh

  2. 检查默认登录 Shell: 输入以下命令:

    echo $SHELL

    这会显示用户的默认 Shell 路径,例如 /bin/bash/bin/zsh

  3. 通过进程查看: 输入以下命令:

    ps -p $$

    这会显示当前进程的名称,通常是当前 Shell 的类型。

  4. 查看系统支持的 Shell: 查看系统上可用的 Shell 列表:

    cat /etc/shells

不同 Shell 的主要区别

不同的 Shell 提供了不同的功能特性和语法支持。以下是常见 Shell 的特点:

  1. sh (Bourne Shell):

    • 最早的 UNIX Shell,适用于脚本编写和基础操作。
    • 功能较为有限,不支持一些现代特性(如命令行补全、别名等)。
  2. bash (Bourne Again Shell):

    • 基于 sh 的改进版,最常见的 Linux 默认 Shell。
    • 支持丰富的功能,如命令历史、Tab 补全、数组、别名和脚本增强。
  3. zsh (Z Shell):

    • 功能强大的 Shell,受到很多开发者喜爱。
    • 提供丰富的定制化选项和插件,支持自动建议和语法高亮。
  4. csh (C Shell):(~/.cshrc)

    • 类似于 C 语言语法的 Shell,提供与编程语言风格一致的语法。
    • 使用较少,脚本编写略显复杂。
  5. tcsh(~/.tcshrc)

    • csh 的改进版本,提供了更好的用户交互功能。
    • 增加了命令行编辑和历史功能。
  6. ksh (Korn Shell):

    • 综合了 shcsh 的优点,适合脚本编写。
    • 支持更强大的编程特性,如联合数组和高级模式匹配。
  7. fish (Friendly Interactive Shell):

    • 新一代交互式 Shell,以用户友好为目标。
    • 提供简洁的语法、强大的自动补全和实时错误提示。

总结

  • 如果需要简单的脚本编写,shbash 是不错的选择。
  • 如果追求更多定制化功能和交互体验,可以选择 zshfish
  • 通过命令 echo $SHELLps -p $$ 能快速确定当前使用的 Shell 类型。

不同 Shell 的选择取决于你的需求和个人偏好,你可以尝试切换并探索其特性。

切换默认Shell

# It will prompt you to enter your password. Your default login shell is /bin/bash now.
# You must log out and log back in to see this change.
# 可能需要管理员权限
chsh -s /bin/bash

语法

常用语法

# 换行:使用空格 + 反斜线
[aduser@vm-stg-batch001 tracking]$ echo \
> $SHELL
/bin/bash
 
# 管道:使用竖线(|),将前面命令的输出作为输入传递给后面的命令
# 在类 Unix 的 Shell(bash、zsh、sh 等)里,`|` 叫“管道(pipe)”。
# 它把左边命令的标准输出(stdout)作为右边命令的标准输入(stdin),让多个小工具串起来处理数据。
cat insert_user_master_test.sql | bq query --use_legacy_sql=false
 
# 重定向
# 从文件读入(到stdin),再将结果(stdout)输出到文件
# 注意指定的是文件名,不是要输入的文本
./a.out < in.txt > out.txt
 
# 合并标准输出+错误输出(都写入到文件)
./a.out > full_log.txt 2>&1
 
# 三个标准“文件描述符”
# `0`:标准输入(stdin)
# `1`:标准输出(stdout)
# `2`:标准错误(stderr)
# `2>&1` 是 重定向(redirction) 的一种写法,读作“把文件描述符 2 指向 1”
 
# 格式化输出
printf
# 字符串处理相关
# `sed` 是流编辑器:按行读取输入,对匹配到的行执行“编辑命令”,再输出结果
sed / cut / tail / awk
# 过滤数据
grep
# JSON处理
jq
 
# 字符串可以使用两种引号
a='1'
b="2"
# 字符串可以直接相连进行拼接
c='1'"2"'3'
# 双引号内部的变量会展开,单引号内部不会
d="$a $b "'$c' # "1 2 $c"
 
# 导出(export)
# 只在当前 shell 里创建一个 shell 变量。子进程(你启动的程序)默认看不到它。
A="aaa"
# 把变量标记为环境变量,之后你在这个 shell 里启动的任何命令/进程都能从环境里继承到它。
export A="aaa"
# export A 会把已存在的 A 标记为导出;export A=aaa 是“赋值并导出”。

虽然Shell的种类有很多,但是大部分语法基本都是相同的,学习常用的bash基本就够用了

建议多用AI写,手写有点痛苦

进阶专题

默认是 bash 语法

脚本示例:备份

一个简单的自动备份脚本(Bash),代码来自:服务器配置

mail_gzher@wikihost-us:~/backup_script$ cat backup.sh 
backupExecTime=$(date +"%Y%m%d%H%M%S")
backupFilePath="/var/www/webdav/autobackup"
backupFileName="GcpBackup"
 
doDelete()
{
    cd ${backupFilePath}
 
    local -i count=0 # Integer
    for backup_file in $(ls -r *.zip); do
        if ((count < 5));
        then
            echo "Keep ${backup_file}"
        else
            echo "Delete ${backup_file}"
            rm ${backup_file}
        fi
 
        count=${count}+1
    done
}
 
doInit()
{
    doClean
 
    cd ${backupFilePath}
 
    mkdir ${backupFileName}
}
 
doCopy()
{
    cd ${backupFilePath}
    cd ./${backupFileName}
 
    echo "Copy ${1}"
    cp -r ${1} .
}
 
doZip()
{
    cd ${backupFilePath}
 
    echo "Start Zip"
    zip -rq ./${backupFileName}-${backupExecTime}.zip ./${backupFileName}
}
 
doChown()
{
    cd ${backupFilePath}
 
    chown mail_gzher:mail_gzher ./${backupFileName}-${backupExecTime}.zip
}
 
doClean()
{
    cd ${backupFilePath}
 
    echo "Start Clean"
    # Folder Exist
    if [ -d ${backupFileName} ]; # Keep the Space
    then
        rm -rf ${backupFileName}
    fi
}
 
doDelete
doInit
doCopy /var/www/DokuWikiStick/dokuwiki
# doCopy /var/www/webdav/data/Joplin
# doCopy /var/www/webdav/data/Notability
doCopy /var/www/webdav/data/BCKY
doZip
doChown
doClean
/var/www/DokuWikiStick/dokuwiki/data/pages/程序/shell/shell.txt · Last modified: 2025/11/12 05:26 by zhonghui