Shell 编程 ~ 从入门到入坑。

Shell 基础。



Shell 概述。
Shell 脚本的执行方式。
Bash 的基本功能。
Bash 的变量。
Bash 的运算符。
环境变量配置文件。

Shell 概述。

  • Shell 是一个命令行解释器,ta 为用户提供了一个向 Linux 内核发送请求以便运行程序的界面系统级程序,用户可以用 Shell 来启动、挂起、停止甚至是编写一些程序。

外层应用程序 —> Shell 命令解释器 —> 内核 —> 硬件。
内核只识别二进制(机器语言),我们输入的命令,如 ls,通过 Shell 翻译成机器语言,由内核按照我们的命令控制硬件,硬件将结果返回给内核,再由 Shell 把返回结果翻译成我们看得懂的信息交还给用户。
Windows 侦测鼠标点击 —> Windows 图形交互界面就是 Windows 的 Shell。

  • Shell 还是一个功能强大的编程语言,易编写,易调试,灵活性较强。Shell 是解释执行的脚本语言,在 Shell 中可以直接调用 Linux 系统命令。


Shell 的分类。

  • Bourne Shell:从 1979 起 Unix 就开始使用 Bourne Shell,Bourne Shell 的主文件名为 sh

  • C Shell:C Shell 主要在 BSD 版的 Unix 系统中使用,其语法和 C 语言相类似而得名。

Shell 的两种主要语法类型有 Bourne 和 C,这两种语法彼此不兼容。

  • Bourne 家庭主要包括:sh、 ksh、 Bash、 psh、 zsh。
  • C 家庭主要包括:csh、 tcsh。
    Linux 标准 Shell:Bash。
  • bash:bash 与 sh 兼容,现在使用的 Linux 就是使用 Bash 作为用户的基本 Shell。

  • Linux 支持的 Shell。

geek@geek-PC:~$ cat /etc/shells 
# /etc/shells: valid login shells
/bin/sh
/bin/bash
/usr/bin/bash
/bin/rbash
/usr/bin/rbash
/bin/dash
/usr/bin/dash

[root@localhost ~]# cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/bin/dash
  • 切换 Shell。
geek@geek-PC:~$ sh
$ ^C
$ exit
geek@geek-PC:~$ dash
$ 
  • nologin

普通用户:/bin/bash or /sbin/shutdown(具体用户 - 具体命令)。
伪用户:/sbin/nologin(不是用来执行命令的用户)。



Shell 脚本的执行方式。

[root@localhost geek]# echo "hello world!"
-bash: !": event not found
[root@localhost geek]# echo 'hello world!'
hello world!
  • echo 输出命令。

[root@localhost ~]# echo [选项] [输出内容]
-e —> 支持反斜线控制的字符转换。

[root@localhost ~]# echo -e "ab\bc"
ac
[root@localhost ~]# echo -e "a\tb\tc\nd\te\tf"
a	b	c
d	e	f

\0nnn —> 八进制 ASCII 码。
\xhh —> 十六进制 ASCII 码。

[root@localhost ~]# echo -e "\x61\t\x62\t\x63\n\x64\t\x65\t\x66"
a	b	c
d	e	f
[root@localhost ~]# echo -e "\e[1;31m abcd \e[0m"
 abcd 

\e[1; —> 开启颜色输出。
\e[0m —> 结束。

30m —> 黑色
31m —> 红色
32m —> 绿色
33m —> 黄色
34m —> 蓝色
35m —> 洋红
36m —> 青色
37m —> 白色



第一个脚本。
#! /bin/bash
#The first program.
# Author: Geek ~ Email: liyifan@lyfGeek.club

echo -e 'Geek, geek,!'
# 赋予执行权限,直接运行。
geek@geek-PC:~/Desktop/shell_geek$ ll
total 4
-rw-r--r-- 1 geek geek 102 Aug  5 21:28 hello.sh
geek@geek-PC:~/Desktop/shell_geek$ chmod +x hello.sh 
geek@geek-PC:~/Desktop/shell_geek$ ./hello.sh 
Geek, geek,!

# 通过 bash 调用执行脚本。可以不要执行权限。
geek@geek-PC:~/Desktop/shell_geek$ bash hello.sh 
Geek, geek,!

cat -A —> 查看文件所有内容,包括隐藏字符。
Linux 中的回车符 —> $
Windows 中的回车符 —> ^M$

geek@geek-PC:~/Desktop/shell_geek$ cat -A hello.sh 
#! /bin/bash$
#The first program.$
# Author: Geek ~ Email: liyifan@lyfGeek.club$
$
echo -e 'Geek, geek,!'$

dos2unix 文件名。
unix2dos



Bash 的基本功能。

历史命令与补全。
[root@localhost ~]# history [选项] [历史命令保存文件]
-c —> 清空历史命令。
-w —> 把缓存中的历史命令写入历史命令保存文件。默认:~/.bash_history。

命令在正常登录退出后才会(自动)写入 ~/.bash_history。
历史命令默认会保存 1000 条,可以在环境变量配置文件 /etc/profile 中进行修改。

[root@localhost ~]# vim /etc/profile
HISTSIZE=1000


历史命令的调用。

使用 箭头调用以前的历史命令。
使用 !n 重复执行第 n 条历史命令。
使用 !! 重复执行上一条命令。
使用 !字符串 重复执行最后一条以该字符串开头的命令。



命令与文件补全。

在 bash 中,命令与文件补全是在非常方便与常用的命令,我们只要在输入命令或文件时,按 Tab 键就会自动进行补全。



命令别名与常用快捷键。

[root@localhost ~]# alias 别名=‘原命令’
// 设定命令别名。
[root@localhost ~]# alias
// 查询命令别名。
[root@localhost ~]# alias
alias cp=‘cp -i’
alias l.=‘ls -d .* --color=auto’
alias ll=‘ls -l --color=auto’
alias ls=‘ls --color=auto’
alias mv=‘mv -i’
alias rm=‘rm -i’
alias which=‘alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde’

geek@geek-PC:~/Desktop/shell_geek$ alias
alias dir='dir --color=auto'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l='ls -CF'
alias la='ls -A'
alias ll='ls -l'
alias ls='ls --color=auto'
alias vdir='vdir --color=auto'



命令的执行顺序。

第一顺位执行用绝对路径或相对路径执行的命令。
第二顺位执行别名。
第三顺位执行 bash 的内部命令。
第四顺位执行按照 $PATH 环境变量定义的目录查找顺序找到的第一个命令。

[root@localhost ~]# $PATH
-bash: /usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin: No such file or directory
[root@localhost ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
[root@localhost ~]# whereis ls
ls: /bin/ls /usr/share/man/man1/ls.1.gz
[root@localhost ~]# whereis cd
cd: /usr/share/man/man1/cd.1.gz  # shell 自带命令。只有帮助文档。

用命令行定义的别名临时生效。—> 永久生效。—> 配置文件。

[root@localhost ~]# vi /root/.bashrc


删除别名。
[root@localhost ~]# unalias 别名


bash 常用快捷键。

  • Ctrl - A。
    —> 把光标移动到命令行的开头。如果我们输入的命令过长,想要把光标移动到命令行的开头时使用。

  • Ctrl - E。
    —> 把光标移动到命令行的结尾。

  • Ctrl - C。
    —> 强制终止当前的命令。

  • Ctrl - L。
    —> 清屏。相当于 clear 命令。

-Ctrl - U。
—> 删除或剪切光标之前的命令。我们输入了一行很长的命令,不用使用退格键一个一个字符的删除,使用这个命令会更加方便。

  • Ctrl - K。
    —> 删除或剪切光标后的内容。

  • Ctrl - Y。
    —> 粘贴 Ctrl - U 或 Ctrl - K 剪切的内容。

  • Ctrl - R。
    —> 在历史命令中搜索。按下 Ctrl - R 后,就会进入搜索页面,只要输入内容,就会在历史命令搜索。

  • Ctrl - D。
    —> 退出当前终端。

  • Ctrl - Z。
    —> 暂停。并放入后台。这个快捷键牵扯工作管理的内容,—— >系统管理章节。

  • Ctrl - S。
    —> 暂停屏幕输出。

  • Ctrl - Q。
    —> 恢复屏幕输出。



输入输出重定向。

  • 标准输入输出设备。
设备设备文件名文件描述符类型
键盘/dev/stdin0标准输入
显示器/dev/stdout1标准输出
显示器/dev/stderr2标准错误输出
输出重定向。

改变输出方向,屏幕 —> 文件。

类型符号作用
标准输出重定向命令 > 文件以覆盖的方式,把命令的正确输出输出到指定的文件或设备当中。
命令 >> 文件以追加的方式,把命令的正确输出输出到指定的文件或设备当中。
标准错误输出重定向错误命令 `2>` 文件以覆盖的方式,把命令的错误输出输出到指定的文件或设备当中。
错误命令 `2>>` 文件以追加的方式,把命令的错误输出输出到指定的文件或设备当中。
geek@geek-PC:~$ date
Mon Feb 24 12:57:02 CST 2020

如果用 >>command not found 不会写入文件。

[root@localhost geek]# lst >> error_test.txt
-bash: lst: command not found
[root@localhost geek]# cat error_test.txt 

geek@geek-PC:~/Desktop/shell_geek$ lsa 2>> error.txt
geek@geek-PC:~/Desktop/shell_geek$ ls
error.txt  hello.sh
geek@geek-PC:~/Desktop/shell_geek$ cat error.txt 
bash: lsa: command not found

正确输出和错误输出同时保存。

解释:2>&1 —> 先把错误输出保存在正确输出中。
再把正确输出和错误输出保存在文件中。

命令 > 文件 2>&1以覆盖的方式,把正确输出和错误输出都保存到同一个文件中。
命令 >> 文件 2>&1以追加的方式,把正确输出和错误输出都保存到同一个文件中。
命令 &> 文件以覆盖的方式,把正确输出和错误输出都保存到同一个文件中。
命令 &>> 文件以追加的方式,把正确输出和错误输出都保存到同一个文件中。
命令 >> ‘文件1’ 2 >> ‘文件2’把正确的输出追加到文件 1,把错误的输出追加到文件 2。
[root@localhost geek]# lsa >> true.txt 2>>false.txt
[root@localhost geek]# ls &> /dev/null
[root@localhost geek]# cat /dev/null
# Linux 垃圾箱。


输入重定向。

[root@localhost ~]# wc [选项] [文件名]
-c —> 统计字节数。
-w —> 统计单词数。
-l —> 统计行数。

wc


Ctrl - D。

命令 < 文件。 # 把文件作为命令的输入。

[root@localhost ~]# wc < anaconda-ks.cfg 
  31  115 1107

<< —> 统计两个符号之间的内容。

[root@localhost ~]# wc << geek
> hello
> world
> geek
 2  2 12


多命令顺序执行与管道。

  • 多命令执行顺序。

| 多命令执行符 | 格式 | 作用 |
|–|–|–|–|
| ; | 命令 1 ; 命令 2 | 多个命令顺序执行,命令之间没有任何逻辑联系。 |
| && | 命令 1 && 命令 2 | 逻辑与。



当命令 1 正确执行,命令 2 才会执行。



当命令 1 执行不正确,命令 2 不会执行。|
| || | 命令 1 || 命令 2 | 逻辑或。



当命令 1 执行不正确,命令 2 才会执行。



当命令 1 执行正确,命令 2 不会执行。|

: —> 用来简化操作。

[root@localhost ~]# dd if=输入文件 of=输出文件 bs=字节数 count=个数
选项。
 if=输入文件。—> 指定源文件或设备。
 of=输出文件。—> 指定目标文件或目标设备。
 bs=字节数。—> 指定一次输入/输出多少字节,即把多少字节看作一个数据块。
 count=个数。—> 指定输入/输出多少个数据块。

cp 命令只能复制文件。dd(磁盘复制、数据复制命令)可以复制特殊命令、特殊文件,复制分区甚至整个硬盘。不仅复制分区或硬盘中的数据,并且复制分区或硬盘的文件系统。(磁盘对拷命令)。

[root@localhost ~]# date; dd if=/dev/zero of=/root/testfile bs=1k count=100000; date

// 每次从 /dev/zero 复制 1k 数据到 /root/testfile,执行 100_000 次,并统计时间。

  • &&
[root@localhost ~]# ls && echo yes
anaconda-ks.cfg  geek  install.log  install.log.syslog
yes
[root@localhost ~]# ./configure && make && make install
  • ||
[root@localhost ~]# lsa || echo no 
no
[root@localhost ~]# 命令 && echo yes || echo no

&& 优先级高于 ||。



管道符~|

[root@localhost ~]# 命令 1 | 命令 2
// 命令 1 的正确输出作为命令 2 的操作对象。
颜色显示。

[root@localhost ~]# ll -a /etc/ | more

[root@localhost ~]# netstat -an | grep "ESTABLISHED"
tcp        0      0 192.168.223.129:22          192.168.223.1:39006         ESTABLISHED

[root@localhost ~]# grep [选项] “搜索内容” 文件名
选项。
-i。—> 忽略大小写。
-n。—> 输出行号。
-v。—> 反向查找。
–color=auto。—> 搜索出的关键字用颜色显示。



通配符与其他特殊符号。
通配符作用
?匹配一个任意字符。
  • | 匹配 0 个或多个任意字符,也就是可以匹配任何内容。
    [] | 匹配中括号中任意一个字符。eg. [abc] 代表一定匹配一个字符,或者是 a,或者是 b,或者是 c。
    [ - ] | 匹配中括号中任意一个字符,- 代表一个范围。eg. [a-z] 代表匹配一个小写字母。
    [^] | 逻辑非,表示匹配不是中括号内的一个字符。eg. [^0-9] 代表匹配一个不是数字的字符。
符号作用
‘’单引号,在单绰号中所有的特殊符号,eg. $ 和 `(反引号)都没有特殊含义。
“”双引号。在双绰号中特殊符号都没有特殊含义,但是 $(调用变量的值)、`(引用命令) 和 \(转义符) 是例外。拥有特殊含义。
``反引号。反引号中的内容是系统命令。在 Bash 中会优先执行 ta。
$()和反引号作用一样,用来引用系统命令。推荐使用,因为反引号容易看错。

| 在 Shell 脚本中,# 开头的行表示注释。

$ | 用于调用变量的值。eg. 调用变量 name 的值:$name。
\ | 转义符。跟在 \ 之后的符号将失去特殊含义,变为普通字符。eg. $ 将输出为 $ 符号,而不是当作变量引用。

geek@geek-PC:~$ name=geek
geek@geek-PC:~$ echo '$name'
$name
geek@geek-PC:~$ echo "$name"
geek
geek@geek-PC:~$ echo '$(date)'
$(date)
geek@geek-PC:~$ echo "$(date)"
Fri 07 Aug 2020 01:26:30 PM CST
geek@geek-PC:~$ echo date
date
geek@geek-PC:~$ echo geek
geek
geek@geek-PC:~$ echo name
name

geek@geek-PC:~$ abc=`date`
geek@geek-PC:~$ echo abc
abc
geek@geek-PC:~$ echo $abc
Fri 07 Aug 2020 01:29:06 PM CST


Bash 的变量。

变量是计算机内存的单元,其中存放的值可以改变。当 SheII 脚本需要保存一些信息时,如一个文件名或是一个数字,就把 ta 存放在一个变量中。每个变量有一个名字,所以很容易引用 ta。使用变量可以保存有用信息,使系统获知用户相关设置,变量也可以用于保存暂时信息。



用户自定义变量。
  • 变量设置规则。
  • 变量名称可以由字母、数字和下划线组成,但是不能以数字开头。如果变量名是 “2name”,则是错误的。
  • 在 Bash 中,变量的默认类型都是字符串型,如果要进行数值运算,则必须指定变量类型为数值型。
  • 变量用等号连接值,等号左右两侧不能有空格。
    变量的值如果有空格,需要使用单引号或双引号包括。
  • 在变量的值中,可以使用 “\” 转义符。
  • 如果需要增加变量的值,那么可以进行变量值的叠加。不过变量需要用双引号包含$变量名或用${变量名} 包含。
  • 如果是把命令的结果作为变量值赋予变量,则需要使用反引号或 $() 包含命令。
  • 环境变量名建议大写,便于区分。


  • 用户自定义变量。
  • 环境变量:这种变量中主要保存的是和系统操作环境相关的数据。
  • 位置参数变量:这种变量主要是用来向脚本当中传递参数或数据的,变量名不能自定义,变量作用是固定的。
  • 预定义变量:是 Bash 中己经定义好的变量,变量名不能自定义,变量作用也是固定的。
geek@geek-PC:~$ name="Yifan Li"
geek@geek-PC:~$ aa=123
geek@geek-PC:~$ aa="$aa"456
geek@geek-PC:~$ echo aa
aa
geek@geek-PC:~$ echo $aa
123456
geek@geek-PC:~$ aa=${aa}789
geek@geek-PC:~$ echo $aa
123456789
geek@geek-PC:~$ echo $name
Yifan Li

  • 变量调用。

echo $name

  • 变量查看。

set

  • 变量删除。

unset name



环境变量。

用户自定义变量只在当前的 SheII 中生效,而环境变量会在当前SheII 和这个 SheII 的所有子 SheII 当中生效。如果把环境变量写入相应的配置文件,那么这个环境变量就会在所有的 SheII 中生效。

  • 设置环境变量。

export 变量名=变量值

  • 查询变量。

env

  • 删除变量。

unset 变量名

geek@geek-PC:~$ pstree
systemd─┬─ModemManager───2*[{ModemManager}]
        ├─NetworkManager─┬─dhclient
        │                └─2*[{NetworkManager}]
        ├─VGAuthService
        ├─accounts-daemon───2*[{accounts-daemon}]
        ├─alsactl
        ├─avahi-daemon───avahi-daemon
        ├─avfsd───3*[{avfsd}]
        ├─bluetoothd
        ├─cron
        ├─cupsd
        ├─2*[dbus-daemon]
        ├─dde-clipboardlo───5*[{dde-clipboardlo}]
        ├─dde-file-manage───2*[{dde-file-manage}]
        ├─dde-system-daem─┬─rfkill
        │                 └─12*[{dde-system-daem}]
        ├─deepin-anything───deepin-anything───{deepin-anything}
        ├─deepin-sync-hel───4*[{deepin-sync-hel}]
        ├─deepin-wine───WeChat.exe───45*[{WeChat.exe}]
        ├─et───9*[{et}]
        ├─explorer.exe───3*[{explorer.exe}]
        ├─fcitx───{fcitx}
        ├─fcitx-dbus-watc
        ├─geoclue───2*[{geoclue}]
        ├─gnome-keyring-d─┬─ssh-agent
        │                 └─3*[{gnome-keyring-d}]
        ├─imwheel
        ├─lastore-daemon───9*[{lastore-daemon}]
        ├─lightdm─┬─Xorg───{Xorg}
        │         ├─lightdm─┬─startdde─┬─agent───2*[{agent}]
        │         │         │          ├─chromium─┬─chrome-sandbox───chromium───chromium─┬─5*[chromium───9*[{chromium}]]
        │         │         │          │          │                                      └─chromium───11*[{chromium}]
        │         │         │          │          ├─chromium─┬─chromium
        │         │         │          │          │          └─7*[{chromium}]
        │         │         │          │          ├─chromium───8*[{chromium}]
        │         │         │          │          └─26*[{chromium}]
        │         │         │          ├─dde-clipboard───5*[{dde-clipboard}]
        │         │         │          ├─dde-desktop───10*[{dde-desktop}]
        │         │         │          ├─dde-dock───9*[{dde-dock}]
        │         │         │          ├─dde-file-manage───10*[{dde-file-manage}]
        │         │         │          ├─dde-osd───8*[{dde-osd}]
        │         │         │          ├─dde-polkit-agen───5*[{dde-polkit-agen}]
        │         │         │          ├─dde-printer───6*[{dde-printer}]
        │         │         │          ├─dde-session-dae───22*[{dde-session-dae}]
        │         │         │          ├─deepin-deepinid───7*[{deepin-deepinid}]
        │         │         │          ├─kwin_no_scale───kwin_x11───10*[{kwin_x11}]
        │         │         │          ├─sh───default-termina─┬─deepin-terminal─┬─bash───bash───pstree
        │         │         │          │                      │                 └─2*[{deepin-terminal}]
        │         │         │          │                      └─7*[{default-termina}]

geek@geek-PC:~$ $PATH
bash: /usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/sbin:/usr/sbin: No such file or directory
  • PS1 ~ 定义系统提示符的变量。

\d ~ 显示日期,格式为“星期 月 日”。
\h ~ 显示简写主机名。如默认主机名"localhost"。
\t ~ 显示 24 小时制时间,格式为 “HH:MM:SS”。
\T ~ 显示 12 小时制时间,格式为 “HH:MM:SS”。
\A ~ 显示 24 小时制时间,格式为 “HH:MM”。
\u ~ 显示当前用户名。
\w ~ 显示当前所在目录的完整名称。
\W ~ 显示当前所在目录的最后一个目录。
# ~ 执行的第几个命令。
$ ~ 提示符。如果是 root 用户会显示提示符为 “#”,如果是普通用户会显示提示符为 “$”。

geek@geek-PC:~$ echo $PS1
\[\e]0;\u@\h: \w\a\]${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$


位置参数变量。
  • $n。
    n 为数字,$0 代表命令本身,$1 ~ $9 代表第一到第九个参数,十以上的参数代表需要用大括号包含,eg. ${10}。

  • $*
    这个变量代表命令行中所有的参数,$* 把所有的参数看成一个整体。

  • $@。
    这个变量也代表命令行中所有的参数,不过 $@ 把每个参数区分对待。

  • $#。
    这个变量代表命令行中所有参数的个数。

geek@geek-PC:~/Desktop/shell_geek$ cat args.sh 
#!/bin/bash

echo $0
echo $1
echo $2
echo $3

geek@geek-PC:~/Desktop/shell_geek$ bash args.sh 11 22 33
args.sh
11
22
33

geek@geek-PC:~/Desktop/shell_geek$ cat args_math.sh 
#!/bin/bash

num1=$1
num2=$2
sum=$(($num1 + $num2))

echo $sum
geek@geek-PC:~/Desktop/shell_geek$ bash args_math.sh 1 2
3

geek@geek-PC:~/Desktop/shell_geek$ cat args_num.sh 
#!/bin/bash

echo "total parameters: $#."

echo "The parameters are: $*."

echo "The parameters are: $@."
geek@geek-PC:~/Desktop/shell_geek$ bash args_num.sh a1 b1 c1 d1
total parameters: 4.
The parameters are: a1 b1 c1 d1.
The parameters are: a1 b1 c1 d1.


$* v.s. $@
geek@geek-PC:~/Desktop/shell_geek$ cat args_dif.sh 
#!/bin/bash

for i in "$*"
	do
		echo "The parameterrs: $i."
	done

x=1

for y in "$@"
	do 
		echo "The parameter - $x is: $y."
		x=$(($x + 1))
	done

geek@geek-PC:~/Desktop/shell_geek$ bash args_dif.sh a1 b1 c1 d1 e1
The parameterrs: a1 b1 c1 d1 e1.
The parameter - 1 is: a1.
The parameter - 2 is: b1.
The parameter - 3 is: c1.
The parameter - 4 is: d1.
The parameter - 5 is: e1.



预定义变量。
预定义变量作用
$?最后一次执行的命令的返回状态。0 ~ 上一个命令正确执行。非 0(具体是哪一个数字由命令本身决定)~ 上一个命令执行不正确。
$$当前进程的 PID。
$!后台运行的最后一个进程的进程号(PID)。
geek@geek-PC:~/Desktop/shell_geek$ ls
args_dif.sh  args_math.sh  args_num.sh  args.sh  error.txt  hello.sh
geek@geek-PC:~/Desktop/shell_geek$ echo $?
0
geek@geek-PC:~/Desktop/shell_geek$ lsa
bash: lsa: command not found
geek@geek-PC:~/Desktop/shell_geek$ echo $?
127
geek@geek-PC:~/Desktop/shell_geek$ ls a
ls: cannot access 'a': No such file or directory
geek@geek-PC:~/Desktop/shell_geek$ echo $?
2



接受键盘输入。

read [选项] [变量名]
 -p “提示信息”。 在等待 read 输入时,输出提示信息。
 -t 秒数。  read 命令会一直等待用户输入,使用此选项可以指定等待时间。
 -n 字符数。 read 命令只接受指定的字符数,就会执行。(不用按回车)。
 -s。  隐藏输入的数据。适用于机密信息的输入。

#!/bin/bash

# 提示“请输入姓名”并等待 30 秒,把用户的输入保存入变量 name 中。
read -t 30 -p "Please input your name: " name
echo "Name is $name."

read -s -t 30 -p "Please input your age: " age
# 隐私数据使用 -s。
echo "Age is $age."
echo -e "\n"

read -n 1 -t 30 -p "Please select your gender[M/F]: " gender
# 使用 "-n 1" 选项只接受一个输入字符就会执行(不用输回车)。
echo -e "\n"
echo "gender is $gender."


Bash 的运算符。

数值运算 & 运算符。
geek@geek-PC:~/Desktop/shell_geek$ aa=11
geek@geek-PC:~/Desktop/shell_geek$ bb=22
geek@geek-PC:~/Desktop/shell_geek$ cc=$aa+$bb
geek@geek-PC:~/Desktop/shell_geek$ echo $cc
11+22

declare 声明变量类型。

declare [+/-] [选项] 变量名
选项。
 -。 给变量设定类型属性。
 +。 取消变量的类型属性。
 -i。 将变量声明为整数型(integer)。
 -x。 将变量声明为环境变量。
 -p。 显示 / 指定变量的被声明的类型。

geek@geek-PC:~$ aa=11
geek@geek-PC:~$ bb=22
geek@geek-PC:~$ cc=$aa+$bb
geek@geek-PC:~$ echo $cc
11+22
geek@geek-PC:~$ declare -p aa
declare -- aa="11"
geek@geek-PC:~$ export aa
geek@geek-PC:~$ declare -p aa
declare -x aa="11"


数值运算 ~ 方法 1。
geek@geek-PC:~$ aa=11
geek@geek-PC:~$ bb=22
geek@geek-PC:~$ declare -i cc=$aa+$bb
geek@geek-PC:~$ echo cc
cc
geek@geek-PC:~$ echo $cc
33


数值运算 ~ 方法 2 ~ expr 或 let 数值运算工具。
geek@geek-PC:~$ aa=11
geek@geek-PC:~$ bb=22
geek@geek-PC:~$ dd=$(expr $aa+$bb)
geek@geek-PC:~$ echo dd
dd
geek@geek-PC:~$ echo $dd
11+22
geek@geek-PC:~$ dd=$(expr $aa + $bb)  # + 号左右必须有空格。
geek@geek-PC:~$ echo $dd
33



数值运算 ~ 方法 3 ~ $((运算式)) or $[运算式]。
geek@geek-PC:~$ aa=11
geek@geek-PC:~$ bb=22
geek@geek-PC:~$ ff=$(($aa+$bb))
geek@geek-PC:~$ gg=$[$aa+$bb]
geek@geek-PC:~$ echo $ff
33
geek@geek-PC:~$ echo $gg
33

geek@geek-PC:~$ gg=$(( (7+8)*6/3 ))
geek@geek-PC:~$ echo $gg
30



变量测试与内容替换。
变量置换方式变量 y 没有设置值变量 y 为空值变量 y 设置值
x=$ {y -新值}x = 新值x 为空x=$y
x=$ {y: -新值}x = 新值x = 新值x=$y
x=$ {y+新值}x 为空x = 新值x = 新值
x=$ {y: +新值}x 为空x 为空x = 新值
x=$ {y = 新值}x = 新值


y = 新值 | x 为空



y 值不变 | x=$y



y 值不变
x=$ {y := 新值} | x = 新值



y = 新值 | x = 新值



y = 新值 | x=$y



y 值不变
x=$ {y?新值} | 新值输出到标准错误输出(就是屏幕) | x 为空 | x= y x = y x= yx= {y:?新值} | 新值输出到标准错误输出(就是屏幕) | 新值输出到标准错误输出(就是屏幕) | x=$y



环境变量配置文件。

环境变量配置文件简介。

环境变量可以在一系列 Shell 中生效。本地变量只能在当前 Shell 文件中生效。
环境变量有系统默认变量。变量名称和作用固定,我们可以改变 ta 的值。
环境变量允许用户把自己定义的本地变量声明为环境变量。
环境变量配置文件:系统每次启动读取生效。(登录)

  • source 命令。

[root@localhost]# source 配置文件

[root@localhost]# . 配置文件 # . 就是 source。

环境变量配置文件中主要定义对系统的操作环境生效的系统默认环境变量,eg. PATH, HISTSIZE, PSI, HOSTNAME 等默认环境变量。

[root@localhost ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

geek@geek-PC:~$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/sbin:/usr/sbin

PATH="$PATH":/root	# 重启失效。
  • /etc/profile
  • /etc/profile.d/*.sh
  • ~/.bash_profile
  • ~/.bashrc
  • /etc/bashrc

/etc/* —> 对所有登录此 Linux 系统的用户都生效。



环境变量配置文件作用。

在这里插入图片描述
一般前面的配置文件会调用后面的配置文件。

[root@localhost ~]# cat ~/.bashrc 
# .bashrc

# User specific aliases and functions

alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'

# Source global definitions
if [ -f /etc/bashrc ]; then
	. /etc/bashrc
fi

后面的配置文件会覆盖前面的。

但这里使用 追加,在原来的 $PATH 基础上再增加。

PATH=$PATH:$HOME/bin

[root@localhost ~]# cat ~/.bash_profile 
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
	. ~/.bashrc
fi

# User specific environment and startup programs

PATH=$PATH:$HOME/bin

export PATH



注销时生效的环境变量配置文件(~/.bash_logout)。
历史命令文件(~/.bash_history)。
登录界面信息(本地登录)。
[root@localhost ~]# cat /etc/issue
CentOS release 6.10 (Final)
Kernel \r on an \m

转义符作用
\d显示当前系统日期
\s显示操作系统名称
\l显示登录的终端号,这个比较常用。
\m显示硬件体系结构,如 i386 、i686 等。
\n显示主机名。
\o显示域名。
\r显示内核版本。
\t显示当前系统时间。
\u显示当前登录用户的序列号。


登录界面信息(远程登录)。
[root@localhost ~]# vim /etc/ssh/sshd_config

# no default banner path
#Banner none

Banner /etc/issue.net


登录后的欢迎信息。(远程 + 本地)~ /etc/motd


正则。

正则 v.s. 通配符。

正则表达式用来在文件中匹配符合条件的字符串,正则是包含匹配。
grep、awk、sed 等命令可以支持正则表达式。

通配符用来匹配符合条件的文件名,通配符是完全匹配。ls 、find 、cp 这些命令不支持正则表达式,所以只能使用 Shell 自己
的通配符来进行匹配了。

元字符作用
  • | 前一个字符匹配 0 次或任意多次。
    . | 匹配除了换行符外任意一字符。
    ^ | 匹配行首。eg. ^hello 会匹配以hello 开头的行。
    $ | 匹配行尾。eg. $hello 会匹配以hello 结尾的行。
    [] | 匹配中括号中指定的任意一字符,只匹配一个字符。eg. [aeiou] 匹配任意一个元音字母,[0-9] 匹配任意一位数字,[a-z][0-9] 匹配小写字和一位数字构成的两位字符。
    [^] | 匹配除中括号的字符以外的任意一个字符。eg. [^0-9 ] 匹配任意一位非数字字符,[^a-z] 表示任意一位非小写字母。
    \ | 转义符。用于取消。将特殊符号的含义取消。
    {n} | 表示其前面的字符恰好出现 n 次。eg. [0-9]{4} 匹配 4 位数字,[1][3-8][0-9]{9} 匹配手机号码。
    {n, } | 表示其前面的字符出现不小于 n 次。eg. [0-9]{2,} 表示两位及以上的数字。
    {n,m} | 表示其前面的字符至少出现 n 次,最多出现 m 次。eg. [a-z]{6,8} 匹配 6 到 8 位的小写字母。

^$

匹配空白行。



字符截取命令。

字段提取命令 ~ cut。

cut [选项] 文件名
选项。
 -f 列号。  提取第几列。
 -d 分隔符。 按照指定分隔符分隔列。

geek@geek-PC:~/Desktop/shell_geek$ vim student.txt
geek@geek-PC:~/Desktop/shell_geek$ cat student.txt 
ID	name	gender	mark
1	Liming	M	86
2	sc	M	90
3	Geek	M	83
geek@geek-PC:~/Desktop/shell_geek$ cut -f 2 student.txt 
name
Liming
sc
Geek
geek@geek-PC:~/Desktop/shell_geek$ cut -f 2,4 student.txt 
name	mark
Liming	86
sc	90
Geek	83

  • -d。指定分隔符。
geek@geek-PC:~/Desktop/shell_geek$ cut -d ":" -f 1,3 /etc/passwd

geek@geek-PC:~/Desktop/shell_geek$ cat /etc/passwd | grep /bin/bash
root:x:0:0:root:/root:/bin/bash
geek:x:1000:1000::/home/geek:/bin/bash
geek@geek-PC:~/Desktop/shell_geek$ cat /etc/passwd | grep /bin/bash | grep -v root
geek:x:1000:1000::/home/geek:/bin/bash
geek@geek-PC:~/Desktop/shell_geek$ cat /etc/passwd | grep /bin/bash | grep -v root | cut -d ":" -f 1
geek

  • 分隔符不是制表符。
geek@geek-PC:~/Desktop/shell_geek$ df -h
Filesystem      Size  Used Avail Use% Mounted on
udev            1.9G     0  1.9G   0% /dev
tmpfs           392M  3.0M  389M   1% /run
/dev/sda5        15G  7.1G  7.0G  51% /
tmpfs           2.0G  116M  1.8G   6% /dev/shm
tmpfs           5.0M  4.0K  5.0M   1% /run/lock
tmpfs           2.0G     0  2.0G   0% /sys/fs/cgroup
/dev/sda3       9.8G  6.0G  3.3G  65% /recovery
/dev/sda1       1.5G  110M  1.3G   8% /boot
/dev/sda7        17G   12G  3.8G  76% /data
tmpfs           392M   64K  392M   1% /run/user/1000
geek@geek-PC:~/Desktop/shell_geek$ df -h | grep "sda5"
/dev/sda5        15G  7.1G  7.0G  51% /
geek@geek-PC:~/Desktop/shell_geek$ df -h | grep "sda5" | cut -f 5
/dev/sda5        15G  7.1G  7.0G  51% /

↓ ↓ ↓

awk。



printf。
  • printf ‘输出类型 输出格式’ 输出内容
    输出类型。
     %ns~输出字符串。n 是数字。指代输出几个字符。
     %ni~输出整数。n 是数字。指代输出几个数字。
     %m.nf~输出浮点数。m 和 n 是数字,指代输出的整数位数和小数位数。eg. 8.2f 代表共输出 8 位数,其中 2 位是小数,6 位是整数。
geek@geek-PC:~/Desktop/shell_geek$ printf %s 1 2 3 4 5 6
123456geek@geek-PC:~/Desktop/shell_geek$ printf %s %s %s 1 2 3 4 5 6
%s%s123456geek@geek-PC:~/Desktop/shell_geek$ printf '%s %s %s' 1 2 3 4 5 6
1 2 34 5 6geek@geek-PC:~/Desktop/shell_geek$ printf '%s %s %s\n' 1 2 3 4 5 6
1 2 3
4 5 6

  • 输出文件内容。
geek@geek-PC:~/Desktop/shell_geek$ printf '%s' student.txt 
student.txtgeek@geek-PC:~/Desktop/shell_geek$ cat student.txt | printf '%s'
geek@geek-PC:~/Desktop/shell_geek$ printf '%s' $(cat student.txt)
IDnamegendermark1LimingM862scM903GeekM83geek@geek-PC:~/Desktop/shell_geek$ 

在 awk 命令的输出中支持 print 和 printf 命令。

  • print。
    会在每个输出之后自动加一个换行符。(Linux 默认没有 print 命令)。
  • printf。
    标准格式输出命令,并不会自动加入换行符。如果需要换行,需要手工加入换行符。


awk。

awk ‘条件 1 {动作 1} 条件 2 {动作 2} …’ 文件名

  • 条件(Pattern)。
    一般使用关系表达式作为条件。
    x > 10 ~ 判断变量 x 是否大于 10。
    x >= 10
    x <= 10
  • 动作(Action)。
    格式化输出。
    流程控制语句。
geek@geek-PC:~/Desktop/shell_geek$ vim student.txt 
geek@geek-PC:~/Desktop/shell_geek$ cat student.txt 
ID	name	PHP	Linux	MySQL	average
1	Liming	82	95	86	87.66
2	sc		74	96	87	85.66
3	Geek	99	83	93	91.66

geek@geek-PC:~/Desktop/shell_geek$ awk '{printf $2 "\t" $6 "\n"}' student.txt 
name	average
Liming	87.66
sc	85.66
Geek	91.66

geek@geek-PC:~/Desktop/shell_geek$ df -h | awk '{print $1 "\t" $3}'
Filesystem	Used
udev	0
tmpfs	3.0M
/dev/sda5	7.1G
tmpfs	116M
tmpfs	4.0K
tmpfs	0
/dev/sda3	6.0G
/dev/sda1	110M
/dev/sda7	12G
tmpfs	72K

$ df -h | grep sda5 | awk ‘{print $5}’ | cut -d “%” -f 1
51

geek@geek-PC:~/Desktop/shell_geek$ awk 'BEGIN{print "start..."} {print $2 "\t $5"}' student.txt 
start...
name	 $5
Liming	 $5
sc	 $5
Geek	 $5

awk:先读入第一行数据,再执行。

geek@geek-PC:~/Desktop/shell_geek$ awk '{FS=":"} {print $1 "\t" $3}' /etc/passwd
root:x:0:0:root:/root:/bin/bash	
daemon	1
bin	2

BEGIN:读取数据之前。

geek@geek-PC:~/Desktop/shell_geek$ awk 'BEGIN{FS=":"} {print $1 "\t" $3}' /etc/passwd
root	0
daemon	1
bin	2

  • $ awk ‘BEGIN{FS=“:”}END{print “~~~”} {print $1 “\t” $3}’ /etc/passwd

geek@geek-PC:~/Desktop/shell_geek$ cat student.txt | grep -v name | awk '$6 >= 87 {printf $2 "\n"}'
Liming
Geek



sed。

sed 是一种几乎包括在所有 UNIX 平台的轻量级流编辑器。sed 主要是用来将数据进行选取、替换、删除、新增的命令。

(使用 vi,需要将命令结果先保存到文件,在进行修改)。

sed 直接使用管道符修改。

sed [选项] ‘[动作]’ 文件名
选项。
 -n。 一般 sed 命令会把所有数据都输出到屏幕。如果加入此选项,则只会把经过 sed 命令处理的行输出到屏幕。
 -e。 允许对输入数据应用多条 sed 命令编辑。
 -i。 用 sed 的修改结果直接修改读取数据的文件,而不是由屏幕输出。

  • 动作。

  • a\。
    追加,在当前行后添加一行或多行。添加多行时,除最后一行外,每行末尾需要用 \ 代表数据未完结。

  • c \。
    行替换,用 c 后面的字符串替换原数据行,替换多行时,除最后一行外,每行末尾需用 \ 代表数据未完结。

  • i \。
    插入,在当期行前插入一行或多行。插入多行时,除最后一行外,每行末尾需要用 \ 代表数据未完结。

  • d。
    删除。删除指定的行。

  • p。
    打印,输出指定的行。

  • s。
    字串替换。用一个字符串替换另外一个字符串。格式为 行范围s/旧字串/新字串/g(和 vim 中的替换格式类似)。

geek@geek-PC:~/Desktop/shell_geek$ sed '2p' student.txt 
ID	name	PHP	Linux	MySQL	average
1	Liming	82	95	86	87.66
1	Liming	82	95	86	87.66
2	sc	74	96	87	85.66
3	Geek	99	83	93	91.66

# 第二行输出了 2 遍。

geek@geek-PC:~/Desktop/shell_geek$ sed -n '2p' student.txt 
1	Liming	82	95	86	87.66
  • 删除第 2 到 3 行内容。但不会删除原文件内容。
geek@geek-PC:~/Desktop/shell_geek$ sed '2,2d' student.txt 
ID	name	PHP	Linux	MySQL	average
2	sc	74	96	87	85.66
3	Geek	99	83	93	91.66
geek@geek-PC:~/Desktop/shell_geek$ sed '2i hello \' student.txt 
ID	name	PHP	Linux	MySQL	average
hello 
1	Liming	82	95	86	87.66
2	sc	74	96	87	85.66
3	Geek	99	83	93	91.66
geek@geek-PC:~/Desktop/shell_geek$ sed '2i hello \
> world' student.txt
ID	name	PHP	Linux	MySQL	average
hello 
world
1	Liming	82	95	86	87.66
2	sc	74	96	87	85.66
3	Geek	99	83	93	91.66

geek@geek-PC:~/Desktop/shell_geek$ sed '3s/74/99/g' student.txt 
ID	name	PHP	Linux	MySQL	average
1	Liming	82	95	86	87.66
2	sc	99	96	87	85.66
3	Geek	99	83	93	91.66

# 修改源文件。
geek@geek-PC:~/Desktop/shell_geek$ sed -i '3s/74/99/g' student.txt 
geek@geek-PC:~/Desktop/shell_geek$ cat student.txt 
ID	name	PHP	Linux	MySQL	average
1	Liming	82	95	86	87.66
2	sc	99	96	87	85.66
3	Geek	99	83	93	91.66


字符处理命令。

sort [选项] 文件名
选项。
-f。 忽略大小写。
-n。 以数值型进行排序,默认使用字符串型排序。
-r。 反向排序。
-t。 指定分隔符,默认是分隔符是制表符。
-k n[,m]。 按照指定的字段范围排序。从第 n 字段开始,m 字段结束(默认到行尾)。

sort -t “:” -k 3,3 /etc/passd
指定分隔符是“:”,用第三个字段开头,第三个字段结尾排序。



条件判断。

测试选项作用
-b 文件判断该文件是否存在,并且是否为块设备文件(是块设备文件为真)。
-c 文件判断该文件是否存在,并且是否为字符设备文件(是字符设备文件为真)。
-d 文件判断该文件是否存在,并且是否为目录文件(是目录为真)。
-e 文件判断该文件是否存在(存在为真)。
-f 文件判断该文件是否存在,并且是否为普通文件(是普通文件为真)。
-L 文件判断该文件是否存在,并且是否为符号链接文件(是符号链接文件为真)。
-p 文件判断该文件是否存在,并且是否为管道文件(是管道文件为真)。
-s 文件判断该文件是否存在,并且是否为非空(非空为真)。
-S 文件判断该文件是否存在,并且是否为套接字文件(是套接字文件为真)。
geek@geek-PC:~/Desktop/shell_geek$ test -e student.txt 
geek@geek-PC:~/Desktop/shell_geek$ echo $?
0
geek@geek-PC:~/Desktop/shell_geek$ [-e student.txtabc]
bash: [-e: command not found
geek@geek-PC:~/Desktop/shell_geek$ [ -e student.txtabc ]
geek@geek-PC:~/Desktop/shell_geek$ echo $?
1

geek@geek-PC:~/Desktop/shell_geek$ [ -d /root ] && echo "yes" || echo "no"
yes

  • 按照文件权限进行判断。
测试选项作用
-r 文件判断该文件是否存在,并且是否该文件拥有读权限(有读权限为真)。
-w 文件判断文件是否存在,并且是否该文件拥有写权限(有写权限为真)。
-x 文件判断该文件是否存在,并且是否该文件拥有执行权限(有执行权限为真)。
-u 文件判断该文件是否存在,并且是否该文件拥有 SUID 权限(有 SUID 权限为真)。
-g 文件判断该文件是否存在,并且是否该文件拥有SGID 权限(有 SGID 权限为真)。
-k 文件判断该文件是否存在,并且是否该文件拥有SBit 权限(有 SBit 权限为真)。
  • 两个文件之前的比较。
选项作用。
文件1 -nt 文件2判断文件1 的修改时间否比文件2 的新。(如果新之前为真)。
文件1 -ot 文件2判断文件1 的修改时间是否比文件2 旧。(如果旧则为真)。
文件1 -ef 文件2判断文件1 是否和文件2 的 Inode 号一致,可以理解为两个文件是否为同一个文件。(用于判断硬链接是很好的方法)。
  • 两个整数之间的比较。
测试选项作用
整数1 -eq 整数2判断整数1 是否和整数2 相等(相等为真)。
整数1 -ne 整数判断整数1 是否和整数2 不相等(不相等为真)。2
整数1 -gt 整数2判断整数1 是否大于整数2 (大于为真)。
整数1 -lt 整数2判断整数1 是否小于整数2 (小于为真)。
整数1 -ge 整数2判断整数1 是否大于等于整数2 (大于等于为真)。
整数1 -le 整数2判断整数1 是否小于等于整数2 (小于等于为真)。
  • 字符串的比较。
测试选项作用
-z 字符串判断字符串是否为空(为空返回真)。
-n 字符串判断字符串是否为非空(非空返回真)。
字串1 == 字串2判断字符串1 是否和字符串2 相等(相等返回真)。
字串1 != 字串2判断字符串1 是否和字符串2 不相等(不相等返回真)。

[ -z “$name” ] && echo yes || echo no

  • 多重条件判断。
测试选项作用
判断1 -a 判断2逻辑与。判断1 和判断2 都成立,最终的结果才为真。
判断1 -o 判断2逻辑或。判断1 和判断2 有一个成立,最终的结果就为真。
! 判断。逻辑非。使原始的判断式取反。


流程控制。

if 语句。
单分支 if 条件语句。
if [ 条件判断式 ];then
	...
fi

~ or

if [ 条件判断式 ]
	then
		...
fi
  • eg. 判断分区使用率。
geek@geek-PC:~/Desktop/shell_geek$ cat fenqu.sh 
#!/bin/bash
# 统计根分区使用率。
# Author: Geek.

rate=$(df -h | grep /dev/sda3 | awk '{print $5}' | cut -d "%" -f1)

echo $rate

if [ $rate -ge 80 ]
then
	echo "Warning! /dev/sda3 is full,!"
fi
geek@geek-PC:~/Desktop/shell_geek$ bash fenqu.sh 
65


双分支 if 条件语句。
if [ 条件判断式 ]
	then
		条件成立时,。。。
	else
		条件不成立时,。。。
fi
  • eg. 备份 MySQL。
geek@geek-PC:~/Desktop/shell_geek$ vim mysql_bak.sh
geek@geek-PC:~/Desktop/shell_geek$ cat mysql_bak.sh
#!/bin/bash

# 备份 MySQL 数据库。
# Author: Geek

# 同步系统时间。
ntpdate asia.pool.ntp.org &> /dev/null
# 把系统时间按照“年月日”的格式赋值给变量 date。
date=$(date +%y%m%d)
# 统计 MySQL 数据库的大小,并把大小赋值给 size 变量。
size=$(du -sh /var/lib/mysql)

if [ -d /tmp/dbbak ]
then
	echo "Date: $date" > /tmp/dbbak/dbinfo.txt
	echo "data size: $size" >> /tmp/dbbak/dbinfo/txt
	cd /tmp/dbbak
	tar -zcf mysql-lib-$date.tar.gz /var/lib/mysql dbinfo.txt &>/dev/null
	rm -rf /tmp/dbbak/dbinfo.txt
else
	mkdir /tmp/dbbak
	echo "Date: $date" > /tmp/dbbak/dbinfo.txt
	echo "data size: $size" >> /tmp/dbbak/dbinfo/txt
	cd /tmp/dbbak
	tar -zcf mysql-lib-$date.tar.gz /var/lib/mysql dbinfo.txt &>/dev/null
	rm -rf /tmp/dbbak/dbinfo.txt
fi
  • 判断 Apache 服务。
geek@geek-PC:~/Desktop/shell_geek$ cat pio.sh 
#!/bin/bash

port=$(nmap -sT 192.168.142.161 | grep tcp | grep http | awk '{print $2}')

if [ "$port" == "open" ]
	then
		echo "$(date) httpd is ok!!" >> /tmp/http_acc.log
	else
		/etc/rc.d/init.d/httpd restart &> /dev/null
		echo "$(date) http reboot!!" >> /tmp/http_err.log
fi



case 语句。
case $变量名 in
	"值 1")
		如果变量的值等于值 1,则执行程序 1;;
	"值 2")
		如果变量的值等于值 2,则执行程序 2;;
	... 省略其他分支。
	*)
		如果变量的值不是以上的值,则执行此程序。
		;;
esac


for 循环。


while 循环。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lyfGeek

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值