1. Linux知识点
[TOC]
一个程序需要从外界获取输入,常见形式如下:
- 配置文件
- 环境变量
- 命令行参数。三者风格:
param=value-字母 value--字符串 value
- 交互式键盘输入
1.1.1. Linux常用快捷键
Tab:- 命令补全
- 文件名或目录名补全
- 连续按下两次
Tab,显示以输入字符开头的所有命令。
Ctrl+d:- 结束键盘输入
- 让用户离开文字界面,相当于输入exit
- 在命令行中向右删除,相当于按下Del键
Ctrl+c:- 结束当前正在运行的程序
- 取消当前命令行的编辑
Ctrl+l:终端清屏,刷新屏幕Ctrl+z:将正在运行的程序送到后台。Ctrl+r:搜索历史命令Ctrl+a:移动光标到所在行的行首Ctrl+e:移动光标到所在行的行尾Ctrl+u:擦除从当前光标位置到行首的全部内容Ctrl+k:擦除从当前光标位置到行尾的全部内容Ctrl+w:擦除光标位置前的单词(以空格划分);如果光标在一个单词本身上,它将擦除从光标位置到该单词词首的全部字母。ESC d: 先按ESC键,松开再按d,会删除光标后的一个单词。Ctrl+y:粘贴使用Ctrl+w,Ctrl+u和Ctrl+k快捷键擦除的文本。ESC+U: 将当前光标(包含当前)后的一个单词全部大写- `ESC+L : 将当前光标(包含当前)后的一个单词全部小写
1.1.2. shell执行命令流程
主要有以下前置工作:
文件名生成:
遵循通配符规则,按照字典序排列。如
ls *.c如果没有找到匹配文件,保持原文。如
ls *.c ls: cannot access *.c: No such file or directory
变量替换:如
ls $HOME命令替换:
- 使用反引号将命令括起来。如
now='date'(反引号不能显示,这里以单引号代替),以命令date的stdout替换date。 - (我的机器不支持)使用
${}:如now=${date},以命令date的标准输出替换${date}。
- 使用反引号将命令括起来。如
1.1.3. bash
自动执行的一批命令(用户级别):
- 当bash作为注册shell被启动时,会自动执行用户主目录下的
~/.bash_profile文件中的命令。 - 当bash作为注册shell在退出时,会自动执行用户主目录下的
~/.bash_logout。 - 当bash作为交互式shell启动时,会自动执行用户主目录下的
~/.bashrc。
自动执行的一批命令(系统级别):
- 当bash作为注册shell被启动时,会自动执行用户主目录下的
/etc/profile文件中的命令。 - 当bash作为注册shell在退出时,会自动执行用户主目录下的
/etc/logout。 - 当bash作为交互式shell启动时,会自动执行用户主目录下的
/etc/bashrc。
1.1.4. bash历史
历史记录表存储在 ~/.bash_history .
如果想要修改历史记录表的大小,需要在 ~/.bashrc 中修改 HISTSIZE 变量。
浏览历史命令:
- 直接使用上下方向键
!!:引用上一命令!str:以str开头的最近用过的命令Ctrl+r:搜索历史命令
1.1.5. 别名
可以为linux命令定制别名(alias):
alias rm='rm -i':新增别名。可以将其写入到~/.bashrc中。alias:查看别名表unalias rm:取消别名
1.1.6. bash补全
Tab键:
- 每行的首个单词:可以补全搜索
$PATH下的命令。 - 行中的其他单词:补全当前目录下的文件名。
1.1.7. bash脚本
变量名:
- 第一个字符必须是字母、下划线
- 其余字符可以是字母、数字、下划线
变量赋值:addr=172.31.3.1。等号左右两边不能有空格。
引用变量:$addr 、${addr}
引用未定义的变量,变量值为空字符串。
赋值时,如果等号右侧字符串中有特殊字符,如空格,需要将整个字符串使用双引号括起来。
shell内部开关:
set +u或set -u:使用加号时,如果引用了一个未被定义的变量,会被认为是空串(默认情况)。使用减号是,如果引用未定义变量,会产生一个错误。set +x或set -x:减号表明,执行命令前打印出shell替换后变量后的命令及参数(为了区别正常输出,会在该打印前加上+)。加号则取消上述设置。
变量类型:
- 局部变量:所创建的shell变量,默认为局部变量。
- 环境变量:使用
export命令可以将局部变量转为环境变量。常见环境变量:- LANG:语言选择
- HOME:主目录
- TERM:终端 类型
- PATH:可执行文件的查找路径
- CLASSPATH :类库查找路径
- CVSROOT:
shell启动的子进程会继承环境变量,不会继承局部变量。
子进程中对环境变量的修改,不影响父进程中的同名变量。
列出当前变量:
set:内部命令,列出当前所有变量及其值,以及函数定义。env:外部命令,列出所有环境变量。
shell内部变量(位置参数):
$0:脚本文件本身的名字。$1/$2:1号命令参数,2号命令参数,以此类推$#:命令行参数的个数,不包括脚本文件名。"$*":等同于"$1 $2 $3 ...""$@":等同于"$1" "$2" "$3" ...$?:命令执行后返回的状态$$:当前进程的进程号- ?
%!:后台运行的最后一个进程号
内部命令:
shift:位置参数的移位操作,$#的值减1,旧的$2变成$1, 旧的$3变成$2。shift 3:移动3位
1.1.8. shell元字符
- 空格、制表符:命令行参数的分隔符
- 回车:执行键入的命令
- <>|:重定向与管道
;:用于一行内输入多个命令&:后台运行$:引用shell变量- 反向单引号:用于命令替换
*[]?:文件通配符\:取消后继字符的特殊作用(转义)。如果反斜线加在非元字符前面,跟没有一样。():用于定义shell函数,或在子shell中执行一组命令
()><|;& 等除了它们自身的特殊含义外,还同时起到分隔符的作用 (同空格 )
元字符:
- 单引号:对所括起的任何字符,不作特殊解释。系统从扫描到单引号开始,停止对所有字符的特殊解释,直到再次遇到单引号。
- 双引号:除
$和反向单引号之外,其他特殊字符的特殊含义被取消 - 反向单引号:只有自身和反斜线是需要特殊对待的,将反撇号和反斜线再使用反斜线进行转义。
1.1.9. 命令中的条件判断
使用 $? 可以获取上一条linux命令的执行情况。0表示正常运行,非0表示出错。
用管道线连接在一起的若干命令 ,进行条件判断时以最后一个命令执行的返回码为准。
复合逻辑:
cmd1 && cmd2:若cmd1执行成功(返回0)则执行cmd2,否则不执行。cmd1 || cmd2:cmd执行失败(返回非0)则执行cmd2,否则不执行cmd2.
/bin/true总返回0,/bin/false总返回非0。
test命令:/usr/bin/test ,与 /usr/bin/\[(该命令必须以]结尾)的效果相同。
test选项:
| 选项 | -f | -d | -r | -w | -x | -s |
|---|---|---|---|---|---|---|
| 含义 | 普通文件 | 目录文件 | 可读 | 可写 | 可执行 | size>0 |
字符串比较:[ str1 = str2 ] / [ str1 != str2 ],注意在方括号、等号周围都有空格。
整数比较:
| 选项 | -eq | -ne | -gt | -ge | -lt | -le |
|---|---|---|---|---|---|---|
| 含义 | 等于 | 不等于 | 大于 | 大于等于 | 小于 | 小于等于 |
例:test 'ls | wc -l' -ge 100 && echo "Too many files",框住ls命令的是反向单引号。
逻辑运算:! 非、-o或、 -a 与。
例:[ ! -d $cmd -a -x $cmd ] && $cmd
1.1.10. 命令组合
{ list; }:在当前shell中执行一组命令。(list):在子shell中执行一组命令。
左花括号后面必须有一个空格。圆括号是 shell元字符,花括号不是,它作为一个特殊内部命令处理。所以必须是一行的行首单词。
[ -f core ] && {
echo "rm core"
rm core
}
[ -f core ] && { echo "rm core";rm core;}
1.1.11. 控制流程
if condition
then list # if 不能和 then 合并成一行。除非加分号
elif condition
then list
else
list
fi
case:
case word in
pattern1) list1;; # 两个分号是一个整体
pattern2) list2;;
...
esac
while:
while condition
do list
done
until condition
do list
done
for
for name in word1 word2 ...
do list
done
for name # 相当于for name in $1 $2 ...
do list
done
for i in `seq 1 10` # 产生1到10
内部命令:
break:用于for、while结构,终止循环continue:结束本轮循环exit:结束脚本程序的执行,退出。参数为该进程执行结束后的返回码。
函数:
name() {list; return 0;}
参数引用:
- 函数定义完成之后,该函数名作为一个自定义内部命令执行,后面可以调用
- 调用时函数名后附加0到多个参数,在函数内部以
$1 $1 $* $@进行引用。
shell 不支持除字符串以外的数据类型,不支持加减乘等算运和关于字符串的正则表达式运算。
可以借助可执行程序/usr/bin/expr 实现。
有的 shell (包括 bash )为了提高执行效率,供内部命令版本 echo、printf、expr、echo、 test、[ 等命令,但这仅仅是一种优化措施。只依赖外部命令完全可以实现。
expr命令:
- 括号
- 算术运算(5种):
+-*/% - 关系运算(6种):
>/>=/</<=/=/!= - 逻辑运算(2种):或
|、与&。 - 正则表达式运算:冒号
string : pattern,pattern匹配字符串,打印匹配长度。冒号左右有空格- pattern中用
\(和\)括起来的一部分,能匹配时打印括号内匹配的部分,否则为空字符串。
- pattern中用
1.1.12. 调试shell程序
在Shell脚本程序的编写过程中难免会出现这样或那样的错误,错误是在所难免的,主要是要学会快速查找和改正错误。本小节介绍Shell脚本编写过程中的一般错误和程序的调试与跟踪方法。
一般错误:
- 输入错误:如输入了错误的关键字、成对的符号漏输入一部分等。
- 字符大小写:在Linux中,对大小写字符是严格区分的,输入时需要注意。所有关键字都是使用小写字母来表示的,建议变量名使用大写字母组合来表示。
- 循环错误:由于Shell中的循环控制语句与一般高级程序设计语言有所不同,输入结构时容易出错。
调试跟踪:
-n:bash命令的“-n”选项使Shell不执行脚本,仅检查脚本中的语法问题。-v:bash命令的“-v”选项使Shell在执行程序过程中,将读入的每一个命令行都原样输出到终端。-x:bash命令的“-x”选项使Shell在执行程序过程中,把执行的每一个命令在行首用一个“+”号加上对应的命令显示在终端上,并把每一个变量和该变量的值也显示出来。使用该选项更方便跟踪程序的执行过程。
1.1.13. xx
printf '%s\n' $HOME : 要使用单引号。
read name:从用户输入中获取一行内容,赋值给变量name。