• bash 教程 shell 基础语法


    博文地址

    我的GitHub 我的博客 我的微信 我的邮箱
    baiqiantao baiqiantao bqt20094 baiqiantao@sina.com

    目录

    Bash 教程

    本文改编自 网道的 Bash 教程,主要为了精简大量本人不感兴趣的内容。

    Bash & Shell 简介

    Bash 是 Unix 系统和 Linux 系统的一种 Shell(命令行环境),是目前绝大多数 Linux 发行版的默认 Shell。

    Shell 的原意是 外壳,跟 kernel(内核)相对应。

    Shell 提供了一个与用户对话的命令行环境(command line interface,CLI),通过 CLI 将用户从键盘输入的命令送入操作系统执行,并将结果返回给用户。

    Shell 有很多种,只要能给用户提供命令行环境的程序,都可以看作是 Shell。

    wsl             # 启动后显示的【bqt@BQT-X】代表【user@host】,【$】代表普通用户,【#】代表 root 用户
    uname -a        # 显示电脑以及操作系统的相关信息【Linux BQT-X 4.19.128... GNU/Linux】
    
    echo $SHELL     # 【/bin/bash】,查看当前运行的 Shell
    cat /etc/shells # 查看当前的 Linux 系统安装的所有 Shell
    bash --version  # 【echo $BASH_VERSION】,查看本机的 Bash 版本
    
    bash            # 如果当前运行的 Shell 不是 Bash,可以输入 bash 命令启动 Bash
    exit            # 退出 Bash 环境
    

    快捷键

    • 命令自动补全:命令或路径输入到一半的时候,可以按下 Tab 键,Bash 会自动完成剩下的部分
    • 路径选择提示:按下 Tab 键后,如果有多个可能的选择,再按一次 Tab 键,Bash 会显示所有选项让你选择
    • Ctrl + L:将当前行移到页面顶部,并非清屏,通过滚轮可以查看滑出屏幕的内容
    • Ctrl + C:中止当前正在执行的命令
    • Ctrl + D:关闭 Shell 会话
    • ↑/↓:浏览已执行命令的历史记录
    • Shift + PgUp/PgDn:向上/下滚动---无效
    • Ctrl + U:删除光标前面容
    • Ctrl + K:删除光标后门的内容

    Bash 语法

    基本语法

    # 基本格式
    command [arg1...argN] # command 是具体的命令或者一个可执行文件
    echo foo  bar         # 【foo bar】,Bash 使用空格或 Tab 分割参数,多个连续的空格会被当做一个空格
    
    # 组合命令
    Command1; Command2    # 先执行 Command1,结束后再继续执行 Command2
    Command1 && Command2  # 先执行 Command1,如果 Command1 运行成功,则继续运行 Command2
    Command1 || Command2  # 先执行 Command1,如果 Command1 运行失败,则继续运行 Command2
    

    echo 命令

    echo 白 "白" '白'   # 【白 白 白】,字符串可以使用双引号、单引号包裹,也可以省略引号
    echo               # 【(换行)】,默认情况下,输出的文本末尾会有一个回车符
    echo -n a; echo b  # 【ab】,取消末尾的回车符
    

    type 命令

    # type 命令用来判断命令的来源(内置命令、外部程序)
    type echo     # 【echo is a shell builtin】,内置命令
    type ls       # 【ls is aliased to `ls --color=auto'】,别名
    type bash     # 【bash is /usr/bin/bash】,文件
    
    type -a echo  # 查看一个命令的所有定义
    type -t bash  # 【file】,返回一个命令的类型:alias,keyword,function,builtin,file
    

    Bash 变量

    Bash 变量分成环境变量和自定义变量两类。

    • 环境变量是 Bash 环境自带的变量,可以直接使用。通常是系统定义好的,也可以由用户从父 Shell 传入子 Shell。
    • 自定义变量是用户在当前 Shell 里面自己定义的变量,仅在当前 Shell 可用。
    set     # 显示所有变量(包括环境变量和自定义变量),以及所有的 Bash 函数
    

    环境变量

    很多环境变量很少发生变化,而且是只读的,可以视为常量。

    由于环境变量的变量名全部都是大写,所以传统上,如果用户要自己定义一个常量,也会使用全部大写的变量名。

    env           # 【printenv】,显示所有环境变量
    echo $PATH    # 【printenv PATH】,查看单个环境变量的值
    echo -e ${PATH//:/"\n"}  # 将环境变量 PATH 中的所有分隔符,由【:】替换成【\n】,并解释为换行符
    
    echo -e "$BASHPID \n$BASHOPTS \n$DISPLAY \n$EDITOR \n$HOME \n$HOST \n$IFS \n$LANG"
    echo -e "$PS1 \n$PS2 \n$PWD \n$RANDOM \n$SHELL \n$SHELLOPTS \n$TERM \n$UID \n$USER"
    

    常见的环境变量。

    • BASHPID:【104】Bash 进程的进程 ID
    • BASHOPTS:当前 Shell 的参数,可以用shopt命令修改
    • DISPLAY:图形环境的显示器名字,通常是:0,表示 X Server 的第一个显示器
    • EDITOR:默认的文本编辑器
    • HOME:【/home/bqt】用户的主目录
    • HOST:当前主机的名称。
    • IFS:词与词之间的分隔符,默认为空格
    • LANG:【C.UTF-8】字符集以及语言编码,比如zh_CN.UTF-8
    • PATH:由冒号分开的目录列表,当输入可执行程序名后,会搜索这个目录列表
    • PS1:Shell 提示符
    • PS2:【>】输入多行命令时,次要的 Shell 提示符
    • PWD:【/home/bqt】当前工作目录
    • RANDOM:【19211】返回一个0到32767之间的随机数
    • SHELL:【/bin/bash】Shell 的名字
    • SHELLOPTS:启动当前 Shell 的set命令的参数
    • TERM:【xterm-256color】终端类型名,即终端仿真器所用的协议
    • UID:【1000】当前用户的 ID 编号
    • USER:【bqt】当前用户的用户名

    定义变量

    • 变量名的规则和 Java 等编程语言一样
    • 变量名区分大小写
    • Bash 没有数据类型的概念,所有的变量值都是字符串
    • 注意,变量名和等号之间不能有空格
    var=value    # 变量名区分大小写,变量值都是字符串
    b="b qt"     # 如果变量值包含空格,必须放在引号里面
    e=$(pwd)     # 【e=`pwd`】变量值可以是命令的执行结果
    f=$((5*7))   # 变量值可以是数学运算的结果
    foo=1;bar=2  # 同一行定义多个变量,必须使用分号分隔
    
    for file in $(ls $(pwd)); do echo $file; done
    

    读取变量

    • 如果变量不存在,会输出空字符,而不会报错
    • 在变量名与其他字符连用的情况下,必须使用 花括号 包围的格式:${var}
    • 如果变量的值本身也是变量,必须在变量前面加 感叹号 才能读取最终的值:${!var}
    • 变量值包含连续空格、制表符、换行符时,直接读取时会被合并成一个空格;放在 双引号 里面能保持原来的格式
    echo $100.00   # 【00.00】Bash 将【$1】解释成了变量,该变量不存在,会输出空字符
    echo \$100.00  # 【$100.00】加反斜杠进行转义
    
    bqt=baiqiantao
    echo $bqt2022    # 【(空)】Bash 将其整个 bqt2022 解释为变量,而这个变量是不存在的
    echo ${bqt}2022  # 【baiqiantao2022】在变量名与其他字符连用的情况下,必须使用花括号包围
    
    var=USER
    echo $var     # 【USER】
    echo ${!var}  # 【bqt】如果变量的值本身也是变量,必须使用【${!var}】读取最终的值
    
    a="1 2   3"
    echo $a     # 【1 2 3】直接读取时,Shell 会将连续空格合并成一个
    echo "$a"   # 【1 2   3】放在双引号里面读取时,能保持原来的格式
    

    删除变量

    unset 命令用来删除一个变量,这个命令等价于将变量设成空字符串。

    这个命令不是很有用,因为不存在的 Bash 变量一律等于空字符串,所以即使用 unset 命令删除了变量,还是可以读取这个变量,值为空字符串。

    # 以下三种方式效果是一样的
    unset bqt
    bqt=''
    bqt=
    

    特殊变量 & 传递参数

    Bash 提供一些特殊变量。这些变量的值由 Shell 提供,用户不能进行赋值。

    • $0:当前 Shell 的名称(在命令行直接执行时),或者脚本文件名(在脚本中执行时)
    • $n:传递到脚本的第 n 个参数的值,建议使用 ${n} 来获取
    • $#:传递到脚本的参数数量
    • $*:显示所有向脚本或函数传递的参数,与$@基本相同,区别见下文
    • $@:显示所有向脚本或函数传递的参数,与$*基本相同,区别见下文
    • $?:上一个命令的退出码,返回 0 表示上一个命令执行成功;否则,表示上一个命令执行失败
    • $$:当前 Shell 的进程 ID,常用来辅助命名临时文件
    • $-:当前 Shell 的启动参数
    • $_:上一个命令的最后一个参数,不一定是用户输入的参数
    • $!:最近一个后台执行的异步命令的进程 ID,没有的话返回空
    # 调用格式【./test.sh 29 男】
    chmod 777 test.sh
    echo $0   #【./test.sh】脚本文件名
    echo $1   #【29】
    echo $2   #【男】
    
    echo $#   #【2】传递到脚本的参数数量
    echo $*   #【29 男】以一个字符串显示所有向脚本或函数传递的参数
    echo $@   #【29 男】
    
    echo $?   #【0】上一个命令的退出码
    echo $$   #【14372】当前 Shell 的进程 ID
    echo $-   #【hBH】当前 Shell 的启动参数
    echo $_   #【hBH】上一个命令的最后一个参数,不一定是用户输入的参数
    echo $!   #【】最近一个后台执行的异步命令的进程 ID
    

    $*$@ 的区别:在双引号中,$* 的作用是将所有参数当做一个参数

    # 【./test.sh 29 男 白乾涛】
    for i in $@;   do echo -n $i-; done;  # 【29-男-白乾涛】
    for i in $*;   do echo -n $i-; done;  # 【29-男-白乾涛】
    
    for i in "$@"; do echo -n $i-; done;  # 【29-男-白乾涛】
    for i in "$*"; do echo -n $i-; done;  # 【29 男 白乾涛】注意,这里是将所有参数当做一个参数
    
    for i in '$@'; do echo -n $i-; done;  # 【$@】
    for i in '$*'; do echo -n $i-; done;  # 【$*】
    

    变量未定义时的默认值

    • ${var:-word}:如果变量 var 存在且不为空,则返回它的值,否则返回 word
    • ${var:=word}:如果变量 var 存在且不为空,则返回它的值,否则将它设为 word,并且返回 word
    • ${var:+word}:如果变量 var 存在且不为空,则返回 word,否则返回空值,可用来测试变量是否存在
    • ${var:?info}:如果变量 var 存在且不为空,则返回它的值,否则中断脚本的执行,并打印 var: info
    echo ${abc:-"变量未定义"}  # 【变量未定义】
    echo ${abc:="baiqiantao"} # 【baiqiantao】
    echo ${bqt:+"变量已定义"}  # 【变量已定义】
    echo ${abc:?"变量未定义"}  # 【bash: abc: 变量未定义】变量未定义时就中断执行,并返回给定的报错信息
    echo ${abc:?}             # 【bash: abc: parameter null or not set】可以省略报错信息
    

    上面四种语法如果用在脚本中,变量名的部分可以用数字19,表示脚本的参数。

    声明输出变量 export

    • export 命令用来向子 Shell 输出变量。
    • 用户创建的变量仅可用于当前 Shell,使用 export 命令可以把变量传递给子 Shell
    • 通过 export 命令输出的变量,对于子 Shell 来说就是环境变量
    • 子 Shell 如果修改继承的变量,不会影响父 Shell
    bqt=baiqiantao
    export bqt       # 输出变量 bqt,执行后,当前 Shell 及随后新建的子 Shell,都可以读取变量 bqt
    export var=value # 给变量赋值并输出
    
    # 子 Shell 如果修改继承的变量,不会影响父 Shell
    bash             # 新建子 Shell
    echo $bqt        # 读取 $bqt
    bqt=baz          # 修改继承的变量
    exit             # 退出子 Shell
    echo $bqt        # 读取 $bqt
    

    声明只读变量 readonly

    声明只读变量,等同于 declare -r,声明后无法改变变量值,也不能 unset 变量

    readonly 命令有三个参数

    • -f:声明的变量为函数名
    • -p:打印出所有的只读变量
    • -a:声明的变量为数组

    声明时执行算术式 let

    使用 let 命令声明变量时,可以直接执行算术表达式。

    let a=1+2      # 使用 let 命令声明变量时,可以直接执行算术表达式
    let "b =1 +2"  # 参数表达式如果包含空格,需要使用引号
    echo $a $b     # 【3 3】
    
    let "v1 = 1" v2=v1++  # 可以同时对多个变量赋值,赋值表达式之间使用空格分隔
    echo $v1,$v2          # 【2,1】,v2=v1++ 的意思是:先返回 v1 的值,然后 v1 再自增
    

    声明特殊变量 declare

    declare 命令可以声明一些特殊类型的变量。declare 命令如果用在函数中,声明的变量只在函数内部有效,等同于 local 命令。

    • 声明整数变量 -i:声明后可以直接进行数学运算
    • 声明只读变量 -r:等同于 readonly 命令,声明后无法改变变量值,也不能 unset 变量
    • 声明大写字母 -u:声明后可以自动把变量值转成大写字母
    • 声明小写字母 -l:声明后可以自动把变量值转成小写字母
    • 输出变量信息 -p:输出已定义变量的值,未定义的变量会提示找不到;不带参数时输出所有变量的信息
    • 输出环境变量 -x:等同于 export 命令,可以将一个变量输出为子 Shell 的环境变量
    • 输出所有函数名 -F:不包含函数定义
    • 输出所有函数定义 -f:包含函数定义
    • 声明数组变量 -a
    # 声明整数变量
    declare -i a=2 b=5 # 声明整数变量,声明后可以直接进行数学运算
    declare -i c=a*b # 只要一个变量声明为整数,它的赋值就会自动解释为整数运算,这里 a、b 可不声明为整数变量
    echo $a*$b=$c    # 【2*5=10】
    c=bqt; echo $c   # 【0(不确定的值)】变量声明为整数以后,如果被改写为字符串,不会报错,但会赋以不确定的值
    
    # 声明只读变量
    declare -r r=1   # 声明只读变量,等同于 readonly 命令,声明后无法改变变量值,也不能 unset 变量
    r=2              # 【bash: r: readonly variable】报错,命令执行失败
    unset r          # 【bash: unset: r: cannot unset: readonly variable】
    
    # 声明大/小写
    declare -u u     # 声明大写字母,声明后可以自动把变量值转成大写字母
    u=bQt; echo $u   # 【BQT】
    declare -l l     # 声明小写字母,声明后可以自动把变量值转成小写字母
    l=bQt; echo $l   # 【bqt】
    
    # 输出变量信息
    p=bqt
    declare -p p     # 【declare -- p="bqt"】
    declare -p pp    # 【bash: declare: pp: not found】
    declare -p       # 输出所有变量的信息
    
    # 其他
    declare -x x     # 输出环境变量,等同于【export x】,可以将一个变量输出为子 Shell 的环境变量
    declare -F       # 输出当前环境的所有函数名,不包含函数定义
    declare -f       # 输出当前环境的所有函数,包括它的定义
    declare          # 等同于【set】命令,输出当前环境的所有变量以及函数
    

    2022-1-3

    本文来自博客园,作者:白乾涛,转载请注明原文链接:https://www.cnblogs.com/baiqiantao/p/15759764.html

  • 相关阅读:
    poj 3928 树状数组
    poj 2528 线段树+离散化
    poj 3468 成段增减
    hdu 2795 线段树(纵向)
    2016年江西理工大学C语言程序设计竞赛(高级组)
    2016年江西理工大学C语言程序设计竞赛(初级组)
    2015年江西理工大学C语言程序设计竞赛(高级组)
    江西理工大学南昌校区2016年新生赛
    2014江西理工大学C语言程序竞赛高级组
    2014江西理工大学C语言程序竞赛初级组
  • 原文地址:https://www.cnblogs.com/baiqiantao/p/15759764.html
Copyright © 2020-2023  润新知