赞
踩
当前 Linux 系统可用的 Shell 都记录在/etc/shells
文件中。/etc/shells
是一个纯文本文件
$ cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
/bin/tcsh
/bin/csh
在现代的 Linux 上,sh 已经被 bash 代替,/bin/sh
往往是指向/bin/bash
的符号链接
如果你希望查看当前 Linux 的默认 Shell,那么可以输出 SHELL 环境变量:
$ echo $SHELL
/bin/bash
对于普通用户,Base shell 默认的提示符是美元符号$
;对于超级用户(root 用户),Bash Shell 默认的提示符是井号#
。该符号表示 Shell 等待输入命令
Shell 通过PS1
和PS2
两个环境变量来控制提示符格式:
要显示提示符的当前格式,可以使用 echo 输出 PS1 和 PS2:
[mozhiyan@localhost ~]$ echo $PS1
[\u@\h \W]\$
[mozhiyan@localhost ~]$ echo $PS2
>
Shell 使用以\
为前导的特殊字符来表示命令提示符中包含的要素,这使得 PS1 和 PS2 的格式看起来可能有点奇怪。下表展示了可以在 PS1 和 PS2 中使用的特殊字符。
字符 | 描述 |
---|---|
\a | 铃声字符 |
\d | 格式为“日 月 年”的日期 |
\e | ASCII转义字符 |
\h | 本地主机名 |
\H | 完全合格的限定域主机名 |
\j | shell当前管理的作业数 |
\1 | shell终端设备名的基本名称 |
\n | ASCII换行字符 |
\r | ASCII回车 |
\s | shell的名称 |
\t | 格式为“小时:分钟:秒”的24小时制的当前时间 |
\T | 格式为“小时:分钟:秒”的12小时制的当前时间 |
@ | 格式为am/pm的12小时制的当前时间 |
\u | 当前用户的用户名 |
\v | bash shell的版本 |
\V | bash shell的发布级别 |
\w | 当前工作目录 |
\W | 当前工作目录的基本名称 |
! | 该命令的bash shell历史数 |
# | 该命令的命令数量 |
$ | 如果是普通用户,则为美元符号$ ;如果超级用户(root 用户),则为井号# 。 |
\nnn | 对应于八进制值 nnn 的字符 |
\ | 斜杠 |
[ | 控制码序列的开头 |
] | 控制码序列的结尾 |
注意,所有的特殊字符均以反斜杠\
开头,目的是与普通字符区分开来。您可以在命令提示符中使用以上任何特殊字符的组合。我们可以通过修改 PS1 变量来修改提示符格式,例如:
[mozhiyan@localhost ~]$ PS1="[\t][\u]\$ "[17:27:34][mozhiyan]$
新的 Shell 提示符现在可以显示当前的时间和用户名。不过这个新定义的 PS1 变量只在当前 Shell 会话期间有效,再次启动 Shell 时将重新使用默认的提示符格式
打开文本编辑器,新建一个文本文件,并命名为 test.sh。
扩展名
sh
代表 shell,扩展名并不影响脚本执行,见名知意就好,如果你用 php 写 shell 脚本,扩展名就用php
好了
在 test.sh 中输入代码:
#!/bin/bash
echo "Hello World !" #这是一条语句
第 1 行的#!
是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种Shell;后面的/bin/bash
就是指明了解释器的具体位置。
第 2 行的 echo 命令用于向标准输出文件(Standard Output,stdout,一般就是指终端)输出文本。在.sh
文件中使用命令与在终端直接输入命令的效果是一样的。
第 2 行的#
及其后面的内容是注释。Shell 脚本中所有以#
开头的都是注释(当然以#!
开头的除外)。写脚本的时候,多写注释是非常有必要的,以方便其他人能看懂你的脚本,也方便后期自己维护时看懂自己的脚本——实际上,即便是自己写的脚本,在经过一段时间后也很容易忘记。
下面给出了一段稍微复杂的 Shell 脚本:
#!/bin/bash
# Copyright (c) http://c.biancheng.net/shell/
echo "What is your name?"
read PERSON
echo "Hello, $PERSON"
第 5 行中表示从终端读取用户输入的数据,并赋值给 PERSON 变量。read 命令用来从标准输入文件(Standard Input,stdin,一般就是指终端)读取用户输入的数据。
第 6 行表示输出变量 PERSON 的内容。注意在变量名前边要加上$
,否则变量名会作为字符串的一部分处理。
Shell 脚本也是一种解释执行的程序,可以在终端直接调用(需要使用 chmod 命令给 Shell 脚本加上执行权限),如下所示:
$ cd demo #切换到 test.sh 所在的目录
$ chmod +x ./test.sh #使脚本具有执行权限
$ ./test.sh #执行脚本
第 2 行中,chmod +x
表示给 test.sh 增加执行权限。
第 3 行中,./
表示当前目录,整条命令的意思是执行当前目录下的 test.sh 脚本。如果不写./
,Linux会到系统路径(由 PATH 环境变量指定)下查找 test.sh,而系统路径下显然不存在这个脚本,所以会执行失败。
通过这种方式运行脚本,第一行一定要写对,好让系统查找到正确的解释器。
.
点号用于执行某个脚本,甚至脚本没有可执行权限也可以运行。有时候在测试运行某个脚本时可能并不想为此修改脚本权限,这时候就可以使用.
来运行脚本,非常方便。
如果没有运行权限的话,用./
执行就会有报错,但是若在其前面使用点号来执行就不会报错
$ . ./test.sh #注意 两个 . 之间有空格
与点号类似,source 命令也可读取并在当前环境中执行脚本,同时还可返回脚本中最后一个命令的返回状态;如果没有返回值则返回 0,代表执行成功;如果未找到指定的脚本则返回 false。
$ source test.sh
这种运行方式是,直接运行解释器,其参数就是 shell 脚本的文件名,如:
$ /bin/bash test.sh
http://c.biancheng.net/shell/
这种方式运行的脚本,不需要在第一行指定解释器信息,写了也没用
variable=value
variable='value'
variable="value"
注意,赋值号=
的周围不能有空格,这可能和你熟悉的大部分编程语言都不一样
' '
包围变量的值时,单引号里面是什么就输出什么,即使内容中有变量和命令(命令需要反引起来)也会把它们原样输出。这种方式比较适合定义显示纯字符串的情况,即不希望解析变量、命令等的场景。" "
包围变量的值时,输出时会先解析里面的变量和命令,而不是把双引号中的变量名和命令原样输出。这种方式比较适合字符串中附带有变量和命令并且想将其解析后再输出的变量定义。echo $variable
echo ${variable}
#下面这种情况,需要加{},否则解释器就会把 $skillScript 当成一个变量(其值为空)
echo "I am good at ${skill}Script"
加花括号是为了帮助解释器识别变量的边界,推荐给所有变量加上花括号{}
使用 readonly
命令可以将变量定义为只读变量,只读变量的值不能被改变
#!/bin/bash
myUrl="http://see.xidian.edu.cn/cpp/shell/"
readonly myUrl
#下面这一行会报错:zsh: read-only variable: myUrl
myUrl="http://see.xidian.edu.cn/cpp/danpianji/"
使用 unset
命令可以删除变量。语法:
unset variable_name
变量被删除后不能再次使用;unset 命令不能删除只读变量
一共三种作用域
所谓全局变量,就是指变量在当前的整个 Shell 会话中都有效。每个 Shell 会话都有自己的作用域,彼此之间互不影响。在 Shell 中定义的变量,默认就是全局变量
需要强调的是,全局变量的作用范围是当前的 Shell 会话,而不是当前的 Shell 脚本文件,它们是不同的概念。打开一个 Shell 窗口就创建了一个 Shell 会话,打开多个 Shell 窗口就创建了多个 Shell 会话,每个 Shell 会话都是独立的进程,拥有不同的进程 ID。在一个 Shell 会话中,可以执行多个 Shell 脚本文件,此时全局变量在这些脚本文件中都有效
Shell 也支持自定义函数,但是 Shell 函数和 C/C++、Java 等其他编程语言函数的一个不同点就是:在 Shell 函数中定义的变量默认也是全局变量,它和在函数外部定义变量拥有一样的效果
要想变量的作用域仅限于函数内部,那么可以在定义时加上local
命令,此时该变量就成了局部变量
#!/bin/bash
#定义函数
function func(){
local a=99
}
#调用函数
func
#输出函数内部的变量
echo $a
输出结果为空,表明变量 a 在函数外部无效,是一个局部变量。
Shell 变量的这个特性和 JavaScript 中的变量是类似的。在 JavaScript 函数内部定义的变量,默认也是全局变量,只有加上var
关键字,它才会变成局部变量
使用export
命令将它导出,它就在所有的子 Shell 中也有效了
环境变量被创建时所处的 Shell 被称为父 Shell,如果在父 Shell 中再创建一个 Shell,则该 Shell 被称作子 Shell。当子 Shell 产生时,它会继承父 Shell 的环境变量为自己所用,所以说环境变量可从父 Shell 传给子 Shell。不难理解,环境变量还可以传递给孙 Shell。
注意,环境变量只能向下传递而不能向上传递,即“传子不传父”。
在一个 Shell 中创建子 Shell 最简单的方式是运行 bash 命令
通过exit
命令可以一层一层地退出 Shell
export a
这种形式是在定义变量 a 以后再将它导出为环境变量,如果想在定义的同时导出为环境变量,可以写作export a=22
如果想让环境变量在所有 Shell 中都有效,并且能够永久保存,在关闭 Shell 后也不丢失,那么就需要把环境变量写入启动文件
运行 Shell 脚本文件时我们可以给它传递一些参数,这些参数在脚本文件内部可以使用$n
的形式来接收,例如,$1
表示第一个参数,$2
表示第二个参数,依次类推。
同样,在调用函数时也可以传递参数。Shell 函数参数的传递和其它编程语言不同,没有所谓的形参和实参,在定义函数时也不用指明参数的名字和数目。换句话说,定义 Shell 函数时不能带参数,但是在调用函数时却可以传递参数,这些传递进来的参数,在函数内部就也使用$n
的形式接收,例如,$1
表示第一个参数,$2
表示第二个参数,依次类推。
这种通过$n
的形式来接收的参数,在 Shell 中称为位置参数
#!/bin/bash
echo "Language: $1"
echo "URL: $2"
$ . ./a.sh Shell http://c.biancheng.net/shell/
#!/bin/bash
#定义函数
function func(){
echo "Language: $1"
echo "URL: $2"
}
#调用函数
func C++ http://c.biancheng.net/cplus/
变量 | 含义 |
---|---|
$0 | 当前脚本的文件名。 |
$n(n≥1) | 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1 ,第二个参数是 $2 。 |
$# | 传递给脚本或函数的参数个数。${#str} 可以获取str字符串长度 |
$* | 传递给脚本或函数的所有参数。 |
$@ | 传递给脚本或函数的所有参数。当被双引号" " 包含时,$@ 与 $* 稍有不同,我们将在《Shell
∗
和
*和
∗和@的区别》一节中详细讲解。 |
$? | 上个命令的退出状态,或函数的返回值,我们将在《Shell $?》一节中详细讲解。 |
$$ | 当前 Shell 进程 ID。对于 Shell 脚本,就是这些脚本所在的进程 ID。 |
$*
和$@
的区别当 $* 和 $@ 不被双引号" "
包围时,它们之间没有任何区别,都是将接收到的每个参数看做一份数据,彼此之间以空格来分隔。但是当它们被双引号" "
包含时,就会有区别了:
"$*"
会将所有的参数从整体上看做一份数据,而不是把每个参数都看做一份数据。"$@"
仍然将每个参数都看作一份数据,彼此之间是独立的。 注:可以分割用于for循环$?
:获取函数返回值或上一个命令的退出状态获取上一个命令的退出状态
a.sh
#!/bin/bash
if [ $1 == 100 ]
then
return 0 #参数正确,返回0
else
return 1 #参数错误,返回1
fi
b.sh
#!/bin/bash
echo $?
结果:
$ . ./a.sh 100
$ . ./b.sh
0
获取函数返回值
test.sh
#!/bin/bash
#得到两个数相加的和
function add(){
return `expr $1 + $2`
}
add 23 50 #调用函数
echo $? #获取函数返回值
结果:
$ . ./test.sh
73
从左向右
#${string: start :length}
#string 是要截取的字符串,start 是起始位置(从左边开始,从 0 开始计数),length 是要截取的长度(省略的话表示直到字符串的末尾)
url="c.biancheng.net"
echo ${url: 2: 9}
echo ${url: 2} #省略 length,截取到字符串末尾
从右向左
从右边开始计数时,起始数字是 1。不管从哪边开始计数,截取方向都是从左到右
#${string: 0-start :length}
url="c.biancheng.net"
echo ${url: 0-13: 9}
#上面的结果为biancheng。从右边数,b是第 13 个字符
url="c.biancheng.net"
echo ${url: 0-13} #省略 length,直接截取到字符串末尾
#使用#号可以截取指定字符(或者子字符串)右边的所有字符
${string#*chars}
#示例
url="http://c.biancheng.net/index.html"
echo ${url#*:}
#结果为//c.biancheng.net/index.html
#如果希望直到最后一个指定字符(子字符串)再匹配结束,那么可以使用##
${string##*chars}
其中,string 表示要截取的字符,chars 是指定的字符(或者子字符串),*
是通配符的一种,表示任意长度的字符串。*chars
连起来使用的意思是:忽略左边的所有字符,直到遇见 chars(chars 不会被截取
#注意*的位置,因为要截取 chars 左边的字符,而忽略 chars 右边的字符,所以*应该位于 chars 的右侧。其他方面%和#的用法相同
${string%chars*}
汇总
格式 | 说明 |
---|---|
${string: start :length} | 从 string 字符串的左边第 start 个字符开始,向右截取 length 个字符。 |
${string: start} | 从 string 字符串的左边第 start 个字符开始截取,直到最后。 |
${string: 0-start :length} | 从 string 字符串的右边第 start 个字符开始,向右截取 length 个字符。 |
${string: 0-start} | 从 string 字符串的右边第 start 个字符开始截取,直到最后。 |
${string#*chars} | 从 string 字符串第一次出现 *chars 的位置开始,截取 *chars 右边的所有字符。 |
${string##*chars} | 从 string 字符串最后一次出现 *chars 的位置开始,截取 *chars 右边的所有字符。 |
${string%*chars} | 从 string 字符串第一次出现 *chars 的位置开始,截取 *chars 左边的所有字符。 |
${string%%*chars} | 从 string 字符串最后一次出现 *chars 的位置开始,截取 *chars 左边的所有字符。 |
Shell 是弱类型的,它并不要求所有数组元素的类型必须相同
Shell 数组元素的下标也是从 0 开始计数
array_name=(ele1 ele2 ele3 ... elen)
#下面的ages只给第 3、5、10 个元素赋值,所以数组长度是 3
ages=([3]=24 [5]=19 [10]=12)
#其中,array_name 是数组名,index 是下标
${array_name[index]}
使用@
或*
可以获取数组中的所有元素
${nums[*]}
${nums[@]}
利用@
或*
,可以将数组扩展成列表,然后使用#
来获取数组元素的个数
${#array_name[@]}
${#array_name[*]}
如果某个元素是字符串,还可以通过指定下标的方式获得该元素的长度
${#arr[2]}
拼接数组的思路是:先利用@
或*
,将数组扩展成列表,然后再合并到一起
array_new=(${array1[@]} ${array2[@]})
array_new=(${array1[*]} ${array2[*]})
#删除某个元素
unset array_name[index]
#删除整个数组
unset array_name
#array_name 表示数组名,index 表示数组下标
alias
#查看当前存在的别名列表
$ alias
#添加别名,当前shell有效
$ alias myShutdown='shutdown -h now'
#为了确保永远生效,可以将该别名手动写入到用户主目录中的.bashrc
#删除所有别名,当前shell有效
$ unalias -a
#删除指定别名,当前shell有效
$ unalias 别名名字
#要想永久删除在.bashrc文件中定义的别名,只能进入该文件手动删除
echo
echo 命令输出结束后默认会换行,如果不希望换行,可以加上-n
参数
name="Tom"
height=175
weight=62
echo -n "${name} is years old, "
echo -n "${height}cm in height "
echo "and ${weight}kg in weight."
默认情况下,echo 不会解析以反斜杠\
开头的转义字符。比如,\n
表示换行,echo 默认会将它作为普通字符
我们可以添加-e
参数来让 echo 命令解析转义字符
[root@localhost ~]# echo -e "hello \nworld"
hello
world
有了-e
参数,我们也可以使用转义字符\c
来强制 echo 命令不换行了
#!/bin/bash
name="Tom"
weight=62
echo -e "${name} years old, \c"
echo "and ${weight}kg in weight."
exit
如果在终端中直接运行 exit 命令,会退出当前登录的 Shell,并关闭终端;
如果在 Shell 脚本中出现 exit 命令,会停止执行后边的所有代码,立即退出 Shell 脚本
exit 命令可以接受的参数是一个状态值 n,代表退出时的状态。如果不指定,默认状态值是 0
#!/bin/bash
echo "befor exit"
exit 8
echo "after exit"
我们可以紧接着使用 $?
来获取 demo.sh 的退出状态
[root@localhost ~]# echo $?
8
ulimit
默认情况下 Linux 系统的各个资源都做了软硬限制,其中硬限制的作用是控制软限制(换言之,软限制不能高于硬限制)。使用ulimit -a
可以查看当前系统的软限制,使用命令ulimit -a –H
可查看系统的硬限制
[root@localhost ~]# ulimit -a #core文件大小,单位是block,默认为0 core file size (blocks, -c) 0 #数据段大小,单位是kbyte,默认不做限制 data seg size (kbytes, -d) unlimited #调度优先级,默认为0 scheduling priority (-e) 0 #创建文件的大小,单位是block,默认不做限制 file size (blocks, -f) unlimited #挂起的信号数量,默认是8192 pending signals (-i) 8192 #最大锁定内存的值,单位是kbyte,默认是32 max locked memory (kbytes, -l) 32 #最大可用的常驻内存值,单位是kbyte,默认不做限制 max memory size (kbytes, -m) unlimited #最大打开的文件数,默认是1024 open files (-n) 1024 #管道最大缓冲区的值 pipe size (512 bytes, -p) 8 #消息队列的最大值,单位是byte POSIX message queues (bytes, -q) 819200 #程序的实时性优先级,默认为0 real-time priority (-r) 0 #栈大小,单位是kbyte stack size (kbytes, -s) 10240 #最大cpu占用时间,默认不做限制 cpu time (seconds, -t) unlimited #用户最大进程数,默认是8192 max user processes (-u) 8192 #最大虚拟内存,单位是kbyte,默认不做限制 virtual memory (kbytes, -v) unlimited #文件锁,默认不做限制 file locks (-x) unlimited
每一行中都包含了相应的改变该项设置的参数,以最大可以打开的文件数为例(open files 默认是 1024),想要增大至 4096 则按照如下命令设置(可参照此方法调整其他参数)
#设置最大打开的文件数
#该命令会同时设置硬限制和软限制
[root@localhost ~]# ulimit -n 4096
#使用-S参数单独设置软限制
#[root@localhost ~]# ulimit -S -n 4096
#使用-H参数单独设置硬限制
#[root@localhost ~]# ulimit -H -n 4096
使用 ulimit 直接调整参数,只会在当前运行时生效,一旦系统重启,所有调整过的参数就会变回系统默认值。所以建议将所有的改动放在 ulimit 的系统配置文件中
[root@localhost ~]# cat /etc/security/limits.conf # /etc/security/limits.conf #该文件是ulimit的配置文件,任何对系统的ulimit的修改都应该写入该文件 #请将所有的设置写到该文件的最后 #Each line describes a limit for a user in the form: #配置应该写成下面这行的格式,即每个配置占用1行,每行4列 #每列分别是<domain> <type> <item> <value> #<domain> <type> <item> <value> # #其中: #<domain>可以取的值如下: # - 一个用户名 # - 一个组名,组名前面用@符号 # - 通配符* # - 通配符% #Where: #<domain> can be: # - an user name # - a group name, with @group syntax # - the wildcard *, for default entry # - the wildcard %, can be also used with %group syntax, # for maxlogin limit # #<type>只有以下两个可用值: # - soft用于设置软限制 # - hard用于设置硬限制 #<type> can have the two values: # - "soft" for enforcing the soft limits # - "hard" for enforcing hard limits # #<item>的值可以是以下任意一种: # - core - core文件大小的限制 (KB) # - data - 最大数据段限制 (KB) # - fsize - 最大文件大小 (KB) # - memlock - 最大锁定的内存大小 (KB) # - nofile - 最大打开文件数 # - rss - 最大常驻内存值 (KB) # - stack - 最大栈空间大小 (KB) # - cpu - 最大CPU使用时间 (MIN) # - nproc - 最大进程数 # - as - 虚拟地址空间 # - maxlogins - 某用户的最大登录数 # - maxsyslogins - 系统用户最大登录数 # - priority - 用户进程的运行优先级 # - locks – 用户最大可以锁定文件的数量 # - sigpending - 最大挂起的信号量数 # - msgqueue - POSIX信号队列使用的最大内存值 (bytes) # - nice - 最大nice值 # - rtprio - 最大实时优先级 # #<item> can be one of the following: # - core - limits the core file size (KB) # - data - max data size (KB) # - fsize - maximum filesize (KB) # - memlock - max locked-in-memory address space (KB) # - nofile - max number of open files # - rss - max resident set size (KB) # - stack - max stack size (KB) # - cpu - max CPU time (MIN) # - nproc - max number of processes # - as - address space limit # - maxlogins - max number of logins for this user # - maxsyslogins - max number of logins on the system # - priority - the priority to run user process with # - locks - max number of file locks the user can hold # - sigpending - max number of pending signals # - msgqueue - max memory used by POSIX message queues (bytes) # - nice - max nice priority allowed to raise to # - rtprio - max realtime priority # #<domain> <type> <item> <value> # #以下是使用样例,请参照配置 #* soft core 0 #* hard rss 10000 #@student hard nproc 20 #@faculty soft nproc 20 #@faculty hard nproc 50 #ftp hard nproc 0 #@student - maxlogins 4
declare
declare [+/-] [aAfFgilprtux] [变量名=变量值]
其中,-
表示设置属性,+
表示取消属性,aAfFgilprtux
都是具体的选项,它们的含义如下表所示
选项 | 含义 |
---|---|
-f [name] | 列出之前由用户在脚本中定义的函数名称和函数体。 |
-F [name] | 仅列出自定义函数名称。 |
-g name | 在 Shell 函数内部创建全局变量。 |
-p [name] | 显示指定变量的属性和值。 |
-a name | 声明变量为普通数组。 |
-A name | 声明变量为关联数组(支持索引下标为字符串)。 |
-i name | 将变量定义为整数型。 |
-r name[=value] | 将变量定义为只读(不可修改和删除),等价于 readonly name。 |
-x name[=value] | 将变量设置为环境变量,等价于 export name[=value]。 |
【实例1】将变量声明为整数并进行计算
#!/bin/bash
declare -i m n ret #将多个变量声明为整数
m=10
n=30
ret=$m+$n
echo $ret
#运行结果:40
注意:除了将参与运算的变量定义为整数,还得将承载结果的变量定义为整数,而且只能用整数类型的变量来承载运算结果,不能直接使用 echo 输出。
和 (())、let、$[] 不同,declare -i
的功能非常有限,仅支持最基本的数学运算(加减乘除和取余),不支持逻辑运算(比较运算、与运算、或运算、非运算),所以在实际开发中很少使用
【实例2】将变量定义为只读变量
[c.biancheng.net]$ declare -r n=10
[c.biancheng.net]$ n=20
-bash: n: readonly variable
[c.biancheng.net]$ echo $n
10
【实例3】显示变量的属性和值
[c.biancheng.net]$ declare -r n=10
[c.biancheng.net]$ declare -p n
declare -r n="10"
Shell 中有两种方式可以完成命令替换,一种是反引号,一种是$()
var_name=`command`
var_name=$(command)
如果被替换的命令的输出内容包括多行(也即有换行符),或者含有多个连续的空白符,那么在输出变量时应该将变量用双引号包围,否则系统会使用默认的空白符来填充,这会导致换行无效,以及连续的空白符被压缩成一个.所以,为了防止出现格式混乱的情况,建议在输出变量时加上双引号
$() 支持嵌套
[root@localhost ~]# Fir_File_Lines=$(wc -l $(ls | sed -n '1p'))
[root@localhost ~]# echo "$Fir_File_Lines"
36 anaconda-ks.cfg
$() 仅在 Bash Shell 中有效,而反引号可在多种 Shell 中使用
常见的 Shell 算术运算符
算术运算符 | 说明/含义 |
---|---|
+、- | 加法(或正号)、减法(或负号) |
*、/、% | 乘法、除法、取余(取模) |
** | 幂运算 |
++、– | 自增和自减,可以放在变量的前面也可以放在变量的后面 |
!、&&、|| | 逻辑非(取反)、逻辑与(and)、逻辑或(or) |
<、<=、>、>= | 比较符号(小于、小于等于、大于、大于等于) |
==、!=、= | 比较符号(相等、不相等;对于字符串,= 也可以表示相当于) |
<<、>> | 向左移位、向右移位 |
~、|、 &、^ | 按位取反、按位或、按位与、按位异或 |
=、+=、-=、*=、/=、%= | 赋值运算符,例如 a+=1 相当于 a=a+1,a-=1 相当于 a=a-1 |
Shell 中常用的数学计算命令如下表
运算操作符/运算命令 | 说明 |
---|---|
(( )) | 用于整数运算,效率很高,推荐使用。 |
let | 用于整数运算,和 (()) 类似。 |
[$] | 用于整数运算,不如 (()) 灵活。 |
expr | 可用于整数运算,也可以处理字符串。比较麻烦,需要注意各种细节,不推荐使用。 |
bc | Linux下的一个计算器程序,可以处理整数和小数。Shell 本身只支持整数运算,想计算小数就得使用 bc 这个外部的计算器。 |
declare -i | 将变量定义为整数,然后再进行数学运算时就不会被当做字符串了。功能有限,仅支持最基本的数学运算(加减乘除和取余),不支持逻辑运算、自增自减等,所以在实际开发中很少使用。 |
运算操作符/运算命令 | 说明 |
---|---|
((a=10+66) ((b=a-15)) ((c=a+b)) | 这种写法可以在计算完成后给变量赋值。以 ((b=a-15)) 为例,即将 a-15 的运算结果赋值给变量 c。 注意,使用变量时不用加$ 前缀,(( )) 会自动解析变量名。 |
a= ( ( 10 + 66 ) b = ((10+66) b= ((10+66)b=((a-15)) c=$((a+b)) | 可以在 (( )) 前面加上$ 符号获取 (( )) 命令的执行结果,也即获取整个表达式的值。以 c=
(
(
a
+
b
)
)
为
例
,
即
将
a
+
b
这
个
表
达
式
的
运
算
结
果
赋
值
给
变
量
c
。
注
意
,
类
似
c
=
(
(
a
+
b
)
)
这
样
的
写
法
是
错
误
的
,
不
加
‘
((a+b)) 为例,即将 a+b 这个表达式的运算结果赋值给变量 c。 注意,类似 c=((a+b)) 这样的写法是错误的,不加`
((a+b))为例,即将a+b这个表达式的运算结果赋值给变量c。注意,类似c=((a+b))这样的写法是错误的,不加‘`就不能取得表达式的结果。 |
((a>7 && b==c)) | (( )) 也可以进行逻辑运算,在 if 语句中常会使用逻辑运算。 |
echo $((a+10)) | 需要立接输出表达式的运算结果时,可以在 (( )) 前面加$ 符号。 |
((a=3+5, b=a+10)) | 对多个表达式同时进行计算。 |
和双小括号 (( )) 一样,let 命令也只能进行整数运算,不能对小数(浮点数)或者字符串进行运算
let 表达式
#当表达式中含有 Shell 特殊字符(例如 |)时,需要用双引号" "或者单引号' '将表达式包围起来
和 (( )) 类似,let 命令也支持一次性计算多个表达式,并且以最后一个表达式的值作为整个 let 命令的执行结果。但是,对于多个表达式之间的分隔符,let 和 (( )) 是有区别的:
,
来分隔多个表达式。另外还要注意,对于类似let x+y
这样的写法,Shell 虽然计算了 x+y 的值,但却将结果丢弃;若不想这样,可以使用let sum=x+y
将 x+y 的结果保存在变量 sum 中。
#$[] 会对表达式进行计算,并取得计算结果。如果表达式中包含了变量,那么你可以加$,也可以不加
#需要注意的是,不能单独使用 $[],必须能够接收 $[] 的计算结果
$[表达式]
#示例
$ echo $[$m*$n]
expr 是 evaluate expressions 的缩写,译为“表达式求值”。Shell expr 是一个功能强大,并且比较复杂的命令,它除了可以实现整数计算,还可以结合一些选项对字符串进行处理,例如计算字符串长度、字符串比较、字符串匹配、字符串提取等。
expr 对
表达式
的格式有几点特殊的要求:
表达式
中的运算符、数字、变量和小括号的左右两边至少要有一个空格,否则会报错。\
进行转义(屏蔽其特殊含义),比如乘号*
和小括号()
,如果不用\
转义,那么 Shell 会把它们误解为正则表达式中的符号(*
对应通配符,()
对应分组)。$
前缀[c.biancheng.net]$ m=5
[c.biancheng.net]$ n=`expr $m + 10`
[c.biancheng.net]$ echo $n
15
[c.biancheng.net]$ expr \( 2 + 3 \) \* 4 #使用 \ 转义
Link : http://c.biancheng.net/view/2680.html
选项 | 说明 |
---|---|
-h | --help | 帮助信息 |
-v | --version | 显示命令版本信息 |
-l | --mathlib | 使用标准数学库 |
-i | --interactive | 强制交互 |
-w | --warn | 显示 POSIX 的警告信息 |
-s | --standard | 使用 POSIX 标准来处理 |
-q | --quiet | 不显示欢迎信息 |
变量名 | 作 用 |
---|---|
scale | 指定精度,也即小数点后的位数;默认为 0,也即不使用小数部分。 |
ibase | 指定输入的数字的进制,默认为十进制。 |
obase | 指定输出的数字的进制,默认为十进制。 |
last 或者 . | 表示最近打印的数字 |
s(x) | 计算 x 的正弦值,x 是弧度值。 |
---|---|
c(x) | 计算 x 的余弦值,x 是弧度值。 |
a(x) | 计算 x 的反正切值,返回弧度值。 |
l(x) | 计算 x 的自然对数。 |
e(x) | 求 e 的 x 次方。 |
j(n, x) | 贝塞尔函数,计算从 n 到 x 的阶数 |
$ echo "expression" | bc
$ variable=$(echo "expression" | bc)
[c.biancheng.net]$ echo "scale=5;n=$x+2;e(n)"|bc -l
403.42879
variable=$(bc << EOF
expressions
EOF
)
#其中,variable是 Shell 变量名,express是要计算的数学表达式(可以换行,和进入 bc 以后的书写形式一样),EOF是数学表达式的开始和结束标识(你也可以换成其它的名字,比如 aaa、bbb 等)
#demo
if condition1
then
statement1
elif condition2
then
statement2
elif condition3
then
statement3
……
else
statementn
fi
test
用法
$ test expression
#也可以简写为[],注意[]和expression之间的空格,这两个空格是必须的,否则会导致语法错误
$ [ expression ]
文件类型判断 | |
---|---|
选 项 | 作 用 |
-b filename | 判断文件是否存在,并且是否为块设备文件。 |
-c filename | 判断文件是否存在,并且是否为字符设备文件。 |
-d filename | 判断文件是否存在,并且是否为目录文件。 |
-e filename | 判断文件是否存在。 |
-f filename | 判断文件是否存在,井且是否为普通文件。 |
-L filename | 判断文件是否存在,并且是否为符号链接文件。 |
-p filename | 判断文件是否存在,并且是否为管道文件。 |
-s filename | 判断文件是否存在,并且是否为非空。 |
-S filename | 判断该文件是否存在,并且是否为套接字文件。 |
文件权限判断 | |
选 项 | 作 用 |
-r filename | 判断文件是否存在,并且是否拥有读权限。 |
-w filename | 判断文件是否存在,并且是否拥有写权限。 |
-x filename | 判断文件是否存在,并且是否拥有执行权限。 |
-u filename | 判断文件是否存在,并且是否拥有 SUID 权限。 |
-g filename | 判断文件是否存在,并且是否拥有 SGID 权限。 |
-k filename | 判断该文件是否存在,并且是否拥有 SBIT 权限。 |
文件比较 | |
选 项 | 作 用 |
filename1 -nt filename2 | 判断 filename1 的修改时间是否比 filename2 的新。 |
filename -ot filename2 | 判断 filename1 的修改时间是否比 filename2 的旧。 |
filename1 -ef filename2 | 判断 filename1 是否和 filename2 的 inode 号一致,可以理解为两个文件是否为同一个文件。这个判断用于判断硬链接是很好的方法 |
选 项 | 作 用 |
---|---|
num1 -eq num2 | 判断 num1 是否和 num2 相等。 |
num1 -ne num2 | 判断 num1 是否和 num2 不相等。 |
num1 -gt num2 | 判断 num1 是否大于 num2 。 |
num1 -lt num2 | 判断 num1 是否小于 num2。 |
num1 -ge num2 | 判断 num1 是否大于等于 num2。 |
num1 -le num2 | 判断 num1 是否小于等于 num2。 |
选 项 | 作 用 |
---|---|
-z str | 判断字符串 str 是否为空。 |
-n str | 判断宇符串 str 是否为非空。 |
str1 = str2 str1 == str2 | = 和== 是等价的,都用来判断 str1 是否和 str2 相等。 |
str1 != str2 | 判断 str1 是否和 str2 不相等。 |
str1 > str2 | 判断 str1 是否大于 str2。\> 是> 的转义字符,这样写是为了防止> 被误认为成重定向运算符。 |
str1 < str2 | 判断 str1 是否小于 str2。同样,\< 也是转义字符。 |
有C语言、C++、Python、Java 等编程经验的读者请注意,==、>、< 在大部分编程语言中都用来比较数字,而在 Shell 中,它们只能用来比较字符串,不能比较数字,这是非常奇葩的,大家要习惯。
其次,不管是比较数字还是字符串,Shell 都不支持 >= 和 <= 运算符,切记
选 项 | 作 用 |
---|---|
expression1 -a expression | 逻辑与,表达式 expression1 和 expression2 都成立,最终的结果才是成立的。 |
expression1 -o expression2 | 逻辑或,表达式 expression1 和 expression2 有一个成立,最终的结果就成立。 |
!expression | 逻辑非,对 expression 进行取反。 |
test 用变量建议用双引号包起来
[[]]
几乎完全兼容 test ,并且比 test 更加强大,比 test 更加灵活的是[[ ]]
;[[ ]]
不是命令,而是 Shell 关键字
#用法
$ [[ expression ]]
[[ ]] 是 Shell 内置关键字,不是命令,在使用时没有给函数传递参数的过程,所以 test 命令的某些注意事项在 [[ ]] 中就不存在了,具体包括:
""
包围起来,即使变量是空值,也不会出错。注意,[[ ]] 剔除了 test 命令的-o
和-a
选项,你只能使用 || 和 &&
$ [[ str =~ regex ]]
但是 [[ ]] 对数字的比较仍然不友好,所以我建议,以后大家使用 if 判断条件时,用 (()) 来处理整型数字,用 [[ ]] 来处理字符串或者文件
case in
case expression in
pattern1)
statement1
;;
pattern2)
statement2
;;
pattern3)
statement3
;;
……
*)
statementn
esac
case、int 和 esac 都是 Shell 关键字,expression 表示表达式,pattern 表示匹配模式。
case 会将 expression 的值与 pattern1、pattern2、pattern3 逐个进行匹配:
;;
才停止;然后整个 case 语句就执行完了,程序会跳出整个 case 语句,执行 esac 后面的其它语句。*)
后面的语句(*
表示其它所有值),直到遇见双分号;;
或者esac
才结束。*)
相当于多个 if 分支语句中最后的 else 部分除最后一个分支外(这个分支可以是普通分支,也可以是*)
分支),其它的每个分支都必须以;;
结尾,;;
代表一个分支的结束,不写的话会有语法错误。最后一个分支可以写;;
,也可以不写,因为无论如何,执行到 esac 都会结束整个 case in 语句
case in 的 pattern 部分支持简单的正则表达式,具体来说,可以使用以下几种格式
格式 | 说明 |
---|---|
* | 表示任意字符串。 |
[abc] | 表示 a、b、c 三个字符中的任意一个。比如,[15ZH] 表示 1、5、Z、H 四个字符中的任意一个。 |
[m-n] | 表示从 m 到 n 的任意一个字符。比如,[0-9] 表示任意一个数字,[0-9a-zA-Z] 表示字母或数字。 |
| | 表示多重选择,类似逻辑运算中的或运算。比如,abc | xyz 表示匹配字符串 “abc” 或者 “xyz”。 |
while condition
do
statements
done
until condition
do
statements
done
#unti 循环和 while 循环恰好相反,当判断条件不成立时才进行循环,一旦判断条件成立,就终止循环
#c风格
for((exp1; exp2; exp3))
do
statements
done
#python风格
for variable in value_list
do
statements
done
直接给出具体的值
#!/bin/bash
for str in "C语言中文网" "http://c.biancheng.net/" "成立7年了" "日IP数万"
do
echo $str
done
#{start..end}
#demo
#!/bin/bash
sum=0
for n in {1..100}
do
((sum+=n))
done
echo $sum
start 表示起始值,end 表示终止值;注意中间用两个点号相连,而不是三个点号。根据笔者的实测,这种形式只支持数字和字母
再如,输出从 A 到 z 之间的所有字符
#!/bin/bash
for c in {A..z}
do
printf "%c" $c
done
#结果为:ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz
#可以发现,Shell 是根据 ASCII 码表来输出的
#!/bin/bash
sum=0
for n in $(seq 2 2 100)
do
((sum+=n))
done
echo $sum
#!/bin/bash
for filename in *.sh
do
echo $filename
done
#!/bin/bash function func(){ for str in $@ do echo $str done } func C++ Java Python C# #其实,我们也可以省略 value_list,省略后的效果和使用$@一样 #!/bin/bash function func(){ for str do echo $str done } func C++ Java Python C#
select variable in value_list
do
statements
done
注意,select 是无限循环(死循环),输入空值,或者输入的值无效,都不会结束循环,只有遇到 break 语句,或者按下 Ctrl+D 组合键才能结束循环
select in 通常和 case in 一起使用,在用户输入不同的编号时可以做出不同的反应
#!/bin/bash echo "What is your favourite OS?" select name in "Linux" "Windows" "Mac OS" "UNIX" "Android" do case $name in "Linux") echo "Linux是一个类UNIX操作系统,它开源免费,运行在各种服务器设备和嵌入式设备。" break ;; "Windows") echo "Windows是微软开发的个人电脑操作系统,它是闭源收费的。" break ;; "Mac OS") echo "Mac OS是苹果公司基于UNIX开发的一款图形界面操作系统,只能运行与苹果提供的硬件之上。" break ;; "UNIX") echo "UNIX是操作系统的开山鼻祖,现在已经逐渐退出历史舞台,只应用在特殊场合。" break ;; "Android") echo "Android是由Google开发的手机操作系统,目前已经占据了70%的市场份额。" break ;; *) echo "输入错误,请重新输入" esac done
#运行结果示例
What is your favourite OS?
1) Linux
2) Windows
3) Mac OS
4) UNIX
5) Android
#? 7
输入错误,请重新输入
#? 4
UNIX是操作系统的开山鼻祖,现在已经逐渐退出历史舞台,只应用在特殊场合
#可以跳出多层循环,不加n默认当前循环
break n
continue n
Linux 会给每个文件分配一个 ID,这个 ID 就是一个整数,被称为文件描述符**(File Descriptor)**
文件描述符 | 文件名 | 类型 | 硬件 |
---|---|---|---|
0 | stdin | 标准输入 | 键盘 |
1 | stdout | 标准输出 | 显示器 |
2 | stderr | 标准错误输出 | 显示器 |
Linux 程序在执行任何形式的 I/O 操作时,都是在读取或者写入一个文件描述符。一个文件描述符只是一个和打开的文件相关联的整数,它的背后可能是一个硬盘上的普通文件、FIFO、管道、终端、键盘、显示器,甚至是一个网络连接。
stdin、stdout、stderr 默认都是打开的,在重定向的过程中,0、1、2 这三个文件描述符可以直接使用
输出重定向是指命令的结果不再输出到显示器上,而是输出到其它地方,一般是文件中。这样做的最大好处就是把命令的结果保存起来,当我们需要的时候可以随时查询。Bash 支持的重定向符号如下表所示
类 型 | 符 号 | 作 用 |
---|---|---|
标准输出重定向 | 命令 > 文件 | 以覆盖的方式,把命令的正确输出结果输出到指定的文件或设备中。 |
标准输出重定向 | 命令 >> 文件 | 以追加的方式,把命令的正确输出结果输出到指定的文件或设备中。 |
标准错误输出重定向 | 命令 2> 文件 | 以覆盖的方式,把命令的错误信息输出到指定的文件或设备中。 |
标准错误输出重定向 | 命令 2>> 文件 | 以追加的方式,把命令的错误信息输出到指定的文件或设备中。 |
正确输出和错误信息同时保存 | 命令 > 文件 2> &1 | 以覆盖的方式,把正确输出和错误信息同时保存到同一个文件中。 |
同上 | 命令 >> 文件 2> &1 | 以追加的方式,把正确输出和错误信息同时保存到同一个文件中。 |
同上 | 命令 &> 文件 | 以覆盖的方式,把正确输出和错误信息同时保存到同一个文件中。 |
同上 | 命令 &>> 文件 | 以追加的方式,把正确输出和错误信息同时保存到同一个文件中。 |
同上 | 命令 >> 文件1 2>> 文件2 | 把正确的输出追加到文件1中,把错误信息追加到文件2中。 |
/dev/null 文件
如果你既不想把命令的输出结果保存到文件,也不想把命令的输出结果显示到屏幕上,干扰命令的执行,那么可以把命令的所有结果重定向到 /dev/null 文件中。如下所示:
ls -l &> /dev/null
输入重定向就是改变输入的方向,不再使用键盘作为命令输入的来源,而是使用文件作为命令的输入
符号 | 说明 |
---|---|
命令 < 文件 | 将指定的文件作为命令的输入。 |
命令 << 分界符 | 从标准输入(键盘)中读取数据,直到遇见分界符才停止。 |
命令 < 文件1 > 文件2 | 将文件1作为命令的输入,并将命令的处理结果输出到文件2。 |
举例 wc
Linux wc 命令可以用来对文本进行统计,包括单词个数、行数、字节数,它的用法如下:
wc [选项] [文件名]
#其中,-c选项统计字节数,-w选项统计单词数,-l选项统计行数
统计用户在终端输入的文本的行数
[c.biancheng.net]$ wc -l << END
> 123
> 789
> abc
> xyz
> END
4
#wc 命令会一直等待用输入,直到遇见分界符 END 才结束读取
#<<之后的分界符可以自由定义,只要再碰到相同的分界符,两个分界符之间的内容将作为命令的输入(不包括分界符本身)
source 命令的用法为
$ source filename
#也可以简写为
$ . filename
source 是 Shell 内置命令的一种,它会读取 filename 文件中的代码,并依次执行所有语句。你也可以理解为,source 命令会强制执行脚本文件中的全部命令,而忽略脚本文件的权限
#!/bin/bash
source func.sh
echo $(sum 10 20 55 15)
#source 后边可以使用相对路径,也可以使用绝对路径,这里我们使用的是相对路径
可以在模块中额外设置一个变量,使用 if 语句来检测这个变量是否存在,如果发现这个变量存在,就 return 出去
在 Shell 中,return 除了可以退出函数,还能退出由 source 命令引入的脚本文件。
return 只能退出由 source 命令引入的脚本文件,对其它引入脚本的方式无效
if [ -n "$__MODULE_SH__" ]; then
return
fi
__MODULE_SH__='module.sh'
echo "http://c.biancheng.net/shell/"
#!/bin/bash
source module.sh
source module.sh
echo "here executed"
运行 main.sh,输出结果为:
http://c.biancheng.net/shell/
here executed
Bash Shell 含有许多常用的命令,这些命令都已经内建在了 Shell 中。在使用这些命令时,执行速度就要快很多
相比外部命令,内建命令提供了更高的性能,但 Shell 中包含的内建命令越多,消耗的内存就会越大,而有些命令几乎永远也不会用到
命令 | 说明 |
---|---|
: | 扩展参数列表,执行重定向操作 |
. | 读取并执行指定文件中的命令(在当前 shell 环境中) |
alias | 为指定命令定义一个别名 |
bg | 将作业以后台模式运行 |
bind | 将键盘序列绑定到一个 readline 函数或宏 |
break | 退出 for、while、select 或 until 循环 |
builtin | 执行指定的 shell 内建命令 |
caller | 返回活动子函数调用的上下文 |
cd | 将当前目录切换为指定的目录 |
command | 执行指定的命令,无需进行通常的 shell 查找 |
compgen | 为指定单词生成可能的补全匹配 |
complete | 显示指定的单词是如何补全的 |
compopt | 修改指定单词的补全选项 |
continue | 继续执行 for、while、select 或 until 循环的下一次迭代 |
declare | 声明一个变量或变量类型。 |
dirs | 显示当前存储目录的列表 |
disown | 从进程作业表中刪除指定的作业 |
echo | 将指定字符串输出到 STDOUT |
enable | 启用或禁用指定的内建shell命令 |
eval | 将指定的参数拼接成一个命令,然后执行该命令 |
exec | 用指定命令替换 shell 进程 |
exit | 强制 shell 以指定的退出状态码退出 |
export | 设置子 shell 进程可用的变量 |
fc | 从历史记录中选择命令列表 |
fg | 将作业以前台模式运行 |
getopts | 分析指定的位置参数 |
hash | 查找并记住指定命令的全路径名 |
help | 显示帮助文件 |
history | 显示命令历史记录 |
jobs | 列出活动作业 |
kill | 向指定的进程 ID(PID) 发送一个系统信号 |
let | 计算一个数学表达式中的每个参数 |
local | 在函数中创建一个作用域受限的变量 |
logout | 退出登录 shell |
mapfile | 从 STDIN 读取数据行,并将其加入索引数组 |
popd | 从目录栈中删除记录 |
printf | 使用格式化字符串显示文本 |
pushd | 向目录栈添加一个目录 |
pwd | 显示当前工作目录的路径名 |
read | 从 STDIN 读取一行数据并将其赋给一个变量 |
readarray | 从 STDIN 读取数据行并将其放入索引数组 |
readonly | 从 STDIN 读取一行数据并将其赋给一个不可修改的变量 |
return | 强制函数以某个值退出,这个值可以被调用脚本提取 |
set | 设置并显示环境变量的值和 shell 属性 |
shift | 将位置参数依次向下降一个位置 |
shopt | 打开/关闭控制 shell 可选行为的变量值 |
source | 读取并执行指定文件中的命令(在当前 shell 环境中) |
suspend | 暂停 Shell 的执行,直到收到一个 SIGCONT 信号 |
test | 基于指定条件返回退出状态码 0 或 1 |
times | 显示累计的用户和系统时间 |
trap | 如果收到了指定的系统信号,执行指定的命令 |
type | 显示指定的单词如果作为命令将会如何被解释 |
typeset | 声明一个变量或变量类型。 |
ulimit | 为系统用户设置指定的资源的上限 |
umask | 为新建的文件和目录设置默认权限 |
unalias | 刪除指定的别名 |
unset | 刪除指定的环境变量或 shell 属性 |
wait | 等待指定的进程完成,并返回退出状态码 |
Bash Shell 还使用了许多环境变量。虽然环境变量不是命令,但它们通常会影响 Shell 命令的执行
可用 set 内建命令显示这些环境变量。对于不同的 Linux 发行版,开机时设置的默认 shell 环境变量经常会不一样
变量 | 说明 |
---|---|
* | 含有所有命令行参数(以单个文本值的形式) |
@ | 含有所有命令行参数(以多个文本值的形式) |
# | 命令行参数数目 |
? | 最近使用的前台进程的退出状态码 |
- | 当前命令行选项标记 |
$ | 当前shell的进程 ID (PID) |
! | 最近执行的后台进程的 PID |
0 | 命令行中使用的命令名称 |
_ | shell 的绝对路径名 |
BASH | 用来调用 shell 的完整文件名 |
BASHOPTS | 允许冒号分隔列表形式的 Shell 选项 |
BASHPID | 当前 bash shell 的进程 ID |
BASH_ALIASED | 含有当前所用别名的数组 |
BASH_ARGC | 当前子函数中的参数数量 |
BASH_ARGV | 含有所有指定命令行参数的数组 |
BASH_CMDS | 含有命令的内部散列表的数组 |
BASH_COMMAND | 当前正在被执行的命令名 |
BASH_ENV | 如果设置了的话,每个 bash 脚本都会尝试在运行前执行由该变量定义的起始文件 |
BASH_EXECUTION_STRING | 在 -c 命令行选项中用到的命令 |
BASH_LINENO | 含有脚本中每个命令的行号的数组 |
BASH_REMATCH | 含有与指定的正则表达式匹配的文本元素的数组 |
BASH_SOURCE | 含有 shell 中已声明函数所在源文件名的数组 |
BASH_SUBSHELL | 当前 shell 生成的子 shell 数目 |
BASH_VERS INFO | 含有当前 bash shell 实例的主版本号和次版本号的数组 |
BASH_VERS ION | 当前 bash shell 实例的版本号 |
BASH_XTRACEFD | 当设置一个有效的文件描述符整数时,跟踪输出生成,并与诊断和错误信息分离开文件描述符必须设置 -x 启动 |
COLUMNS | 含有当前 bash shell 实例使用的终端的宽度 |
COMP_CWORD | 含有变量 COMP_WORDS 的索引直,COMP_WORDS 包含当前光标所在的位置 |
COMP_KEY | 调用补全功能的按键 |
COMP_LINE | 当前命令行 |
COMP_POINT | 当前光标位置相对干当前命令起始位置的索引 |
COMP_TYPE | 补全类型所对应的整数值 |
COMP_WORDBREAKS | 在进行单词补全时闬作单词分隔符的一组字符 |
COMP_WORDS | 含有当前命令行上所有单词的数组 |
COMPREPLY | 含有由 shell 函数生成的可能补全码的数组 |
COPROC | 含有若干匿名协程 I/O 的文件描述符的数组 |
DIRSTACK | 含有目录栈当前内容的数组 |
EMACS | 如果设置了该环境变量,则 shell 认为其使用的是 emacs shell 缓冲区,同时禁止行编辑功能 |
ENV | 当 shell 以 POSIX 模式调用时,每个 bash 脚本在运行之前都会执行由该环境变量所定义的起始文件 |
EUID | 当前用户的有效用户 ID(数字形式) |
FCEDIT | fc 命令使用的默认编辑器 |
FIGNORE | 以冒号分隔的后缀名列表,在文件名补全时会被忽略 |
FUNCNAME | 当前执行的 shell 函数的名称 |
FUNCNEST | 嵌套函数的最髙层级 |
GLOBIGNORE | 以冒号分隔的模式列表,定义了文件名展开时要忽略的文件名集合 |
GROUPS | 含有当前用户属组的数组 |
histchars | 控制历史记录展开的字符(最多可有3个) |
HISTCMD | 当前命令在历史记录中的编号 |
HISTCONTROL | 控制哪些命令留在历史记录列表中 |
HISTFILE | 保存 shell 历史记录列表的文件名(默认是 .bash_history) |
HISTFILESIZE | 保存在历史文件中的最大行数 |
HISTIGNORE | 以冒号分隔的模式列表,用来决定哪些命令不存进历史文件 |
HISTSIZE | 最多在历史文件中保存多少条命令 |
HISTIMEFORMAT | 设置后,决定历史文件条目的时间戳的格式字符串 |
HOSTFILE | 含有 shell 在补全主机名时读取的文件的名称 |
HOSTNAME | 当前主机的名称 |
HOSTTYPE | 当前运行 bash shell 的机器 |
IGNOREEOF | shell 在退出前必须收到连续的 EOF 字符的数量。如果这个值不存在,默认是 1 |
INPUTRC | readline 初始化文件名(默认是 .inputrc) |
LANG | shell 的语言环境分类 |
LC_ALL | 定义一个语言环境分类,它会覆盖 LANG 变量 |
LC_COLLATE | 设置对字符串值排序时用的对照表顺序 |
LC_CTYPE | 决定在进行文件名扩展和模式匹配时,如何解释其中的字符 |
LC_MESSAGES | 决定解释前置美元符($)的双引号字符串的语言环境设置 |
LC_NUMERIC | 决定格式化数字时的所使用的语言环境设置 |
LINENO | 脚本中当前执行代码的行号 |
LINES | 定义了终端上可见的行数 |
MACHTYPE | 用“cpu-公司-系统”格式定义的系统类型 |
MAILCHECK | Shell 多久查看一次新邮件(以秒为单位,默认值是 60) |
MAPFILE | 含有 mapfile 命令所读入文本的数组,当没有给出变量名的时候,使用该环境变量 |
OLDPWD | shell 之前的工作目录 |
OPTERR | 设置为 1 时,bash shell 会显示 getopts 命令产生的错误 |
OSTYPE | 定义了 shell 运行的操作系统 |
PIPESTATUS | 含有前台进程退出状态码的数组 |
POSIXLY_CORRECT | 如果设置了该环境变量,bash 会以 POSIX 模式启动 |
PPID | bash shell 父进程的 PID |
PROMPT_COMMAND | 如果设置该环境变量,在显示命令行主提示符之前会执行这条命令 |
PS1 | 主命令行提示符字符串 |
PS2 | 次命令行提示符字符串 |
PS3 | select 命令的提示符 |
PS4 | 如果使用了 bash 的 -x 选项,在命令行显示之前显示的提示符 |
PWD | 当前工作目录 |
RANDOM | 返回一个 0~32 767 的随机数,对其赋值可作为随机数生成器的种子 |
READLINE_LINE | 保存了 readline 行缓冲区中的内容 |
READLINE_POINT | 当前 readline 行缓冲区的插入点位置 |
REPLY | read 命令的默认变量 |
SECONDS | 自 shell 启动到现在的秒数,对其赋值将会重置计时器 |
SHELL | shell 的全路径名 |
SHELLOPTS | 已启用 bash shell 选项列表,由冒号分隔 |
SHLVL | 表明 shell 层级,每次启动一个新的 bash shell 时计数加 1 |
TIMEFORMAT | 指定了 shell 显示的时间值的格式 |
TMOUT | select 和 read 命令在没输入的情况下等待多久(以秒为单位)。默认值为零,表示无限长 |
TMPDIR | 如果设置成目录名,shell 会将其作为临时文件目录 |
UID | 当前用户的真实用户 ID (数字形式) |
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。