shell笔记
时间:2007-10-18 来源:brain2007
按键编码
arrowup='\[A'
arrowdown='\[B'
arrowrt='\[C'
arrowleft='\[D'
insert='\[2'
delete='\[3'
bash 相关的基本概念
字(word/token) // shell 中由字符序列构成的一个处理单位
元字符(metacharacter) //当没有被引用时(unquoted),对 shell 具有特殊含义,并导致字分割
// bash 中的元字符有且只有: | & ; ( ) < > space tab
简单命令 //由可选的赋值列表,重定向操作,命令,参数构成的序列,它将由 换行符 | & && || ; 终止
流水线(Pipelines) //Smiple-command1 | Smiple-command2 | ......
命令列表(List) //Pipelines1 && Pipelines2 || ......
组合命令 ( list1; list2; ...)
{ list1; list2; ...}
bash 执行命令的优先级
1.别名 //脚本内部不使用别名
2.关键字
3.函数
4.内置命令
5.脚本或可执行程序(通过 $PATH 环境变量查找)
下列命令可以改变命令的优先级
builtin //调用内建命令
command //禁用别名和函数的查找,只查找内部命令以及搜索路径中找到的脚本或可执行程序
enable
enable //恢复所有的内建命令
enable -n kill //禁用内建命令 kill
enable -a kill //恢复内建命令 kill
enable -f file //从适当的编译过的目标文件 file 中以共享库(DLL)的形式来加载一个内建命令
bash 控制台控制键
Ctrl^C //发出中断信号
Ctrl^D //退出shell,logout
Ctrl^L //清屏
Ctrl^U //删除全行
Ctrl^W //删除一个单词
Ctrl^Z //挂起当前进程
Ctrl^S //挂起 bash 终端
Ctrl^Q //恢复 bash 终端
bash数字常量
BASE#NUMBER //BASE范围:2--64
//字符:10 个数字 + 26 个小写字母 + 26 个大写字母 + @ + _
0NUMBER //八进制
0xNUMBER //十六进制
bash pattern
* //可以匹配 0 个或者多个任意字符,包括 . 以及 /。但是进行文件名匹配时第一个 * 不能匹配 .
? //匹配任何单个字符
. //匹配 .
[ - ] //匹配在某个范围内的字符
[[:lower:]] //匹配小写字母,可移植
[[:upper:]] //匹配大写字母,可移植
[! - ] //匹配不在某个范围内的字符
[[:space:]] //空白字符
赋值操作
var[0]=value0
var[1]=value1 //其中没有定义到的 index 认为没有定义,而不是值为空
var=(a b c) //数组赋值,索引从0开始
//赋值操作关键注意:1.赋值的时候不会进行 word splitting 与 pathname expansion,引用时才会进行
2.多个 word 赋值给一个变量时,会由 space 连接成为一个 word
shopt -s nullglob; var=( *.txt ); shopt -u nullglob;
I/O 重定向 // I/O 重定向的目标可以是文件、命令、程序、脚本、代码块。特别注意 subshell 也是进程,其输入输出也可重定向
//每个打开的文件都会被分配一个文件描述符,exec 命令用于为文件分配文件描述符
//stdin、stdout、stderr 文件的文件描述符分别是0、1、2;对于额外的文件,保留了描述符 3 到 9
//但是,使用文件描述符 5 可能会引起问题。当 Bash 使用exec 创建一个子进程的时候,子进程会继承 fd5,因此不要使用 fd5
// ls -yz >>file 2>&1 与 ls -yz 2>&1 >>file 执行结果并不相同,同一行上出现多个重定向时执行结果与重定向顺序有关
:> //不能用于 I/O 重定向
:>file //若文件存在,清空文件;若文件不存在,创建之
&>
&>file //将 stdout 和 stderr 都重定向到文件 file
> // > 后接文件名
command >file //进行 I/O 重定向。若文件存在,清空文件;若文件不存在,创建之
command j>file //重定向文件描述符 j 到文件 file
exec j>file //为了写 file,把文件 file 打开,并且分配 shell 脚本的文件描述符 j,默认值是 1
>& // >& 后接文件描述符,& 取得 fd 对应的文件
2>&1 //重定向 stderr 至 &1,即文件描述符 1 对应的文件
i>&j //重定向文件描述符 i 至文件 &j
>&j //重定向文件描述符 stdout 到文件 &j
exec n>&- //关闭输出文件描述符 n,- 相当于 null 指针
exec >&- //关闭 stdout
>| //强制重定向,这将强制的覆盖一个现存文件
>>
command >>file //进行 I/O 重定向。如果文件不存在,那么就创建它;如果存在,那么就追加到文件后边
>>&
< // < 后接文件名
0<file
<file
var=`< file` //将 file 的内容放到 var 中
exec j<file //为了读 file,把文件 file 打开,并且分配 shell 脚本的文件描述符 j,默认值是 0
<& // <& 后接文件描述符,& 取得 fd 对应的文件
exec n<&- //关闭输入文件描述符 n,- 相当于 null 指针
exec <&- //关闭 stdin
<>
exec j<>file //为了读写 file,把文件 file 打开,并且分配 shell 脚本的文件描述符 j,默认值是 0
| //将前一个进程的 stdout 连接到下一个进程的 stdin
//注意:管道将产生 subshell
<< //here documents
cat << EOF
......
EOF
文件与文件描述符的区别
//文件描述符形成文件流,即读取文件流里的数据后,文件流指针会自动移动
//下列代码将正常工作
while read line <&3;
do
echo "$line";
done
//文件内则不存在文件流指针的概念
//下列代码只会读取文件 file 的第一行
while read line <file;
do
echo "$line";
done
- // stdin、stdout 文件
(cd /source/directory && tar cf - .)|(cd /dest/directory && tar xpvf -)
\ //屏蔽所有特殊字符
\+Enter //换行
'' //由单引号括起来的字符都作为普通字符出现。特殊字符用单引号括起来以后,也会失去原有意义,而只作为普通字符解释。
//单引号更严格一些,它可以防止任何变量扩展。
"" //由双引号括起来的字符,除$ \ ' "这几个字符仍是特殊字符并保留其特殊功能外,其余字符仍作为普通字符对待。
//防止进行 word splitting 与 pathname expansion,双引号可以防止通配符扩展但允许变量扩展。
//加了 " " 后,原来有几个 word 现在还是有几个 word
`` //反引号还可以嵌套使用。但需注意,嵌套使用时内层的反引号必须用反斜线(\)将其转义。
{} //匿名函数
fun( ){ fun( ){ return 0; }; return 0; } //函数的返回值在调用该函数的程序体中通过 $? 保留字来获得
//返回值范围:0-255,超过的做溢出处理
function fun( ){ local var=1; } //函数的作用域不可局域化,变量的作用域可以局域化
//函数内部的变量默认就是 local 变量
//函数体内使用!必须进行转义\!
echo {file1,file2}none{\ A," B",' C'}
{ read line1; read line2; } < filename;
$ // $var 中,字符串的index从 0 开始计算,使用的是 pattern
$"string"
//等价于 "string"
$- //传递给脚本的falg(使用 set 命令)
$_ //之前执行的命令的最后一个参数
$0 //保存程序名
$1 //位置变量
$? //保存前一个命令的返回码
grep 'string' filename || echo No Found //通过 $? 来判断是否找到匹配
$# //保存程序命令行参数的数目
$* //同 ${var}
$@ //同 ${var[@]}
original_params=("$@") //保存位置参数数组
set -- $original_params //恢复原始位置参数
$$ //这个程序的 PID
$! //在后台工作的最后一个进程的 PID
$!{var} //间接引用 var
${var} //需要注意的是变量扩展完之后会进行 word splitting 与 pathname expansion
//若要防止 word splitting 与 pathname expansion 需要加 " "
${#var} //计算 $var 的长度
${#1} //计算位置参数 $1 的长度
${var
} // 扩展成"$1<$IFS>$2 ... " 的形式,即一个字的形式,中间用 $IFS 连接
// "${var
}" 将会用 " " 引用 ${var
} 扩展成的字让它不进行 word splitting 与 pathname expansion
${var[@]} // 扩展成"$1" "$2" ... 的形式,即多个字的形式
// "${var[@]}" 将会用 " " 引用 ${var[@]} 扩展成的每个字让它不进行 word splitting 与 pathname expansion
${#array
}
${#array[@]} //计算数组 array 的长度
${#*}
${#@} //给出位置参数的个数
${!varprefix*}
${!varprefix@} //使用变量的前缀 varprefix 来匹配前边所有声明过的变量
${var-default} //触发条件:变量未定义
${var:-default} //触发条件:变量未定义 或 值为空
//返回值为 default
${var=default} //触发条件:变量未定义
${var:=default} //触发条件:变量未定义 或 值为空
//在返回 default 的同时将 default 赋值给 var
${var+default} //触发条件:变量已定义
${var:+default} //触发条件:变量已定义 且 值不为空
//触发条件:用 default 替换 var
${var?message} //触发条件:变量未定义
${var:?message} //触发条件:变量未定义 或 值为空
//将消息 message 送到标准错误输出 cerr。若此替换出现在 Shell 程序中,那么该程序将终止运行
${var:offset} //从位置 $position 开始提取子串,这里 offset 和 length 可以是算术表达式,index 从 0 开始
//如果 $string 为 "*" 或 "@",那么将提取从位置 $position 开始的位置参数
echo ${stringZ:(-4)}
echo ${stringZ: -4} //反向提取字符串,index 从 -1 开始
// : 与 - 之间要加入 空格 或者 在负数上加 ( ) 进行转义
${var:offset:length}
//从位置 $position 开始提取 $length 长度的子串,这里 offset 和 length 可以是算术表达式,index 从 0 开始
//如果 $string 为 "*" 或 "@",那么将提取从位置 $position 开始 $length 长度的的位置参数
echo ${stringZ:(-4):3}
echo ${stringZ: -4:3} //反向提取字符串,index 从 -1 开始
// : 与 - 之间要加入 空格 或者 在负数上加 ( ) 进行转义
//注意:模式 pattern 不是正则表达式 regexp
${var#pattern} //使用最短匹配
${var##pattern} //去掉 $var 中与 pattern 相匹配的部分,条件是 $var 的开头与 pattern 相匹配,使用最长匹配
${var%pattern} //使用最短匹配
${var%%pattern} //从 $var 的尾部与 pattern 相匹配,%与%%的区别与#与##一样
${var/pattern/string} //使用 string 来替换第一个匹配的 pattern,使用最长匹配
${var//pattern/string} //使用 string 来替换所有匹配的 pattern,使用最长匹配
${var/#pattern/string} //如果 pattern 匹配 $var 的开头部分,那么就用 string 进行替换,使用最长匹配
${var/%pattern/string} //如果 pattern 匹配 $var 的结尾部分,那么就用 string 进行替换,使用最长匹配
$RANDOM // Bash 的内部函数,返回值范围 [ 0 , 32767 ]
RANDOM=$$ //使用脚本的进程 ID 来作为随机数的产生种子,从 time 或 date 命令中取得 RANDOM 种子也是很常用的办法
//注意:/dev/urandom 设备文件提供了一种比单独使用 $RANDOM 更好的,能产生更"随机"的随机数的方法
$( command ) //等价于 `command`,但是 $( ... ) 形式的命令替换允许嵌套
$(( n++ ))
$[ n++ ] //不存在$[[ n++ ]]
# //注释
#! /bin/bash
bash
bash scriptfile args
-c 'command' //从字符串中读入命令,如果字符串后还有变量则被设定为从$0开始的位置参数
-i // bash 是交互的
- //表示参数执行完毕,并且屏蔽此后所跟的参数,后面的所有变量都被看作是文件名
file globbing //是否进行 file globbing 由相关的命令决定,由 bash 完成
echo
echo *.sh // file globbing
echo '*.sh' // non-file globbing
echo "*.sh" // non-file globbing
find
find . -name *.sh // file globbing
find . -name '*.sh' // file globbing
find . -name "*.sh" // file globbing
for 结构会对循环变量进行 file globbing
作业标识符 //注意:作业不等于进程,作业号也不是进程号,作业由当前 shell 维护,而进程由系统维护
%N //作业号[N]
%String //以字符串 String 开头的被(命令行)调用的作业
%?String //包含字符串 String 的被(命令行)调用的作业
%% //当前作业(前台最后结束的作业 或 后台最后启动的作业)
%+ //当前作业(前台最后结束的作业 或 后台最后启动的作业)
%- //最后的作业
$! //最后的后台进程
作业控制
bg //重新启动一个挂起的作业并在后台运行它
bg task //如果没有指定作业号,那么默认将对当前正在运行的作业做操作
disown //从 shell 的当前作业表中删除作业
disown task
disown PID
fg //把一个在后台运行的作业放到前台来运行
fg task //如果没有指定作业号,那么默认将对当前正在运行的作业做操作
jobs //在后台列出所有正在运行的作业并给出作业号
jobs task
kill //通过发送一个适当的结束信号,来强制结束一个进程
//一个僵尸进程不能被登陆的用户 kill 掉,因为你不能杀掉一些已经死了的东西,但是 init 进程迟早会把它清除干净
//僵尸进程就是子进程已经结束掉,而父进程却没 kill 掉这个子进程,那么这个子进程就成为僵尸进程
kill -l //列出所有信号
logout //退出一个登陆的 shell,也可以指定一个退出码
suspend //挂起 shell,cannot suspend a login shell。这个 shell 的父进程应该在合适的时候通过 SIGCONT signal 重新恢复它
wait //停止脚本的运行,直到后台运行的所有作业都结束为止,或者直到指定作业号或进程号为选项的作业结束为止
//可以使用 wait 命令来防止在后台作业没完成(这会产生一个孤儿进程)之前退出脚本
wait task
wait PID
wait $PPID
常用环境变量 //环境变量是特殊的变量,环境变量会被传递到子进程中,而普通变量则不会
bash 内建环境变量
$- //开启的 bash shell 特性
$BASH //指向 Bash 的二进制执行文件的位置
$BASH_ENV //这个环境变量将指向一个Bash 启动文件,这个启动文件将在调用一个脚本时被读取
$BASH_SUBSHELL //这个变量将提醒 subshell 的层次
$BASH_VERSINFO[n]
//记录 Bash 安装信息的一个 6 元素的数组
$BASH_VERSION // Bash 的版本号
$DIRSTACK //在目录栈中最上边的值
${DIRSTACK[@]} //目录栈,最后一个值就是当前目录,无法popd
$EDITOR //脚本调用的默认编辑器
$EUID //"effective"用户ID 号.当前用户被假定的任何 id 号,可能在su 命令中使用
//注意:$EUID 并不一定与$UID 相同
$FCEDIT //Bash的fc命令的默认文本编辑器
$FUNCNAME //当前函数的名字
$GLOBIGNORE //一个文件名的模式匹配列表,如果在 file globbing 中匹配到的文件包含这个列表中的
//某个文件,那么这个文件将被从匹配到的文件中去掉
$GROUPS //当前用户属于的组
$HISTFILE //规定存放最近输入命令行文件的名字
$HISTSIZE //规定命令行历史文件的大小
$HOME //当前用户的宿主目录
$HOSTNAME // hostname 命令将在一个init 脚本中,在启动的时候分配一个系统名字
$HOSTTYPE //主机类型
$IFS //内部域分隔符(Internal Field Separator)
//这个变量用来决定 Bash 在解释字符串时如何识别域,或者单词边界,即用于进行 word splitting
// IFS 默认为空白(空格,tab,和新行)
// IFS 是可以更改的。在每个新的fork过程中,IFS都会恢复到默认值;而在每个进程中,IFS是可以修改的
// IFS 也可以 unset,恢复默认值
//参数在需要解析的时候才使用 IFS 分割参数
// word splitting 会使 $IFS 字符消失
IFS=" "
IFS="\t"
IFS="\n"
$IGNOREEOF //忽略EOF: 告诉 shell 在 log out 之前要忽略多少文件结束符(ctrl^D)
$LC_COLLATE //用来在文件名扩展和模式匹配校对顺序
$LC_CTYPE //用来控制 file globbing 和模式匹配的字符串解释
$LINENO //记录它所在的shell 脚本中它所在行的行号
$MACHTYPE //系统类型,提示系统硬件
$OLDPWD //用户使用的前一个目录
$OSTYPE //操作系统类型
$PATH //规定bash寻找可执行文件时搜索的路径
$PIPESTATUS
//数组变量,将保存最后一个运行的前台管道的退出码,数组的每个成员都会保存一个管道命令的退出码
//$PIPESTATUS[0]保存第一个管道命令的退出码,$PIPESTATUS[1] 保存第 2 个,以此类推
//有趣的是,这个退出码和最后一个命令运行的退出码并不一定相同
$PPID //父进程PID
$PROMPT_COMMAND //保存一个在主提示符 ($PS1) 显示之前需要执行的命令
$PS1 //主提示符
$PS2 //第 2 提示符,当你需要额外的输入的时候将会显示,默认为">"
$PS3 //第 3 提示符,在一个select 循环中显示
$PS4 //第 4 提示符,当使用 -x 选项调用脚本时,这个提示符将出现在每行的输出前边。默认为"+"
$PWD //用户当前工作目录
$REPLY // read 命令如果没有给变量,那么输入将保存在 $REPLY 中
//在 select 菜单中也可用,但是只提供选择的变量的项数,而不是变量本身的值
$SECONDS //当前运行的bash进程的运行时间(以秒为单位)
$SHELLOPTS //保存 shell 允许的选项,这个变量是只读的
$SHLVL // Shell 层次,就是 shell 层叠的层次
$TMOUT //如果 $TMOUT 环境变量被设置为一个非零的时间值,那么在过了这个指定的时间之后,shell 提示符将会超时
//与 read 命令搭配使用
$UID //用户 ID,只读变量
// Root 的 UID 是 0
以下变量并不是 Bash 的内建变量。它们经常被设置成环境变量,一般都放在Bash 的安装文件中
$ENV
$LOGNAME
$MAIL
$TERM
$USER
$USERNAME
$SHELL //用户登录的 shell 的名字,可能是从/etc/passwd 设置的,也可能是在一个"init"脚本中设置的
( ) // subshell
( date; uname -a ) >> logfile //重定向 subshell 输出
[ expression ] // [ 是builtin command;[ ] 不做算术运算;进行文件名扩展;需要用空格分隔各值和运算符
//对应的外部命令是test
-b file //如果文件为一个块特殊文件,则为真
! -b file //否定形式
-c file //如果文件为一个字符特殊文件,则为真
-d file //如果文件为一个目录,则为真
-e file //如果文件存在,则为真
//如果文件是软连接文件则检测的是所连接的文件存在与否
//即如果 -e file 求值为真的话,则要么 file 存在要么 file 为一软连接文件并指向另一存在文件
-f file //如果文件为一个普通文件,则为真
-g file //如果设置了文件的 SGID 位,则为真
-G file //如果文件存在且文件的 group-id 和你的相同,则为真
-h file //文件是个符号链接
-k file //如果设置了文件的粘着位,则为真
-L file //文件是个符号链接
-N file //从文件最后被阅读到现在,是否被修改
-O file //如果文件存在并且归该用户所有,则为真
-p file //如果文件为一个命名管道,则为真
-r file //如果文件可读,则为真
-s file //如果文件的长度不为零,则为真
-S file //如果文件为一个套接字特殊文件,则为真
-t fd //如果 fd 是一个与终端相连的打开的文件描述符(fd 默认为 1),则为真
//一般都用来检测是否在一个给定脚本中的stdin[-t0]或[-t1]是一个终端
-u file //如果设置了文件的 SUID 位,则为真
-w file //如果文件可写,则为真
-x file //如果文件可执行,则为真
file1 -ef file2 //测试以判断两个文件是否与同一个设备相连,是否拥有相同的 inode 编号
file1 -nt file2 //测试以判断第一个文件是否比第二个文件更新(由修改日期决定)
file1 -ot file2 //测试以判断第一个文件是否比第二个文件更旧
string //测试以判断字符串是否不为空
-n string //测试以判断字符串是否不为空;字符串必须为 test 所识别,即 string 必须加" "
-z string //测试以判断字符串是否为空;字符串必须为 test 所识别
string1 = string2 //测试以判断 string1 是否与 string2 相同
string1 != string2 //测试以判断 string1 是否与 string2 不同
int1 -eq int2 //如果 int1 等于 int2,则为真
int1 -ge int2 //如果 int1 大于或等于 int2,则为真
int1 -gt int2 //如果 int1 大于 int2,则为真
int1 -le int2 //如果 int1 小于或等于 int2,则为真
int1 -lt int2 //如果 int1 小于 int2,则为真
int1 -ne int2 //如果 int1 不等于 int2,则为真
str1 = str2
str1 \> str2
str1 \< str2
str1 != str2
! expr //如果表达式评估为假,则为真
! true
expr1 -a expr2 //如果 expr1 和 expr2 评估为真,则为真
expr1 -o expr2 //如果 expr1 或 expr2 评估为真,则为真
[ expr1 ] && [ expr2 ]
[ expr1 ] || [ expr2 ]
[[ expression ]] // [[ 是keyword;[[ ]] 做算术运算(+ - * / %);不进行文件名扩展(进行模式匹配);需要用空格分隔各值和运算符
// [[ ]] 也能进行 [] 能进行的文件测试、数字测试、字符串测试
str1 = str2 //等号右端的str2支持通配符*、?,但是不能用引号括起
str1 > str2
str1 < str2
str1 != str2
! expr //如果表达式评估为假,则为真
expr1 && expr2 //如果 expr1 和 expr2 评估为真,则为真
expr1 || expr2 //如果 expr1 或 expr2 评估为真,则为真
[[ 99+1 -eq 100 ]] && echo true || echo false // [[ 可以进行算术运算扩展
(( expression )) //同let命令,对应的外部命令是expr;不需要用空格分隔各值和运算符
int1 >= int2
int1 > int2
int1 <= int2
int1 < int2
int1 != int2
int1 == int2
! expr //如果表达式评估为假,则为真
expr1 && expr2 //如果 expr1 和 expr2 评估为真,则为真
expr1 || expr2 //如果 expr1 或 expr2 评估为真,则为真
expr1 , expr2 //,用于连接多个算术运算
= //赋值
(( var=0 ))
? : //条件赋值
(( var= a<45 ? 1 : 0 ))
+ //加法
+= //加等于
- //减法
-= //减等于
* //乘法
*= //乘等于
/ //除法
/= //除等于
% //取模
%= //取模赋值
** //幂运算
++
(( var++ )) //先返回值再加 1
(( ++var )) //先加 1 再返回值
--
(( var-- ))
(( --var ))
<< //左移1 位(每次左移都将乘2)
<<= //左移几位,=号后边将给出左移几位
let "var <<= 2" //左移2 位(就是乘4)
>> //右移1 位(每次右移都将除2)
>>= //右移几位
& //按位与
&= //按位与赋值
| //按位或
|= //按位或赋值
^ //按位异或XOR
^= //异或赋值
~ //取补码
! //逻辑否
&& //逻辑与
if [ $condition1 ] && [ $condition2 ];
if [ $condition1 -a $condition2 ];
if [[ $condition1 && $condition2 ]];
|| //逻辑或
. //等价于 source 命令。source sourced-file 其实像是函数调用,sourced-file 也可以用 return 命令返回值
: //等价于 true 命令,也作为占位符使用
while : //等价于true命令
do
...
done
: ${username=`whoami`} //作为占位符使用
:> filename //若文件存在,清空文件;若文件不存在,创建之
:() { :|:& }; :
alias
alias -p // prints the list of aliases in the form alias NAME=VALUE on standard output
autoload //一个带有 autoload 声明的函数,在它第一次被调用的时候才会被加载以节省系统资源
// autoload 命令并不是 Bash 安装时候的核心命令的一部分。这个命令需要使用命令 enable -f 来加载
bind //显示或修改 readline 的键绑定
break
break N //退出 N 层循环
caller //用于函数或者 sourced-file
caller n
continue
continue N //将 N 层循环全部 continue
case string in "str1" | "str2" ) commands1;; "str3" ) commands2;; * ) commands3;; esac
cd
../..
~
/
- //把工作目录改为 $OLDPWD,就是之前的工作目录
-P // physical 选项,忽略符号连接
declare //与 typeset 完全一样
//注意:使用 declare 将会限制变量的作用域
-r //只读
declare -r
-i //整形,如果把一个变量指定为整形,那么即使没有 expr 和 let 命令,也允许使用特定的算术运算
n=6/3 // n 的值为 "6/3"
declare -i n; n=6/3 // n 的值为 2
-a //数组
-f //函数
declare -f //列出这个脚本中之前定义的所有函数的定义
declare -f function //列出函数 function 的定义
-x //export
dirs //列出目录栈的所有内容
echo
echo $path
echo -n string
echo -e '\n'
eval //将表达式中的参数或者表达式列表组合起来并评估它们,包含在表达式中的任何变量都将被扩展。如无必要使用,不推荐使用
eval arg1 [arg2] ... [argN]
eval var1=\$$var2
eval var1=\${$var2}
eval "var1=\${$var2}"
eval echo \$$var //间接引用 var
eval echo \${$var} //间接引用 var
eval "echo \${$var}" //间接引用 var
典型用法
command=`eval ls -l`; echo $command;
command="eval ls -l"; $command;
var_pointer=var; eval $var_pointer=value; //执行结果相当于执行了 var=value,该技术主要目的为向函数传递变量名
fun( ) { local var_pointer=$1; eval $var_pointer=value; }
fun var; //函数 fun 将对变量 var 赋值
exec //使用一个特定的命令来取代当前进程,也用于重新分配文件描述符
exec j>file //为了写 file,把文件 file 打开,并且分配 shell 脚本的文件描述符 j,默认值是 1
exec j<file //为了读 file,把文件 file 打开,并且分配 shell 脚本的文件描述符 j,默认值是 0
exec j<>file //为了读写 file,把文件 file 打开,并且分配 shell 脚本的文件描述符 j,默认值是 0
exec n>&- //关闭输出文件描述符 n,- 相当于 null 指针
exec n<&- //关闭输入文件描述符 n,- 相当于 null 指针
exec cmd.exe //以 cmd.exe 进程取代当前进程
exit //如果不带参数的使用 exit 来退出,那么退出码将是脚本中最后一个命令的退出码,等价于exit $?
exit 0
export //由export关键字处理过的变量叫做环境变量
for var in list; do ... ; done //如果在 for 循环的
arrowup='\[A'
arrowdown='\[B'
arrowrt='\[C'
arrowleft='\[D'
insert='\[2'
delete='\[3'
bash 相关的基本概念
字(word/token) // shell 中由字符序列构成的一个处理单位
元字符(metacharacter) //当没有被引用时(unquoted),对 shell 具有特殊含义,并导致字分割
// bash 中的元字符有且只有: | & ; ( ) < > space tab
简单命令 //由可选的赋值列表,重定向操作,命令,参数构成的序列,它将由 换行符 | & && || ; 终止
流水线(Pipelines) //Smiple-command1 | Smiple-command2 | ......
命令列表(List) //Pipelines1 && Pipelines2 || ......
组合命令 ( list1; list2; ...)
{ list1; list2; ...}
bash 执行命令的优先级
1.别名 //脚本内部不使用别名
2.关键字
3.函数
4.内置命令
5.脚本或可执行程序(通过 $PATH 环境变量查找)
下列命令可以改变命令的优先级
builtin //调用内建命令
command //禁用别名和函数的查找,只查找内部命令以及搜索路径中找到的脚本或可执行程序
enable
enable //恢复所有的内建命令
enable -n kill //禁用内建命令 kill
enable -a kill //恢复内建命令 kill
enable -f file //从适当的编译过的目标文件 file 中以共享库(DLL)的形式来加载一个内建命令
bash 控制台控制键
Ctrl^C //发出中断信号
Ctrl^D //退出shell,logout
Ctrl^L //清屏
Ctrl^U //删除全行
Ctrl^W //删除一个单词
Ctrl^Z //挂起当前进程
Ctrl^S //挂起 bash 终端
Ctrl^Q //恢复 bash 终端
bash数字常量
BASE#NUMBER //BASE范围:2--64
//字符:10 个数字 + 26 个小写字母 + 26 个大写字母 + @ + _
0NUMBER //八进制
0xNUMBER //十六进制
bash pattern
* //可以匹配 0 个或者多个任意字符,包括 . 以及 /。但是进行文件名匹配时第一个 * 不能匹配 .
? //匹配任何单个字符
. //匹配 .
[ - ] //匹配在某个范围内的字符
[[:lower:]] //匹配小写字母,可移植
[[:upper:]] //匹配大写字母,可移植
[! - ] //匹配不在某个范围内的字符
[[:space:]] //空白字符
赋值操作
var[0]=value0
var[1]=value1 //其中没有定义到的 index 认为没有定义,而不是值为空
var=(a b c) //数组赋值,索引从0开始
//赋值操作关键注意:1.赋值的时候不会进行 word splitting 与 pathname expansion,引用时才会进行
2.多个 word 赋值给一个变量时,会由 space 连接成为一个 word
shopt -s nullglob; var=( *.txt ); shopt -u nullglob;
I/O 重定向 // I/O 重定向的目标可以是文件、命令、程序、脚本、代码块。特别注意 subshell 也是进程,其输入输出也可重定向
//每个打开的文件都会被分配一个文件描述符,exec 命令用于为文件分配文件描述符
//stdin、stdout、stderr 文件的文件描述符分别是0、1、2;对于额外的文件,保留了描述符 3 到 9
//但是,使用文件描述符 5 可能会引起问题。当 Bash 使用exec 创建一个子进程的时候,子进程会继承 fd5,因此不要使用 fd5
// ls -yz >>file 2>&1 与 ls -yz 2>&1 >>file 执行结果并不相同,同一行上出现多个重定向时执行结果与重定向顺序有关
:> //不能用于 I/O 重定向
:>file //若文件存在,清空文件;若文件不存在,创建之
&>
&>file //将 stdout 和 stderr 都重定向到文件 file
> // > 后接文件名
command >file //进行 I/O 重定向。若文件存在,清空文件;若文件不存在,创建之
command j>file //重定向文件描述符 j 到文件 file
exec j>file //为了写 file,把文件 file 打开,并且分配 shell 脚本的文件描述符 j,默认值是 1
>& // >& 后接文件描述符,& 取得 fd 对应的文件
2>&1 //重定向 stderr 至 &1,即文件描述符 1 对应的文件
i>&j //重定向文件描述符 i 至文件 &j
>&j //重定向文件描述符 stdout 到文件 &j
exec n>&- //关闭输出文件描述符 n,- 相当于 null 指针
exec >&- //关闭 stdout
>| //强制重定向,这将强制的覆盖一个现存文件
>>
command >>file //进行 I/O 重定向。如果文件不存在,那么就创建它;如果存在,那么就追加到文件后边
>>&
< // < 后接文件名
0<file
<file
var=`< file` //将 file 的内容放到 var 中
exec j<file //为了读 file,把文件 file 打开,并且分配 shell 脚本的文件描述符 j,默认值是 0
<& // <& 后接文件描述符,& 取得 fd 对应的文件
exec n<&- //关闭输入文件描述符 n,- 相当于 null 指针
exec <&- //关闭 stdin
<>
exec j<>file //为了读写 file,把文件 file 打开,并且分配 shell 脚本的文件描述符 j,默认值是 0
| //将前一个进程的 stdout 连接到下一个进程的 stdin
//注意:管道将产生 subshell
<< //here documents
cat << EOF
......
EOF
文件与文件描述符的区别
//文件描述符形成文件流,即读取文件流里的数据后,文件流指针会自动移动
//下列代码将正常工作
while read line <&3;
do
echo "$line";
done
//文件内则不存在文件流指针的概念
//下列代码只会读取文件 file 的第一行
while read line <file;
do
echo "$line";
done
- // stdin、stdout 文件
(cd /source/directory && tar cf - .)|(cd /dest/directory && tar xpvf -)
\ //屏蔽所有特殊字符
\+Enter //换行
'' //由单引号括起来的字符都作为普通字符出现。特殊字符用单引号括起来以后,也会失去原有意义,而只作为普通字符解释。
//单引号更严格一些,它可以防止任何变量扩展。
"" //由双引号括起来的字符,除$ \ ' "这几个字符仍是特殊字符并保留其特殊功能外,其余字符仍作为普通字符对待。
//防止进行 word splitting 与 pathname expansion,双引号可以防止通配符扩展但允许变量扩展。
//加了 " " 后,原来有几个 word 现在还是有几个 word
`` //反引号还可以嵌套使用。但需注意,嵌套使用时内层的反引号必须用反斜线(\)将其转义。
{} //匿名函数
fun( ){ fun( ){ return 0; }; return 0; } //函数的返回值在调用该函数的程序体中通过 $? 保留字来获得
//返回值范围:0-255,超过的做溢出处理
function fun( ){ local var=1; } //函数的作用域不可局域化,变量的作用域可以局域化
//函数内部的变量默认就是 local 变量
//函数体内使用!必须进行转义\!
echo {file1,file2}none{\ A," B",' C'}
{ read line1; read line2; } < filename;
$ // $var 中,字符串的index从 0 开始计算,使用的是 pattern
$"string"
//等价于 "string"
$- //传递给脚本的falg(使用 set 命令)
$_ //之前执行的命令的最后一个参数
$0 //保存程序名
$1 //位置变量
$? //保存前一个命令的返回码
grep 'string' filename || echo No Found //通过 $? 来判断是否找到匹配
$# //保存程序命令行参数的数目
$* //同 ${var
$@ //同 ${var[@]}
original_params=("$@") //保存位置参数数组
set -- $original_params //恢复原始位置参数
$$ //这个程序的 PID
$! //在后台工作的最后一个进程的 PID
$!{var} //间接引用 var
${var} //需要注意的是变量扩展完之后会进行 word splitting 与 pathname expansion
//若要防止 word splitting 与 pathname expansion 需要加 " "
${#var} //计算 $var 的长度
${#1} //计算位置参数 $1 的长度
${var
// "${var
${var[@]} // 扩展成"$1" "$2" ... 的形式,即多个字的形式
// "${var[@]}" 将会用 " " 引用 ${var[@]} 扩展成的每个字让它不进行 word splitting 与 pathname expansion
${#array
${#array[@]} //计算数组 array 的长度
${#*}
${#@} //给出位置参数的个数
${!varprefix*}
${!varprefix@} //使用变量的前缀 varprefix 来匹配前边所有声明过的变量
${var-default} //触发条件:变量未定义
${var:-default} //触发条件:变量未定义 或 值为空
//返回值为 default
${var=default} //触发条件:变量未定义
${var:=default} //触发条件:变量未定义 或 值为空
//在返回 default 的同时将 default 赋值给 var
${var+default} //触发条件:变量已定义
${var:+default} //触发条件:变量已定义 且 值不为空
//触发条件:用 default 替换 var
${var?message} //触发条件:变量未定义
${var:?message} //触发条件:变量未定义 或 值为空
//将消息 message 送到标准错误输出 cerr。若此替换出现在 Shell 程序中,那么该程序将终止运行
${var:offset} //从位置 $position 开始提取子串,这里 offset 和 length 可以是算术表达式,index 从 0 开始
//如果 $string 为 "*" 或 "@",那么将提取从位置 $position 开始的位置参数
echo ${stringZ:(-4)}
echo ${stringZ: -4} //反向提取字符串,index 从 -1 开始
// : 与 - 之间要加入 空格 或者 在负数上加 ( ) 进行转义
${var:offset:length}
//从位置 $position 开始提取 $length 长度的子串,这里 offset 和 length 可以是算术表达式,index 从 0 开始
//如果 $string 为 "*" 或 "@",那么将提取从位置 $position 开始 $length 长度的的位置参数
echo ${stringZ:(-4):3}
echo ${stringZ: -4:3} //反向提取字符串,index 从 -1 开始
// : 与 - 之间要加入 空格 或者 在负数上加 ( ) 进行转义
//注意:模式 pattern 不是正则表达式 regexp
${var#pattern} //使用最短匹配
${var##pattern} //去掉 $var 中与 pattern 相匹配的部分,条件是 $var 的开头与 pattern 相匹配,使用最长匹配
${var%pattern} //使用最短匹配
${var%%pattern} //从 $var 的尾部与 pattern 相匹配,%与%%的区别与#与##一样
${var/pattern/string} //使用 string 来替换第一个匹配的 pattern,使用最长匹配
${var//pattern/string} //使用 string 来替换所有匹配的 pattern,使用最长匹配
${var/#pattern/string} //如果 pattern 匹配 $var 的开头部分,那么就用 string 进行替换,使用最长匹配
${var/%pattern/string} //如果 pattern 匹配 $var 的结尾部分,那么就用 string 进行替换,使用最长匹配
$RANDOM // Bash 的内部函数,返回值范围 [ 0 , 32767 ]
RANDOM=$$ //使用脚本的进程 ID 来作为随机数的产生种子,从 time 或 date 命令中取得 RANDOM 种子也是很常用的办法
//注意:/dev/urandom 设备文件提供了一种比单独使用 $RANDOM 更好的,能产生更"随机"的随机数的方法
$( command ) //等价于 `command`,但是 $( ... ) 形式的命令替换允许嵌套
$(( n++ ))
$[ n++ ] //不存在$[[ n++ ]]
# //注释
#! /bin/bash
bash
bash scriptfile args
-c 'command' //从字符串中读入命令,如果字符串后还有变量则被设定为从$0开始的位置参数
-i // bash 是交互的
- //表示参数执行完毕,并且屏蔽此后所跟的参数,后面的所有变量都被看作是文件名
file globbing //是否进行 file globbing 由相关的命令决定,由 bash 完成
echo
echo *.sh // file globbing
echo '*.sh' // non-file globbing
echo "*.sh" // non-file globbing
find
find . -name *.sh // file globbing
find . -name '*.sh' // file globbing
find . -name "*.sh" // file globbing
for 结构会对循环变量进行 file globbing
作业标识符 //注意:作业不等于进程,作业号也不是进程号,作业由当前 shell 维护,而进程由系统维护
%N //作业号[N]
%String //以字符串 String 开头的被(命令行)调用的作业
%?String //包含字符串 String 的被(命令行)调用的作业
%% //当前作业(前台最后结束的作业 或 后台最后启动的作业)
%+ //当前作业(前台最后结束的作业 或 后台最后启动的作业)
%- //最后的作业
$! //最后的后台进程
作业控制
bg //重新启动一个挂起的作业并在后台运行它
bg task //如果没有指定作业号,那么默认将对当前正在运行的作业做操作
disown //从 shell 的当前作业表中删除作业
disown task
disown PID
fg //把一个在后台运行的作业放到前台来运行
fg task //如果没有指定作业号,那么默认将对当前正在运行的作业做操作
jobs //在后台列出所有正在运行的作业并给出作业号
jobs task
kill //通过发送一个适当的结束信号,来强制结束一个进程
//一个僵尸进程不能被登陆的用户 kill 掉,因为你不能杀掉一些已经死了的东西,但是 init 进程迟早会把它清除干净
//僵尸进程就是子进程已经结束掉,而父进程却没 kill 掉这个子进程,那么这个子进程就成为僵尸进程
kill -l //列出所有信号
logout //退出一个登陆的 shell,也可以指定一个退出码
suspend //挂起 shell,cannot suspend a login shell。这个 shell 的父进程应该在合适的时候通过 SIGCONT signal 重新恢复它
wait //停止脚本的运行,直到后台运行的所有作业都结束为止,或者直到指定作业号或进程号为选项的作业结束为止
//可以使用 wait 命令来防止在后台作业没完成(这会产生一个孤儿进程)之前退出脚本
wait task
wait PID
wait $PPID
常用环境变量 //环境变量是特殊的变量,环境变量会被传递到子进程中,而普通变量则不会
bash 内建环境变量
$- //开启的 bash shell 特性
$BASH //指向 Bash 的二进制执行文件的位置
$BASH_ENV //这个环境变量将指向一个Bash 启动文件,这个启动文件将在调用一个脚本时被读取
$BASH_SUBSHELL //这个变量将提醒 subshell 的层次
$BASH_VERSINFO[n]
//记录 Bash 安装信息的一个 6 元素的数组
$BASH_VERSION // Bash 的版本号
$DIRSTACK //在目录栈中最上边的值
${DIRSTACK[@]} //目录栈,最后一个值就是当前目录,无法popd
$EDITOR //脚本调用的默认编辑器
$EUID //"effective"用户ID 号.当前用户被假定的任何 id 号,可能在su 命令中使用
//注意:$EUID 并不一定与$UID 相同
$FCEDIT //Bash的fc命令的默认文本编辑器
$FUNCNAME //当前函数的名字
$GLOBIGNORE //一个文件名的模式匹配列表,如果在 file globbing 中匹配到的文件包含这个列表中的
//某个文件,那么这个文件将被从匹配到的文件中去掉
$GROUPS //当前用户属于的组
$HISTFILE //规定存放最近输入命令行文件的名字
$HISTSIZE //规定命令行历史文件的大小
$HOME //当前用户的宿主目录
$HOSTNAME // hostname 命令将在一个init 脚本中,在启动的时候分配一个系统名字
$HOSTTYPE //主机类型
$IFS //内部域分隔符(Internal Field Separator)
//这个变量用来决定 Bash 在解释字符串时如何识别域,或者单词边界,即用于进行 word splitting
// IFS 默认为空白(空格,tab,和新行)
// IFS 是可以更改的。在每个新的fork过程中,IFS都会恢复到默认值;而在每个进程中,IFS是可以修改的
// IFS 也可以 unset,恢复默认值
//参数在需要解析的时候才使用 IFS 分割参数
// word splitting 会使 $IFS 字符消失
IFS=" "
IFS="\t"
IFS="\n"
$IGNOREEOF //忽略EOF: 告诉 shell 在 log out 之前要忽略多少文件结束符(ctrl^D)
$LC_COLLATE //用来在文件名扩展和模式匹配校对顺序
$LC_CTYPE //用来控制 file globbing 和模式匹配的字符串解释
$LINENO //记录它所在的shell 脚本中它所在行的行号
$MACHTYPE //系统类型,提示系统硬件
$OLDPWD //用户使用的前一个目录
$OSTYPE //操作系统类型
$PATH //规定bash寻找可执行文件时搜索的路径
$PIPESTATUS
//$PIPESTATUS[0]保存第一个管道命令的退出码,$PIPESTATUS[1] 保存第 2 个,以此类推
//有趣的是,这个退出码和最后一个命令运行的退出码并不一定相同
$PPID //父进程PID
$PROMPT_COMMAND //保存一个在主提示符 ($PS1) 显示之前需要执行的命令
$PS1 //主提示符
$PS2 //第 2 提示符,当你需要额外的输入的时候将会显示,默认为">"
$PS3 //第 3 提示符,在一个select 循环中显示
$PS4 //第 4 提示符,当使用 -x 选项调用脚本时,这个提示符将出现在每行的输出前边。默认为"+"
$PWD //用户当前工作目录
$REPLY // read 命令如果没有给变量,那么输入将保存在 $REPLY 中
//在 select 菜单中也可用,但是只提供选择的变量的项数,而不是变量本身的值
$SECONDS //当前运行的bash进程的运行时间(以秒为单位)
$SHELLOPTS //保存 shell 允许的选项,这个变量是只读的
$SHLVL // Shell 层次,就是 shell 层叠的层次
$TMOUT //如果 $TMOUT 环境变量被设置为一个非零的时间值,那么在过了这个指定的时间之后,shell 提示符将会超时
//与 read 命令搭配使用
$UID //用户 ID,只读变量
// Root 的 UID 是 0
以下变量并不是 Bash 的内建变量。它们经常被设置成环境变量,一般都放在Bash 的安装文件中
$ENV
$LOGNAME
$TERM
$USER
$USERNAME
$SHELL //用户登录的 shell 的名字,可能是从/etc/passwd 设置的,也可能是在一个"init"脚本中设置的
( ) // subshell
( date; uname -a ) >> logfile //重定向 subshell 输出
[ expression ] // [ 是builtin command;[ ] 不做算术运算;进行文件名扩展;需要用空格分隔各值和运算符
//对应的外部命令是test
-b file //如果文件为一个块特殊文件,则为真
! -b file //否定形式
-c file //如果文件为一个字符特殊文件,则为真
-d file //如果文件为一个目录,则为真
-e file //如果文件存在,则为真
//如果文件是软连接文件则检测的是所连接的文件存在与否
//即如果 -e file 求值为真的话,则要么 file 存在要么 file 为一软连接文件并指向另一存在文件
-f file //如果文件为一个普通文件,则为真
-g file //如果设置了文件的 SGID 位,则为真
-G file //如果文件存在且文件的 group-id 和你的相同,则为真
-h file //文件是个符号链接
-k file //如果设置了文件的粘着位,则为真
-L file //文件是个符号链接
-N file //从文件最后被阅读到现在,是否被修改
-O file //如果文件存在并且归该用户所有,则为真
-p file //如果文件为一个命名管道,则为真
-r file //如果文件可读,则为真
-s file //如果文件的长度不为零,则为真
-S file //如果文件为一个套接字特殊文件,则为真
-t fd //如果 fd 是一个与终端相连的打开的文件描述符(fd 默认为 1),则为真
//一般都用来检测是否在一个给定脚本中的stdin[-t0]或[-t1]是一个终端
-u file //如果设置了文件的 SUID 位,则为真
-w file //如果文件可写,则为真
-x file //如果文件可执行,则为真
file1 -ef file2 //测试以判断两个文件是否与同一个设备相连,是否拥有相同的 inode 编号
file1 -nt file2 //测试以判断第一个文件是否比第二个文件更新(由修改日期决定)
file1 -ot file2 //测试以判断第一个文件是否比第二个文件更旧
string //测试以判断字符串是否不为空
-n string //测试以判断字符串是否不为空;字符串必须为 test 所识别,即 string 必须加" "
-z string //测试以判断字符串是否为空;字符串必须为 test 所识别
string1 = string2 //测试以判断 string1 是否与 string2 相同
string1 != string2 //测试以判断 string1 是否与 string2 不同
int1 -eq int2 //如果 int1 等于 int2,则为真
int1 -ge int2 //如果 int1 大于或等于 int2,则为真
int1 -gt int2 //如果 int1 大于 int2,则为真
int1 -le int2 //如果 int1 小于或等于 int2,则为真
int1 -lt int2 //如果 int1 小于 int2,则为真
int1 -ne int2 //如果 int1 不等于 int2,则为真
str1 = str2
str1 \> str2
str1 \< str2
str1 != str2
! expr //如果表达式评估为假,则为真
! true
expr1 -a expr2 //如果 expr1 和 expr2 评估为真,则为真
expr1 -o expr2 //如果 expr1 或 expr2 评估为真,则为真
[ expr1 ] && [ expr2 ]
[ expr1 ] || [ expr2 ]
[[ expression ]] // [[ 是keyword;[[ ]] 做算术运算(+ - * / %);不进行文件名扩展(进行模式匹配);需要用空格分隔各值和运算符
// [[ ]] 也能进行 [] 能进行的文件测试、数字测试、字符串测试
str1 = str2 //等号右端的str2支持通配符*、?,但是不能用引号括起
str1 > str2
str1 < str2
str1 != str2
! expr //如果表达式评估为假,则为真
expr1 && expr2 //如果 expr1 和 expr2 评估为真,则为真
expr1 || expr2 //如果 expr1 或 expr2 评估为真,则为真
[[ 99+1 -eq 100 ]] && echo true || echo false // [[ 可以进行算术运算扩展
(( expression )) //同let命令,对应的外部命令是expr;不需要用空格分隔各值和运算符
int1 >= int2
int1 > int2
int1 <= int2
int1 < int2
int1 != int2
int1 == int2
! expr //如果表达式评估为假,则为真
expr1 && expr2 //如果 expr1 和 expr2 评估为真,则为真
expr1 || expr2 //如果 expr1 或 expr2 评估为真,则为真
expr1 , expr2 //,用于连接多个算术运算
= //赋值
(( var=0 ))
? : //条件赋值
(( var= a<45 ? 1 : 0 ))
+ //加法
+= //加等于
- //减法
-= //减等于
* //乘法
*= //乘等于
/ //除法
/= //除等于
% //取模
%= //取模赋值
** //幂运算
++
(( var++ )) //先返回值再加 1
(( ++var )) //先加 1 再返回值
--
(( var-- ))
(( --var ))
<< //左移1 位(每次左移都将乘2)
<<= //左移几位,=号后边将给出左移几位
let "var <<= 2" //左移2 位(就是乘4)
>> //右移1 位(每次右移都将除2)
>>= //右移几位
& //按位与
&= //按位与赋值
| //按位或
|= //按位或赋值
^ //按位异或XOR
^= //异或赋值
~ //取补码
! //逻辑否
&& //逻辑与
if [ $condition1 ] && [ $condition2 ];
if [ $condition1 -a $condition2 ];
if [[ $condition1 && $condition2 ]];
|| //逻辑或
. //等价于 source 命令。source sourced-file 其实像是函数调用,sourced-file 也可以用 return 命令返回值
: //等价于 true 命令,也作为占位符使用
while : //等价于true命令
do
...
done
: ${username=`whoami`} //作为占位符使用
:> filename //若文件存在,清空文件;若文件不存在,创建之
:() { :|:& }; :
alias
alias -p // prints the list of aliases in the form alias NAME=VALUE on standard output
autoload //一个带有 autoload 声明的函数,在它第一次被调用的时候才会被加载以节省系统资源
// autoload 命令并不是 Bash 安装时候的核心命令的一部分。这个命令需要使用命令 enable -f 来加载
bind //显示或修改 readline 的键绑定
break
break N //退出 N 层循环
caller //用于函数或者 sourced-file
caller n
continue
continue N //将 N 层循环全部 continue
case string in "str1" | "str2" ) commands1;; "str3" ) commands2;; * ) commands3;; esac
cd
../..
~
/
- //把工作目录改为 $OLDPWD,就是之前的工作目录
-P // physical 选项,忽略符号连接
declare //与 typeset 完全一样
//注意:使用 declare 将会限制变量的作用域
-r //只读
declare -r
-i //整形,如果把一个变量指定为整形,那么即使没有 expr 和 let 命令,也允许使用特定的算术运算
n=6/3 // n 的值为 "6/3"
declare -i n; n=6/3 // n 的值为 2
-a //数组
-f //函数
declare -f //列出这个脚本中之前定义的所有函数的定义
declare -f function //列出函数 function 的定义
-x //export
dirs //列出目录栈的所有内容
echo
echo $path
echo -n string
echo -e '\n'
eval //将表达式中的参数或者表达式列表组合起来并评估它们,包含在表达式中的任何变量都将被扩展。如无必要使用,不推荐使用
eval arg1 [arg2] ... [argN]
eval var1=\$$var2
eval var1=\${$var2}
eval "var1=\${$var2}"
eval echo \$$var //间接引用 var
eval echo \${$var} //间接引用 var
eval "echo \${$var}" //间接引用 var
典型用法
command=`eval ls -l`; echo $command;
command="eval ls -l"; $command;
var_pointer=var; eval $var_pointer=value; //执行结果相当于执行了 var=value,该技术主要目的为向函数传递变量名
fun( ) { local var_pointer=$1; eval $var_pointer=value; }
fun var; //函数 fun 将对变量 var 赋值
exec //使用一个特定的命令来取代当前进程,也用于重新分配文件描述符
exec j>file //为了写 file,把文件 file 打开,并且分配 shell 脚本的文件描述符 j,默认值是 1
exec j<file //为了读 file,把文件 file 打开,并且分配 shell 脚本的文件描述符 j,默认值是 0
exec j<>file //为了读写 file,把文件 file 打开,并且分配 shell 脚本的文件描述符 j,默认值是 0
exec n>&- //关闭输出文件描述符 n,- 相当于 null 指针
exec n<&- //关闭输入文件描述符 n,- 相当于 null 指针
exec cmd.exe //以 cmd.exe 进程取代当前进程
exit //如果不带参数的使用 exit 来退出,那么退出码将是脚本中最后一个命令的退出码,等价于exit $?
exit 0
export //由export关键字处理过的变量叫做环境变量
for var in list; do ... ; done //如果在 for 循环的
-
中有通配符(*和?),那将会产生文件名扩展,也就是file globbing
for var; do ... ; done // wordlist 为 "$@",注意是带有 " " 的
for (( i=0; i<10; i++ )); do ... ; done | sort
for ((a=1, b=1; a <= 10; a++, b++)); do ... ; done
getopts //分析传递到脚本的命令行参数的最强力工具
// getopts 结构使用两个隐含变量。$OPTIND-参数指针(选项索引),$OPTARG-选项参数(可以在选项后边附加一个参数)
//在声明标签中,选项名后边的冒号用来提示这个选项名已经分配了一个参数
// getopts 循环处理完选项后,$1 引用的是命令行上的第一个非选项参数
hash
hash //列出所有已经被 hash 的命令
hash -r //重新设置 hash 表
help //获得 shell 内建命令的一个小的使用总结
help command //相当于外建命令的 command --help
history
if [ condition ]; then ...; else ... ; fi
if [ condition ]; then ...; elif [ condition ]; then ... ; else ... ; fi
let //执行变量的算术操作。在许多情况下,它被看作是复杂的 expr 版本的一个简化版
//只能进行两个整数间的运算,其结果仍为整数
let a=a+1
local
local var=value
printf //格式化输入输出命令,printf 默认不带回车,而 echo 默认带回车,语法与 C 语言类似
printf "hello,world\n"
%d //整数
%n.nf //浮点数
%s //字符串
pwd
pushd
pushd dir-name //把路径 dir-name 压入目录栈同时修改当前目录到 dir-name
pushd .
popd //将目录栈中最上边的目录弹出,同时修改当前目录到弹出来的那个目录
read //一个不带变量参数的 read 命令,将把来自键盘的输入存入到专用变量 $REPLY
read var1 var2
-t timeout
-r //使输入的 "\" 字符转义
-s //不打印输入
-nN //直接受 N 个字符的输入,不用打回车
-p "string" //读取输入之前打印出后边的提示符
IFS=: read name passwd uid gid fullname ignore //可以在 read 语句前自定义 IFS
readonly //同 declare -r
readonly var
return //Can be return from a function or sourced script
set //设置各种 bash shell 选项及修改内部脚本变量的值
//一个作用就是触发选项标志位来帮助决定脚本的行为,另一个应用就是重新设置脚本的位置参数
set //输出脚本定义的全部变量(包括环境变量)
set -- // unset 所有位置参数
set -- $var //解析变量 var 并且设置位置参数 $1,$2...
set -- "string1" "string2" //设置位置参数 $1,$2...
set -- `command` //设置位置参数 $1,$2...
+o //关闭
set +o
set +o allexport
set +a
-o //开启
set -o
set -o allexport
set -a
select var in list; do ... ; break; done // select 命令使用 PS3 提示符,默认为 #?
select var; do ... ; break; done // wordlist 为 "$@",注意是带有 " " 的
select var in list; do echo "Are you want to $var"; if [[ "$var" = "word2" ]]; then break; fi; done
shift
shift 2
shopt
shopt -s extglob // s -- set
shopt -u extglob // u -- unset
nullglob // * 与 . 在 file globbing 中如果没匹配到任何文件,就不进行扩展
source
time
time executablefile
times //给出执行命令所占用的时间
type
type command
type -a command //鉴别是关键字还是内建命令,也可以定位同名的系统命令
typeset //同 declare
test
true
unalias
unset //删除 shell 变量,对环境变量也有效,但对位置参数无效
until [ condition ]; do ... ; done
while [ condition ]; do ... ; done
while echo hello; [ condition ]; do ... ; done
while read line; do echo "$line"; done < data-file
相关阅读 更多 +