一、shell 简介
Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。
Shell 既是一种命令语言,又是一种程序设计语言。
Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。

1.Shell 脚本
Shell 脚本(shell script),是一种为 shell 编写的脚本程序。
什么是脚本语言?
脚本语言是像剧本一样教计算机办某个事情的语言,
这类程序可以用文本编辑器修改,不需要编译,通常是解释运行的。

2.Shell 环境
Linux 的 Shell 种类众多,常见的有:
Bourne Shell(/usr/bin/sh或/bin/sh)
Bourne Again Shell(/bin/bash)
C Shell(/usr/bin/csh)
K Shell(/usr/bin/ksh)
Shell for Root(/sbin/sh)
……
Bash(Bourne Again Shell)是日常工作中使用最广泛的,也是大多数Linux 系统默认的 Shell。
在一般情况下,并不区分 Bourne Shell 和 Bourne Again Shell,
所以,像 #!/bin/sh,它同样也可以改为 #!/bin/bash。
#! 告诉系统其后路径所指定的程序即是解释此脚本文件的 Shell 程序。

3.第一个shell脚本
打开文本编辑器(可以使用 vi/vim 命令来创建文件),
新建一个文件 hello.sh,扩展名为 sh(sh代表shell),扩展名并不影响脚本执行。
cat > hello.sh <<!
实例
#!/bin/bash
echo "Hello World !"
#! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell。
echo 命令用于向窗口输出文本。

4.运行 Shell 脚本有两种方法:
4.1 作为可执行程序
将上面的代码保存为 hello.sh,并 cd 到相应目录:
chmod u+x ./hello.sh #使脚本具有执行权限
./hello.sh #执行脚本
注意,一定要写成 ./hello.sh,而不是 hello.sh,运行其它二进制的程序也一样,
直接写 hello.sh,linux 系统会去 PATH 里寻找有没有叫 hello.sh 的,
而只有 /bin, /sbin, /usr/bin,/usr/sbin 等在 PATH 里,
当前目录通常不在 PATH 里,所以写成 hello.sh 是会找不到命令的,
要用 ./hello.sh 告诉系统说,就在当前目录找。

4.2 作为解释器参数
这种运行方式是,直接运行解释器,其参数就是 shell 脚本的文件名,如:
/bin/sh hello.sh
这种方式运行的脚本,不需要在第一行指定解释器信息,写了也没用。

二、shell变量
1.定义变量
your_name="lw"
注意:变量名和等号之间不能有空格。
变量名的命名须遵循如下规则:
首个字符必须为字母(a-z,A-Z)。
中间不能有空格,可以使用下划线(_)。
不能使用标点符号。
不能使用bash里的关键字(可用help命令查看保留关键字)。

2.使用变量
使用一个定义过的变量,只要在变量名前面加美元符号即可,如:
your_name="lw"
echo $your_name
例子:
cat > your_name.sh <<!
#!/bin/bash
your_name="lw"
echo $your_name

chmod u+x ./your_name.sh #使脚本具有执行权限
./your_name.sh #执行脚本

变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界.
echo ${your_name}
已定义的变量,可以被重新使用:
#!/bin/bash
your_name="lw"
echo ${your_name}
your_name="alibaba"
echo ${your_name}

3.只读变量
使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。
尝试更改只读变量,结果报错:your_name: 只读变量
#!/bin/bash
your_name="lw"
echo ${your_name}
readonly your_name
your_name="alibaba"
echo ${your_name}

4.删除变量
使用 unset 命令可以删除变量。语法:
unset variable_name
变量被删除后不能再次使用。unset 命令不能删除只读变量。

#!/bin/bash
your_name="lw"
echo ${your_name}
#readonly your_name
unset your_name
echo ${your_name}

5.变量类型
运行shell时,会同时存在三种变量:
5.1 局部变量
局部变量在脚本或命令中定义,仅在当前shell实例中有效,
其他shell启动的程序不能访问局部变量。
5.2 环境变量
所有的程序,包括shell启动的程序,都能访问环境变量,
有些程序需要环境变量来保证其正常运行。
必要的时候shell脚本也可以定义环境变量。
5.3 shell变量
shell变量是由shell程序设置的特殊变量。
shell变量中有一部分是环境变量,有一部分是局部变量,
这些变量保证了shell的正常运行

6.Shell 字符串
字符串是shell编程中最常用最有用的数据类型(数字和字符串),
字符串可以用单引号,也可以用双引号,也可以不用引号。
6.1 单引号
your_name='lw'
单引号字符串的限制:
单引号里的任何字符都会原样输出,
单引号字符串中的变量是无效的;
单引号字串中不能出现单引号(对单引号使用转义符后也不行)。

6.2 双引号
双引号的优点:
双引号里可以有变量
双引号里可以出现转义字符
cat > your_name3.sh <<!
#!/bin/bash
your_name='lw'
echo "hello,${your_name}!"
#echo "Hello, \"$your_name\"! \n"

6.3 拼接字符串
6.4 # 获取字符串长度
cp your_name3.sh your_name4.sh

#!/bin/bash
your_name="lw"
string=hello
echo $string $your_name
echo ${#string}
echo ${#your_name}

6.5 : 提取子字符串
从字符串第 2 个字符开始截取 4 个字符:
#!/bin/bash
string="hello lw!"
echo ${string:1:4} # 输出 ello

6.6 查找子字符串
查找字符 "e" 的位置:
#!/bin/bash
string="hello lw!"
echo `expr index "$string" e` # 输出 2
注意: 以上脚本中 "`" 是反引号,而不是单引号 "'".
cp your_name4.sh your_name5.sh
vi your_name5.sh
#!/bin/bash
string="hello lw!"
echo ${string:1:4}
echo `expr index "$string" e`

7.Shell 注释
以"#"开头的行就是注释,会被解释器忽略。
每一行加一个#号可以注释一行;
sh里没有多行注释,可以把这一段要注释的代码用一对花括号括起来,
定义成一个函数,没有地方调用这个函数,这块代码就不会执行,达到了和注释一样的效果。

8.字符串截取的八种方法:
假设有变量 var=http://www.aaa.com/123.htm
8.1 从左边第几个字符开始,及字符的个数
echo ${var:0:5}
其中的 0 表示左边第一个字符开始,5 表示字符的总个数。
结果是:http:

8.2 从左边第几个字符开始,一直到结束。
echo ${var:7}
其中的 7 表示左边第8个字符开始,一直到结束。
结果是 :www.aaa.com/123.htm

8.3 从右边第几个字符开始,及字符的个数
echo ${var:0-7:3}
其中的 0-7 表示右边算起第七个字符开始,3 表示字符的个数。
结果是:123

8.4 从右边第几个字符开始,一直到结束。
echo ${var:0-7}
表示从右边第七个字符开始,一直到结束。
结果是:123.htm
注:(左边的第一个字符是用 0 表示,右边的第一个字符用 0-1 表示)

#、## 表示从左边开始删除。
一个 # 表示从左边删除到第一个指定的字符;
两个 # 表示从左边删除到最后一个指定的字符。
%、%% 表示从右边开始删除。
一个 % 表示从右边删除到第一个指定的字符;
两个 % 表示从右边删除到最后一个指定的字符。
删除包括了指定的字符本身。

8.5 # 号截取,删除左边字符,保留右边字符。
echo ${var#*//}
其中 var 是变量名,# 号是运算符,*// 表示从左边开始删除第一个 // 号及左边的所有字符
即删除 http://
echo ${var#*/}
结果是 :/www.aaa.com/123.htm

8.6 ## 号截取,删除左边字符,保留右边字符。
echo ${var##*/}
##*/ 表示从左边开始删除最后(最右边)一个 / 号及左边的所有字符
即删除 http://www.aaa.com/
结果是 123.htm

8.7 %号截取,删除右边字符,保留左边字符
echo ${var%/*}
%/* 表示从右边开始,删除第一个 / 号及右边的字符
结果是:http://www.aaa.com

8.8 %% 号截取,删除右边字符,保留左边字符
echo ${var%%/*}
%%/* 表示从右边开始,删除最后(最左边)一个 / 号及右边的字符
结果是:http:

三、shell传递参数
1.传递参数
在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$n。
n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推……
cp your_name.sh parameter.sh
#!/bin/bash
echo "hello $1";
调用: ./parameter.sh lw

2.参数处理
$# 传递到脚本的参数个数
$* 以一个单字符串显示所有向脚本传递的参数,以"$1 $2 … $n"的形式输出所有参数。
$@ 与$*相同,但是使用时加引号(如"$@"),并在引号中返回每个参数"$1“ ”$2“ … ”$n"。
$* 与 $@ 区别:
相同点:都是引用所有参数。
不同点:只有在双引号中体现出来。
假设在脚本运行时写了三个参数 1、2、3,,
则 " * " 等价于 "1 2 3"(传递了一个参数),
而 "@" 等价于 "1" "2" "3"(传递了三个参数)。
cp prameter.sh prameter2.sh
#!/bin/bash
echo "$1";
echo "$2";
echo "$#";
echo $*;
for i in "$*"; do
echo $i
done
echo "$@";
for i in "$@"; do
echo $i
done
调用: ./prameter2.sh lw 1123 null

四、shell 运算符
shell运算符分为6类,包括:
算术运算符
关系运算符
布尔运算符
逻辑运算符
字符串运算符
文件测试运算符

原生bash不支持简单的数学运算,但是可以通过expr命令来实现。
expr 是一款表达式计算工具,使用它能完成表达式的求值操作。
例如,两个数相加(注意使用的是反引号 ` 而不是单引号 '):
#!/bin/bash
val=`expr 2 + 2`
echo "两数之和为 : $val"
两点注意:
表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2。
完整的表达式要被 ` ` 包含,注意这个字符不是常用的单引号,在 Esc 键下边。

1.算术运算符
下表列出了常用的算术运算符,假定变量 a 为 10,变量 b 为 20:
+ 加法 `expr $a + $b` 结果为 30。
- 减法 `expr $a - $b` 结果为 -10。
* 乘法 `expr $a \* $b` 结果为 200。 乘号(*)前边必须加反斜杠(\)才能实现乘法运算
/ 除法 `expr $b / $a` 结果为 2。
% 取余 `expr $b % $a` 结果为 0。
在 MAC 中 shell 的 expr 语法是:$((表达式)),此处表达式中的 "*" 不需要转义符号 "\" 。

= 赋值 a=$b 将把变量 b 的值赋给 a。
== 相等。 用于比较两个数字,相同则返回 true。 [ $a == $b ] 返回 false。
!= 不相等。 用于比较两个数字,不相同则返回 true。 [ $a != $b ] 返回 true。
注意:条件表达式要放在方括号之间,并且要有空格,
例如: [$a==$b] 是错误的,必须写成 [ $a == $b ]。

算术运算符实例如下:
#!/bin/bash
a=10;
b=20;
val=`expr $a + $b`;
echo "a + b : $val";

val=`expr $a - $b`;
echo "a - b : $val";

val=`expr $a \* $b`;
echo "a * b : $val";

val=`expr $b / $a`;
echo "b / a : $val";

val=`expr $b % $a`;
echo "b % a : $val";

if [ $a == $b ]
then
echo "a 等于 b";
elfi [ $a != $b ]
then
echo "a 不等于 b"
fi

#!/bin/bash
a=10;
b=20;
echo "a+b= $((a+b))";
echo "a-b= $((a-b))";
echo "a*b= $((a*b))";
echo "b/a= $((b/a))";
echo "a%3= $((a%3))";

2.关系运算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
下表列出了常用的关系运算符,假定变量 a 为 10,变量 b 为 20:
-eq == 检测两个数是否相等,相等返回 true。 [ $a -eq $b ] 返回 false。
-ne != 检测两个数是否不相等,不相等返回 true。 [ $a -ne $b ] 返回 true。
-gt > (结果错) 检测左边的数是否大于右边的,如果是,则返回 true。 [ $a -gt $b ] 返回 false。
-lt < (结果错) 检测左边的数是否小于右边的,如果是,则返回 true。 [ $a -lt $b ] 返回 true。
-ge >=(报错) 检测左边的数是否大于等于右边的,如果是,则返回 true。 [ $a -ge $b ] 返回 false。
-le <=(报错) 检测左边的数是否小于等于右边的,如果是,则返回 true。 [ $a -le $b ] 返回 true。

eq 就是 equal等于
ne 就是 not equal不等于
gt 就是 greater than大于 
lt 就是 less than小于
ge 就是 greater than or equal 大于等于
le 就是 less than or equal 小于等于

关系运算符实例如下:
#!/bin/bash
a=10;
b=20;
if [ $a -eq $b ]
then
echo "$a -eq $b : a 等于 b"
else
echo "$a -eq $b: a 不等于 b"
fi
if [ $a -ne $b ]
then
echo "$a -ne $b: a 不等于 b"
else
echo "$a -ne $b : a 等于 b"
fi
if [ $a -gt $b ]
then
echo "$a -gt $b: a 大于 b"
else
echo "$a -gt $b: a 不大于 b"
fi
if [ $a -lt $b ]
then
echo "$a -lt $b: a 小于 b"
else
echo "$a -lt $b: a 不小于 b"
fi
if [ $a -ge $b ]
then
echo "$a -ge $b: a 大于或等于 b"
else
echo "$a -ge $b: a 小于 b"
fi
if [ $a -le $b ]
then
echo "$a -le $b: a 小于或等于 b"
else
echo "$a -le $b: a 大于 b"
fi

3.布尔运算符
下表列出了常用的布尔运算符,假定变量 a 为 10,变量 b 为 20:
! 非运算,表达式为 true 则返回 false,否则返回 true。 [ ! false ] 返回 true。
-o 或运算,有一个表达式为 true 则返回 true。 [ $a -lt 20 -o $b -gt 100 ] 返回 true。
-a 与运算,两个表达式都为 true 才返回 true。 [ $a -lt 20 -a $b -gt 100 ] 返回 false。

布尔运算符实例如下:
#!/bin/bash
a=10
b=20
if [ $a != $b ]
then
echo "$a != $b : a 不等于 b"
else
echo "$a != $b: a 等于 b"
fi
if [ $a -lt 100 -a $b -gt 15 ]
then
echo "$a 小于 100 且 $b 大于 15 : 返回 true"
else
echo "$a 小于 100 且 $b 大于 15 : 返回 false"
fi
if [ $a -lt 100 -o $b -gt 100 ]
then
echo "$a 小于 100 或 $b 大于 100 : 返回 true"
else
echo "$a 小于 100 或 $b 大于 100 : 返回 false"
fi
if [ $a -lt 5 -o $b -gt 100 ]
then
echo "$a 小于 5 或 $b 大于 100 : 返回 true"
else
echo "$a 小于 5 或 $b 大于 100 : 返回 false"
fi

4.逻辑运算符
以下介绍 Shell 的逻辑运算符,假定变量 a 为 10,变量 b 为 20:
&& 逻辑的 AND [[ $a -lt 100 && $b -gt 100 ]] 返回 false
|| 逻辑的 OR [[ $a -lt 100 || $b -gt 100 ]] 返回 true

逻辑运算符实例如下:
#!/bin/bash
a=10
b=20
if [[ $a -lt 100 && $b -gt 100 ]]
then
echo "返回 true"
else
echo "返回 false"
fi

if [[ $a -lt 100 || $b -gt 100 ]]
then
echo "返回 true"
else
echo "返回 false"
fi

5.字符串运算符
下表列出了常用的字符串运算符,假定变量 a 为 "abc",变量 b 为 "efg":
= 检测两个字符串是否相等,相等返回 true。 [ $a = $b ] 返回 false。
!= 检测两个字符串是否不相等,不相等返回 true。 [ $a != $b ] 返回 true。
-z 检测字符串长度是否为0,为0返回 true。 [ -z $a ] 返回 false。
-n 检测字符串长度是否不为0,不为0返回 true。 [ -n $a ] 返回 true。
str 检测字符串是否不为空,不为空返回 true。 [ $a ] 返回 true。

字符串运算符实例如下:
#!/bin/bash
a="abc"
b="efg"
if [ $a = $b ]
then
echo "$a = $b : a 等于 b"
else
echo "$a = $b: a 不等于 b"
fi
if [ $a != $b ]
then
echo "$a != $b : a 不等于 b"
else
echo "$a != $b: a 等于 b"
fi
if [ -z $a ]
then
echo "-z $a : 字符串长度为 0"
else
echo "-z $a : 字符串长度不为 0"
fi
if [ -n $a ]
then
echo "-n $a : 字符串长度不为 0"
else
echo "-n $a : 字符串长度为 0"
fi
if [ $a ]
then
echo "$a : 字符串不为空"
else
echo "$a : 字符串为空"
fi

6.文件测试运算符
文件测试运算符用于检测 Unix 文件的各种属性。
属性检测描述如下:
-b file 检测文件是否是块设备文件,如果是,则返回 true。 [ -b $file ] 返回 false。
-c file 检测文件是否是字符设备文件,如果是,则返回 true。 [ -c $file ] 返回 false。
-d file 检测文件是否是目录,如果是,则返回 true。 [ -d $file ] 返回 false。
-f file 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 [ -f $file ] 返回 true。
-p file 检测文件是否是有名管道,如果是,则返回 true。 [ -p $file ] 返回 false。

-r file 检测文件是否可读,如果是,则返回 true。 [ -r $file ] 返回 true。
-w file 检测文件是否可写,如果是,则返回 true。 [ -w $file ] 返回 true。
-x file 检测文件是否可执行,如果是,则返回 true。 [ -x $file ] 返回 true。
-s file 检测文件是否为空(文件大小是否大于0),不为空返回 true。 [ -s $file ] 返回 true。
-e file 检测文件(包括目录)是否存在,如果是,则返回 true。 [ -e $file ] 返回 true。
-g file 检测文件是否设置了 SGID 位,如果是,则返回 true。 [ -g $file ] 返回 false。
-k file 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 [ -k $file ] 返回 false。
-u file 检测文件是否设置了 SUID 位,如果是,则返回 true。 [ -u $file ] 返回 false。
变量 file 表示文件"/var/www/a.txt",具有 rwx 权限。
下面的代码,将检测该文件的各种属性:
#!/bin/bash
file="/home/lw/a.txt"
if [ -r $file ]
then
echo "文件可读"
else
echo "文件不可读"
fi
if [ -w $file ]
then
echo "文件可写"
else
echo "文件不可写"
fi
if [ -x $file ]
then
echo "文件可执行"
else
echo "文件不可执行"
fi
if [ -f $file ]
then
echo "文件为普通文件"
else
echo "文件为特殊文件"
fi
if [ -d $file ]
then
echo "文件是个目录"
else
echo "文件不是个目录"
fi
if [ -s $file ]
then
echo "文件不为空"
else
echo "文件为空"
fi
if [ -e $file ]
then
echo "文件存在"
else
echo "文件不存在"
fi

Linux_(3)Shell编程(上)的更多相关文章

  1. 末学者笔记--shell编程上 2 玄

    Shell编程-变量及表达运算 [内容简列] 1. shell变量简介 2. 定义变量 3. 使用变量 4. 修改变量的值 5. 单引号和双引号的区别 6. 将命令的结果赋值给变量 7. 删除变量 8 ...

  2. 末学者笔记--shell编程上 1 玄

    Shell 编程 [内容简列]: 1.shell简介 2. shell分类 3. 查看shell 4. 第一个shell脚本 5. shell编程常用命令 5.1 grep 5.2 cut 5.3 s ...

  3. sed命令详解 vim高级技巧 shell编程上

    第1章 sed命令详解 1.1 查找固定的某一行 1.1.1 awk命令方法 [root@znix ~]# awk '!/oldboy/' person.txt 102,zhangyao,CTO 10 ...

  4. shell编程上

    1.1  前言 1.1.1  为什么学Shell Shell脚本语言是实现Linux/UNIX系统管理及自动化运维所必备的重要工具, Linux/UNIX系统的底层及基础应用软件的核心大都涉及Shel ...

  5. 速查笔记(Linux Shell编程<上>)

    转载自: http://www.cnblogs.com/stephen-liu74/archive/2011/11/01/2202027.html 零.shell中的内部变量: 1.    $?:   ...

  6. Linux_(4)Shell编程(下)

    五.shell流程控制1.一重分支if 语句语法格式:if condition then command1 fi末尾的fi就是if倒过来. 写成一行: if condition; then comma ...

  7. 【转】Shell编程基础篇-上

    [转]Shell编程基础篇-上 1.1 前言 1.1.1 为什么学Shell Shell脚本语言是实现Linux/UNIX系统管理及自动化运维所必备的重要工具, Linux/UNIX系统的底层及基础应 ...

  8. Shell编程入门基础上

    前言 为什么学 Shell Shell 脚本语言是实现 Linux/UNIX 系统管理及自动化运维所必备的重要工具, Linux/UNIX 系统的底层及基础应用软件的核心大都涉及 Shell 脚本的内 ...

  9. Linux学习笔记(17) Shell编程之基础

    1. 正则表达式 (1) 正则表达式用来在文件中匹配符合条件的字符串,正则是包含匹配.grep.awk.sed等命令可以支持正则表达式:通配符用来匹配符合条件的文件名,通配符是完全匹配.ls.find ...

随机推荐

  1. 第五次Scrum冲刺

    第五次Scrum冲刺 1.成员今日完成情况 队员 今日完成任务 刘佳 前端初步构建 李佳 后端设计初级阶段 周世元 数据设计 杨小妮 博客编写 许燕婷 管理团队当日及次日任务 陈水莲 测试矩阵用例设计 ...

  2. Asp.Net WebApi 学习记录(一)

    刚创建的 Asp.Net Web Api 项目,在进行简单的测试时发现返回的 JSON 数据很丑陋.与平时我们使用的 JSON.NET 序列化出来的字符串不一样.通过下面的设置就可以了: // 清除所 ...

  3. Android sdk 目录结构说明

    1.add-on:附加的包:2.docs:HTML格式的离线文档:3.platforms:sdk核心内容:4.tool:工具. 在platforms中包含了的各个Android SDK版本的目录中,包 ...

  4. Linux下怎么创建和进入带有空格的文件夹

    有时候需要创建带有空格的文件夹,虽然这不是一个好的习惯,但是偶尔会遇到.用的最多的是很多时候需要进入带有空格的文件夹,如"a b"是一个文件夹名. 创建:mkdir "a ...

  5. 解题4(NumberToEnglish )

    题目描述 Jessi初学英语,为了快速读出一串数字,编写程序将数字转换成英文: 如22:twenty two,123:one hundred and twenty three. 说明: 数字为正整数, ...

  6. python学习 day23 面向对象三大特性之继承

    ### 面向对象三大特性值继承#### 1.什么是继承 继承是一种关系,必须存在两个对象才可能产生这种关系,在现实生活中的继承,王思聪可以继承王健林的财产 被继承的成为父,继承的一方成为子 在程序中, ...

  7. weechat 常用指令

    添加服务器: /server add freenode irc.freenode.org 设置nick: /set irc.server.freenode.nicks "mynick,myn ...

  8. SpringCloud报错: "Field discoveryClient in com.controller.DcController required a bean of type 'com.netflix.discovery.DiscoveryClient' that could not be found."

    SpringCloud报错: "Field discoveryClient in com.controller.DcController required a bean of type 'c ...

  9. Maven 基本参数

    -h,--help                              Display help information-am,--also-make                       ...

  10. 微信小程序开发——小程序API获取用户位置及异常流处理完整示例

    前言: 小程序需要添加一个定位功能,主要的就是获取用户位置的经纬度,然后根据用户经纬度进行一些判断操作. 在小程序提供的Api中,获取用户定位信息的主要Api是 wx.getLocation(obj) ...