1、注释符#
除了#!/bin/bash里的#特殊
2、美元符 $
变量符。与反斜杠转义符相反,使其后的普通字符作为变量名,如$a表示变量a的值。变量字符长度超过1个时,用{}括起来
3、单引号
被引起的字符全部做普通字符,即全部原样
echo ‘my $SHELL’
4、双引号
引号内的内容,除$、转义符\、倒引号`这三个保留特殊功能,其他字符均做普通字符。
5、倒引号(数字1键旁边的那个键)
引号内的字符串当做shell命令行解释执行,得到的结果取代整个倒引号括起来的部分。
6. 反斜线
反斜线是转义字符,它能把特殊字符变成普通字符。在某个字符前面利用反斜杠(\)能够阻止shell把后面的字符解释为特殊字符。
例4:
[yuqun@yuqun ~]$echo “Filename is N0\$\*”
Filename is N0$*
- 本地变量 (局部变量、用户变量)局部变量只在创建它们的Shell中使用,可以在shell程序内任意使用和修改它们。
u本地变量 在用户现在的shell生命期的脚本中使用u 变量名=值注意:
(1)等号两边不可以有空格
(2)取值包含空格,必须用双引号括起来
(3)Shell变量可以用大小写字母,区分大小写
u变量的声明和使用:(1)变量是弱类型的(不用声明类型)
(2)变量声明及赋值格式
变量=值(等号两边不能有空格)
(3)变量的引用
$变量名
${变量名}
变量名为1个字符时建议使用方式一,多余一个字符时建议使用方式二
举例: $a
${abc}
- 环境变量 可以在创建它们的Shell及其派生出来的任意子程序中使用。
有些变量是用户创建的,其他的则是专用的(比如PATH、HOME)。是系统环境的一部分,不必去定义它们,可以在shell程序中使用它们 。还能在shell中加以修改。
- 内部变量 (内置变量)由系统提供的。与环境变量不同,但用户不能修改它们。
内部变量是Linux所提供的一种特殊类型的变量,这类变量在程序中用来作出判断。在shell程序内这类变量的值是不能修改的。
部分内部变量是:
$# ——传送给shell程序的位置参数的数量$?——最后命令的完成码或者在shell程序内部执行的shell程序(返回值)$0——shell程序的名称$*——调用shell程序时所传送的全部参数的单字符串, “参数1”“参数2”…形式保存的参数
$@ “参数1”“参数2”…形式保存的参数$n 第n个参数$$ 本程序的PID$! 上一个命令的PID例子:
- 位置参数:
(1) 位置参数及引用(其实这个就是java和python当中的, sys.arg[]获取的过程,是一个意思)
可以编写一个shell脚本,当从命令行或者从其他shell脚本中调用它的时候,这个脚本接收若干参数。
这些选项是通过Linux作为位置参数(positional parameter)提供给shell程序的。
在shell脚本中应有变量,接收实参,这类变量的名称很特别,分别是1,2,3,…,这类变量称为位置变量。
位置参数1存放在位置变量1中,位置参数2存放位置变量2中,……,在程序中可以使用$1,$2,……来访问
-----Shell变量表达式:
test n1 -参数 n2(或 –参数 表达式)
真返回0,假返回1。
(1)整数,比较运算符见右表
test 1 –lt 4 #判断1<4
echo $? #结果为0
·test语句的等价形式[ 1 –lt 4 ]
p可用中括号代替test,把表达式括起来实现判断注意表达式与中括号间有空格。
-lt 小于
-le 小于等于
-gt 大于
-ge 大于等于
-eq 等于
-ne 不等于
(2)文件测试:例子:
例子:检测从命令行输入的文件是否存在-f 存在且是普通文件
-d 存在且是目录
-s 存在且字节数大于0
-r 存在且可读
-w 存在且可写
-x 存在且可执行
如:test -d “mydoc”
判断mydoc是否是目录
(3)、字符串测试
test s 字符串s非空
test s1=s2 字符串s1等于s2
test s1!=s2 字符串s1不等于s2
test -z s 字符串长=0,即为空串
test -n 字符串长>0
(4)、其他参数
-a 逻辑与
-o 逻辑或
! 逻辑非
-----Shell控制流程:
简单举例 后面例子涉及的命令:pseq命令:产生1-9的数字序列比如 seq 1 4
pexpr命令:对表达式求值p[]直接求值命令:对被括起来的表达式求值
1.分支结构:表达式求值:
$ expr 1 + 3
$ expr 2 – 1
$ expr 1 \* 3 使用*要加转义符
$ echo `expr 1 + 3`
注意:表达式中,数字和运算符指教要有空格,出现在语句中要加反引号
2.循环结构:if [ $# -eq 0 ]
then
echo “输入了0个参数”
elif [ $# -lt 1 ]
then echo “输入了多个参数”
else echo “输入了1个参数”
fi
for 例子——输出100内10的倍数(亲测有效)for i in `seq 1 9`
do
echo `expr $i \* 10`
done
或写 echo $(expr $i \* 10)
可以从键盘上读取多个变量的值,用户输入数据时,以空格或者Tab键作为分隔。如果输入的数据个数不够,则从左到右对应赋值,没有输入的变量为空;如果输入的数据个数超了,则从左到右对应赋值,最后一个变量被赋予剩余的所有数据。
read a b
for i in `seq $a $b`
do
echo `expr $i \* 10`
done
输出a到b序列数各数的10倍数
i=1
sum=0
while [ $i –le 100 ]
do
sum=$[$sum+$i]
i=$[$i+1]
done
echo $sum
1 stdout标准输出2 stderr标准错误输出重定向到文件file,终端上只能看到标准错误:
#命令 >file错误重定向到文件file ,终端上只能看到标准输出:
#命令 2>file标准输出和标准错误都重定向到file,终端上看不到任何信息:
#命令 >file 2>&1(等于#命令 1>file 2>&1)
例子: 很经典
ps:
1)command >file 2>file
2)command >file 2>&1
有什么区别?1)的写法,stdout和stderr都直接送到file中, 会出现两个同抢占file的管道,file会被打开两次,stdout和stderr输出的信息会互相覆盖。
2)的写法将stdout直接送向file, stderr继承1的管道后,再被送往file,此时,file 只被打开了一次,也只使用了一个管道FD1,它包括了stdout和stderr的内容。
从IO效率上,前一条命令的效率要比后面一条的命令效率要低,所以在编写shell脚本的时候,常用command > file 2>&1 这样的写法。
举例:配置java环境变量可使任何目录都能执行javac命令(1)需要配置Java环境变量
JAVA_HOME(JDK存放的路径)CLASSPATH(字节码的位置,让JVM知道要运行的类的字节码放在哪)PATH (让OS找到javac等命令的存放的位置)(2)在Linux下配置它们
打开终端vi .bash_profile (配置用户自己的环境变量,在对应/home/用户名下/.bash_profile)(.开头为隐藏文件)vi /etc/profile 这个是全局的,所有用户都好使
在配置文件中追加内容JAVA_HOME=JDK存放位置
CLASSPATH=.(当前目录)
PATH=$JAVA_HOME/BIN:$PATH(不覆盖原来的内容,追加)
export JAVA_HOME CLASSPATH PATH
保存,让配置起作用(source .bash_profile或者注销)
①编写一个名为iffile程序,它执行时判断/bin目录下date文件是否存在?②编写一个名为greet的问候程序,它执行时能根据系统当前的时间向用户输出问候信息。设从半夜到中午为早晨,中午到下午六点为下午,下午六点到半夜为晚上。③编写一个名为ifuser的程序,它执行时带用户名作为命令行参数,判断该用户是否已经在系统中登录,并给出相关信息。④编写一个名为menu的程序,实现简单的弹出式菜单功能,用户能根据显示的菜单项从键盘选择执行对应的命令。⑤编写一个名为chname的程序,将当前目录下所有的.txt文件更名为.doc文件。编写一个名为chuser的程序,执行中每隔5分钟检查指定的用户是否登录系统,用户名从命令行输入;如果指定的用户已经登录,则显示相关信息。(答案在PPT上,并在164重新写一遍)