Linux|Shell 编程~人入门到入坑。

Shell 基础。
文章目录

    • Shell 基础。
      • Shell 概述。
      • Shell 的分类。
      • Shell 脚本的执行方式。
          • 第一个脚本。
      • Bash 的基本功能。
          • 历史命令与补全。
            • 历史命令的调用。
            • 命令与文件补全。
          • 命令别名与常用快捷键。
          • 命令的执行顺序。
          • 删除别名。
      • bash 常用快捷键。
      • 输入输出重定向。
          • 输出重定向。
          • 输入重定向。
      • 多命令顺序执行与管道。
          • 管道符~`|`。
          • 通配符与其他特殊符号。
      • Bash 的变量。
          • 用户自定义变量。
          • 环境变量。
          • 位置参数变量。
          • `$*` v.s. `$@`。
          • 预定义变量。
            • 接受键盘输入。
      • Bash 的运算符。
          • 数值运算 & 运算符。
            • declare 声明变量类型。
          • 数值运算 ~ 方法 1。
          • 数值运算 ~ 方法 2 ~ expr 或 let 数值运算工具。
          • 数值运算 ~ 方法 3 ~ $((运算式)) or $[运算式]。
          • 变量测试与内容替换。
      • 环境变量配置文件。
            • 环境变量配置文件简介。
            • 环境变量配置文件作用。
          • 注销时生效的环境变量配置文件(~/.bash_logout)。
          • 历史命令文件(~/.bash_history)。
          • 登录界面信息(本地登录)。
          • 登录界面信息(远程登录)。
          • 登录后的欢迎信息。(远程 + 本地)~ `/etc/motd`。
      • 正则。
          • 正则 v.s. 通配符。
      • 字符截取命令。
          • 字段提取命令 ~ cut。
          • printf。
          • awk。
          • sed。
      • 字符处理命令。
      • 条件判断。
      • 流程控制。
          • if 语句。
            • 单分支 if 条件语句。
            • 双分支 if 条件语句。
          • case 语句。
          • for 循环。
          • while 循环。

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.clubecho -e 'Geek, geek,!'

# 赋予执行权限,直接运行。 geek@geek-PC:~/Desktop/shell_geek$ ll total 4 -rw-r--r-- 1 geek geek 102 Aug5 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/stdin 0 标准输入
显示器 /dev/stdout 1 标准输出
显示器 /dev/stderr 2 标准错误输出
输出重定向。 改变输出方向,屏幕 —> 文件。
类型 符号 作用
标准输出重定向 命令 > 文件 以覆盖的方式,把命令的正确输出输出到指定的文件或设备当中。
命令 >> 文件 以追加的方式,把命令的正确输出输出到指定的文件或设备当中。
标准错误输出重定向 错误命令 `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.txthello.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 31115 1107

<< —> 统计两个符号之间的内容。
[root@localhost ~]# wc << geek > hello > world > geek 22 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.cfggeekinstall.loginstall.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" tcp00 192.168.223.129:22192.168.223.1:39006ESTABLISHED

[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/bashecho $0 echo $1 echo $2 echo $3geek@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/bashnum1=$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/bashecho "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/bashfor i in "$*" do echo "The parameterrs: $i." donex=1for y in "$@" do echo "The parameter - $x is: $y." x=$(($x + 1)) donegeek@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.shargs_math.shargs_num.shargs.sherror.txthello.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=$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/bingeek@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 系统的用户都生效。

环境变量配置文件作用。 Linux|Shell 编程~人入门到入坑。
文章图片

一般前面的配置文件会调用后面的配置文件。
[root@localhost ~]# cat ~/.bashrc # .bashrc# User specific aliases and functionsalias 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 programsPATH=$PATH:$HOME/binexport 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 noneBanner /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 FilesystemSizeUsed Avail Use% Mounted on udev1.9G01.9G0% /dev tmpfs392M3.0M389M1% /run /dev/sda515G7.1G7.0G51% / tmpfs2.0G116M1.8G6% /dev/shm tmpfs5.0M4.0K5.0M1% /run/lock tmpfs2.0G02.0G0% /sys/fs/cgroup /dev/sda39.8G6.0G3.3G65% /recovery /dev/sda11.5G110M1.3G8% /boot /dev/sda717G12G3.8G76% /data tmpfs392M64K392M1% /run/user/1000 geek@geek-PC:~/Desktop/shell_geek$ df -h | grep "sda5" /dev/sda515G7.1G7.0G51% / geek@geek-PC:~/Desktop/shell_geek$ df -h | grep "sda5" | cut -f 5 /dev/sda515G7.1G7.0G51% /

↓ ↓ ↓
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 sc74 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.66geek@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 不相等(不相等返回真)。
【Linux|Shell 编程~人入门到入坑。】[ -z “$name” ] && echo yes || echo no
  • 多重条件判断。
测试选项 作用
判断1 -a 判断2 逻辑与。判断1 和判断2 都成立,最终的结果才为真。
判断1 -o 判断2 逻辑或。判断1 和判断2 有一个成立,最终的结果就为真。
! 判断。 逻辑非。使原始的判断式取反。

流程控制。
if 语句。 单分支 if 条件语句。
if [ 条件判断式 ]; then ... fi~ orif [ 条件判断式 ] 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 $rateif [ $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/bashport=$(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 循环。

    推荐阅读