——概述)
一、shell功能分类一、登录ShellLogin Shell定义通过完整身份认证输入用户名/密码启动的Shell会话常见场景包括系统开机登录控制台SSH远程登录执行su - username切换用户核心特征加载系统级配置文件如/etc/profile加载用户级配置文件如~/.profile、~/.bash_profile环境变量初始化完整适用于全局会话设置可通过echo $0返回-bash带-前缀标识为登录Shell二、交互式ShellInteractive Shell定义用户通过终端实时输入命令并获得即时反馈的会话模式例如命令行终端如GNOME TerminalSSH登录后手动操作命令直接执行bash命令启动的新Shell核心特征持续等待用户输入命令支持命令行编辑、历史记录等交互功能加载用户级配置文件如~/.bashrc可能同时是登录Shell如SSH会话也可能是非登录Shell如在图形终端中直接启动或者执行bash命令三、非交互式ShellNon-interactive Shell定义无需用户实时操作自动执行预设命令的Shell模式典型场景包括执行Shell脚本如bash script.sh通过SSH远程执行单条命令如ssh host ls /系统定时任务cron job核心特征不加载交互式配置文件如~/.bashrc执行完毕立即退出无用户输入等待可能是登录或非登录Shell若通过ssh host command执行 →非登录Shell若通过ssh host script.sh执行 →登录Shell罕见场景四、关键差异总结特性登录Shell交互式Shell非交互式Shell身份认证必需不要求不要求配置文件加载/etc/profile~/.profile~/.bashrc通常不加载会话持续性持续持续执行后立即退出用户交互可交互或非交互必需交互无交互典型场景系统登录、su -终端操作、命令行脚本、远程命令shell程序位于/bin目录内。1、默认的交互shell定义用户登录时默认使用的Shell解释器交互shellcat /etc/passwd2、ls -l /bin/sh - xxx 默认的系统shell脚本调用脚本首行指定所用shell 如 #!/bin/bash是推荐的做法因为它明确指定了脚本的解释器但并不是所有情况下都必须有。通过其他方式如显式调用解释器或依赖系统配置也可以执行没有shebang行的脚本。二、注释单行注释 #多行注释if false;then fi三、变量普通变量创建普通变量 nametest 两边不可有空格创建只可函数体中使用的局部变量 local nametest 使用local修饰的变量在函数体外无法访问并且local只能在函数体内使用使用变量 echo $name 或者 echo ${name} 推荐使用大括号版删除变量 unset name; 删除之后不可访问删除不掉只读变量参数传递获取参数值$0 固定代表执行的文件名$1 代表传入的第1个参数$n 代表传入的第n个参数$#参数个数$$脚本运行的当前进程号$后台运行的最后一个进程的ID$? 显示最后命令的退出状态。0表示没有错误其他任何值表明有错误。$* 与 $ 区别相同点都是引用所有参数。不同点只有在双引号中体现出来。假设在脚本运行时写了三个参数 1、2、3$* :以一个单字符串显示所有向脚本传递的参数等价于 1 2 3传递了一个参数 等价于 1 2 3传递了三个参数。引号的使用单引号单引号中的任何字符都会原样输出单引号字符串中的变量是无效的。双引号可以将变量比如$USER放置到双引号中而shell依然能够知道我们的意图可以使用转义字符\将$转义可以作为命令的分割例如watch -n 10 cat /proc/meminfo meminfo.log数组Shell 数组用括号来表示元素用空格符号分割开语法格式如下array_name(value1 value2 ... valuen)也可以用下标来定义数组array_name[0]value0array_name[1]value1array_name[2]value2引用数组${array_name[index]}使用 或 * 可以获取数组中的所有元素#!/bin/bashmy_array[0]Amy_array[1]Bmy_array[2]Cmy_array[3]Decho 数组的元素为: ${my_array[*]}echo 数组的元素为: ${my_array[]}获取数组的长度my_array[0]Amy_array[1]Bmy_array[2]Cmy_array[3]Dstrabcdefgecho 数组元素个数为: ${#my_array[*]}echo 数组元素个数为: ${#my_array[]}echo 字符串个数为 ${#str}四、退出脚本Linux提供了一个专门的变量$?来保存上个已执行命令的退出状态码。对于需要进行检查的命令必须在其运行完毕后立刻查看或使用$?变量。echo $? 查看退出状态码。默认情况下shell脚本会以脚本中的最后一个命令的退出状态码退出。exit命令允许你在脚本结束时指定一个退出状态码。exit 4五、符号总结命令替换即将命令的结果赋值给变量testingdate 反引号testing$(date) 一定要加括号 推荐使用这个命令替换会创建一个子shell来运行对应的命令执行数学运算方式一使用expr命令expr 1 2var$(expr 1 2) 有些需要转义比如expr 1 \* 5 在shell脚本中需要命令替换因为返回的命令输出方式二var1$[1 5]var2$[$var1 4]返回的不是命令输出即不用命令替换在使用方括号来计算公式时不用担心shell会误解乘号或其他符号。shell知道它不是通配符因为它在方括号内。方式三 :(())浮点数解决方案使用bc作用详细作用常用区域 反引号命令替换即将命令的结果赋值给变量testingdate$( )命令替换即将命令的结果赋值给变量testing$(date)${ }仅仅是为了{}中的内容保持完整expr 1 2数字运算由于是命令返回所以需要命令替换var$(expr 1 2)$[$var1 4]数字运算var2$[$var1 4](( ))数字运算((var 1 4))if (( $var 2 ))for(( ))1、赋值2、判断表达式包括if while 成立返回1 不成立返回03、C语言风格的for循环[]条件判断if [ condition ]判断表达式数字、文件、字符串[[]]六、不同的方式调用脚本1、用sh filename与./filename执行脚本是没有区别的。重新建立一个子shell在子shell中执行脚本里面的语句。该子shell继承父shell的环境变量但子shell新建的、改变的变量不会被带回父shell。虽然shebang行如 #!/bin/bash是推荐的做法因为它明确指定了脚本的解释器但并不是所有情况下都必须有。通过其他方式如显式调用解释器或依赖系统配置也可以执行没有shebang行的脚本。2、使用source filename和. filename.后面有空格是等价了这两个命令其实只是简单地读取脚本里面的语句依次在当前shell里面执行没有建立新的子shell。那么脚本里面所有新建、改变变量的语句都会保存在当前shell里面。这对于包含环境变量设置的脚本特别有用。