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)
注意:
# 查看linux系统中shell位置:cat /etc/shells || cat /etc/shell
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash //常用
/usr/sbin/nologin
/bin/tcsh
/bin/csh //c语言风格
# 创建shell脚本文件
vi/vim fileName.sh
#!/bin/bash
echo "Hello World !"
注: shell中变量赋值没有空格,输出变量时,格式为echo $variableName
chmod +x ./test.sh #使脚本具有执行权限
# 方法一
./test.sh 或 .test.sh #执行脚本
# 方法二(适用于其他路径执行shell脚本)
/bin/bash /study/shell_study/my_first.sh
# 方法三(在当前进程中运行 Shell 脚本)
source filename 或者 . filename
或
bash /study/shell_study/my_second.sh
注:
# 在新进程中运行 Shell 脚本
bash test.sh
# 在当前进程中运行 Shell 脚本
. ./test.sh
备注:
1.作为解释器参数这种运行方式是,直接运行解释器,其参数就是 shell 脚本的文件名, 如:
/bin/sh test.sh
/bin/php test.php
2.循环linux下的目录时,注意引号"'",使用"`"。
3.注意变了输出 $name 或者 ${name}
linux中查看当前进程pid命令: echo $$
5.shell命令
#!/bin/bash
myUrl="http://www.google.com"
readonly myUrl
#!/bin/sh
myUrl="http://www.runoob.com"
unset myUrl
echo $myUrl
#!/bin/sh
string="http://www.runoob.com"
echo ${#string}
#!/bin/bash
string="http://www.runoob.com"
echo ${string:1:4} #截取字符串1-4位
- 字符串截取总结
格式 说明
${string: start :length} 从 string 字符串的左边第 start 个字符开始,向右截取 length 个字符。
${string: start} 从 string 字符串的左边第 start 个字符开始截取,直到最后。
${string: 0-start :length} 从 string 字符串的右边第 start 个字符开始,向右截取 length 个字符。
${string: 0-start} 从 string 字符串的右边第 start 个字符开始截取,直到最后。
${string#*chars} 从 string 字符串第一次出现 *chars 的位置开始,截取 *chars 右边的所有字符。
${string##*chars} 从 string 字符串最后一次出现 *chars 的位置开始,截取 *chars 右边的所有字符。
${string%*chars} 从 string 字符串第一次出现 *chars 的位置开始,截取 *chars 左边的所有字符。
${string%%*chars} 从 string 字符串最后一次出现 *chars 的位置开始,截取 *chars 左边的所有字符。
string="runoob is a great site"
echo `expr index "$string" io` # 输出 4
注:
1.截取字符串与调用命令分别:${string:start:length},$('command');
2.从右边开始截取${string:0-start:length}
3.从指定字符串开始截取 ${string#*start_string}
4.直到最后一个指定字符(子字符串)再匹配结束 ${string##*start_string}
eg:
#! /bin/bash
str1='china'
str2='广东'
str3='广州'
str4='白云区'
str5='番禺区'
str6='腾讯大厦'
str_new1=$str1$str2
str_new2="$str2 $str3"
str_new3=$str4":"$str5
str_new4="$str5:$str6"
str_new5="${str1} test: ${str2} index.html"
echo $str_new1
echo $str_new2
echo $str_new3
echo $str_new4
echo $str_new5
结果:
[root@localhost shell_study]# bash string_merge.sh
china广东
广东 广州
白云区:番禺区
番禺区:腾讯大厦
china test: 广东 index.html
数组名=(值1 值2 ... 值n)
如:
array_name=(value0 value1 value2 value3)
或者
array_name=(
value0
value1
value2
value3
)
还可以单独定义数组的各个分量:
array_name[0]=value0
array_name[1]=value1
array_name[n]=valuen
读取
读取数组元素值的一般格式:
${数组名[下标]}
使用 @ 或者 * 符号可以获取数组中的所有元素
echo ${array_name[@]}
# 取得数组元素的个数
length=${#array_name[@]}
或者
length=${#array_name[*]}
# 取得数组单个元素的长度
length=${#array_name[n]}
array_new=(${arr[@]} ${array[*]})
eg:
arr=(1 2 'test')
array=('zhang' 'li' 'wang')
arr_new=(${arr[*]} ${array[@]})
#获取拼接的数组
echo ${arr_new[*]}
结果:
[root@localhost shell_study]# bash arr_merge.sh
1 2 test zhang li wang
删除数组中的元素
unset array_new[index]
删除全部元素
unset array_new
eg:
#! /bin/bash
arr_del=('test' 'new' 'hello')
unset arr_del[0]
echo ${arr_del[*]}
unset arr_del
echo ${arr_del[@]}
结果:
[root@localhost shell_study]# bash arr_del.sh
new hello
单行注释
#--------------------------------------------
# 这是一个注释
# author:t_fengyun
# site:www.51about.com
# slogan:个人博客
#--------------------------------------------
##### 用户配置区 开始 #####
#
#
# 这里可以添加脚本描述信息
#
#
##### 用户配置区 结束 #####
多行注释
:<
代码多行备注
代码中多行代码需要注释断点并进行测试,要注释的代码用一对花括号括起来,定义成一个函数,没有地方调用这个函数,这块代码就不会执行,达到了和注释一样的效果。
我们可以在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$n。n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推……
#!/bin/bash
echo "Shell 传递参数实例!";
echo "执行的文件名:$0";
echo "第一个参数为:$1";
echo "第二个参数为:$2";
echo "第三个参数为:$3";
为脚本设置可执行权限,并执行脚本,输出结果如下所示:
$ chmod +x test.sh
$ ./test.sh 1 2 3
Shell 传递参数实例!
执行的文件名:./test.sh
第一个参数为:1
第二个参数为:2
第三个参数为:3
参数处理 | 说明 |
---|---|
$# | 传递到脚本的参数个数 |
$* | 以一个单字符串显示所有向脚本传递的参数。如"$*“用「”」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。 |
$$ | 脚本运行的当前进程ID号 |
$! | 后台运行的最后一个进程的ID号 |
$@ | 与 ∗ 相 同 , 但 是 使 用 时 加 引 号 , 并 在 引 号 中 返 回 每 个 参 数 。 如 " *相同,但是使用时加引号,并在引号中返回每个参数。如" ∗相同,但是使用时加引号,并在引号中返回每个参数。如"@“用「”」括起来的情况、以"$1" “ 2 " … " 2" … " 2"…"n” 的形式输出所有参数。 |
$- | 显示Shell使用的当前选项,与set命令功能相同 |
$? | 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。 |
#!/bin/bash
val=`expr 2 + 2`
echo "两数之和为 : $val"
a=10
b=20
val=`expr $a + $b`
echo "a + b : $val"
运算符 | 说明 | 举例 |
---|---|---|
+ | 加法 | expr $a + $b 结果为 30。 |
- | 减法 | expr $a - $b 结果为 -10。 |
* | 乘法 | expr $a \* $b 结果为 200。 |
/ | 除法 | expr $b / $a 结果为 2。 |
% | 取余 | expr $b % $a 结果为 0。 |
= | 赋值 | a=$b 将把变量 b 的值赋给 a。 |
== | 相等。用于比较两个数字,相同则返回 true。 | [ $a == $b ] 返回 false。 |
!= | 不相等。用于比较两个数字,不相同则返回 true。 | [ $a != $b ] 返回 true |
val=`expr $b % $a`
echo "b % a : $val"
if [ $a == $b ]
then
echo "a 等于 b"
fi
- 将命令的结果赋值给变量
variable=`test.sh`
variable=$(test.sh)
eg:
#! /bin/bash
variable=$(cat variable_first.sh)
echo $variable
variable_second=`cat variable_second.sh`
echo $variable_second
- 删除变量unset
unset variable
eg:
myUnset='unset'
echo $myUnset
- 变量分类:全局变量,局部变量,环境变量
注:1.shell中变量都默认为全局变量,要想变成局部变量,使用local。
2.进入子进程,执行bash。退出子进程,执行exit。
3.进程类似于windows下一个应用窗口就是一个进程,进程是互不相干扰的。
4.导出环境变量export,通过 export 导出的环境变量只对当前 Shell 进程以及所有的子进程有效,如果最顶层的父进程被关闭了,那么环境变量也就随之消失了,其它的进程也就无法使用了,所以说环境变量也是临时的。
命令:
variable=`command`或者variable=$(command)
注:多个命令之间用';'隔开
eg:
#!/bin/bash
echo "Language: $1"
echo "URL: $2"
运行test.sh:
[mozhiyan@localhost ~]$ cd demo
[mozhiyan@localhost demo]$ . ./test.sh Shell http://c.baidu.net/shell/
Language: Shell
URL: http://c.biancheng.net/shell/
eg1:
#!/bin/bash
#定义函数
function func(){
echo "Language: $1"
echo "URL: $2"
}
#调用函数
func C++ http://c.biancheng.net/cplus/
运行test.sh:
[mozhiyan@localhost ~]$ cd demo
[mozhiyan@localhost demo]$ . ./test.sh
Language: C++
URL: http://c.biancheng.net/cplus/
特殊参数
变量 | 说明
----------------|--------------------------------------------------------------------
$0 | 当前脚本的文件名
$n(n≥1) | 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是 $1,第二个参数是 $2。
$# | 传递给脚本或函数的参数个数
$* | 传递给脚本或函数的所有参数。
$@ | 传递给脚本或函数的所有参数。当被双引号" "包含时,$@ 与 $* 稍有不同
$? | 上个命令的退出状态,或函数的返回值
$$ | 当前 Shell 进程 ID。对于 Shell 脚本,就是这些脚本所在的进程 ID
注释:
- $()与``针对数学计算的使用
1.使用shell自带的函数时,$(expr $($1 + $2)) 或者 `expr $1 + $2`
2.注意数学计算时,参数之间的间隔
- shell脚本转义
echo "print each param from \"\$*\"" 注:转义使用\"\$*"\
- $*与$@都是打印传递给脚本或者函数的所有参数,但是在双引号中,两者有着本质区别,"$*""的循环次数要比"$@"少
- shell脚本中字符串可以用“”或者''包裹使用,也可以不带引号的使用
eg:
#! /bin/bash
a=test
echo $a
结果:
[root@localhost shell_study]# bash string.sh
test
- bash shell内置命令汇总
命令 说明
: 扩展参数列表,执行重定向操作
. 读取并执行指定文件中的命令(在当前 shell 环境中)
alias 为指定命令定义一个别名
bg 将作业以后台模式运行
bind 将键盘序列绑定到一个 readline 函数或宏
break 退出 for、while、select 或 until 循环
builtin 执行指定的 shell 内建命令
caller 返回活动子函数调用的上下文
cd 将当前目录切换为指定的目录
command 执行指定的命令,无需进行通常的 shell 查找
compgen 为指定单词生成可能的补全匹配
complete 显示指定的单词是如何补全的
compopt 修改指定单词的补全选项
continue 继续执行 for、while、select 或 until 循环的下一次迭代
declare 声明一个变量或变量类型。
dirs 显示当前存储目录的列表
disown 从进程作业表中刪除指定的作业
echo 将指定字符串输出到 STDOUT
enable 启用或禁用指定的内建shell命令
eval 将指定的参数拼接成一个命令,然后执行该命令
exec 用指定命令替换 shell 进程
exit 强制 shell 以指定的退出状态码退出
export 设置子 shell 进程可用的变量
fc 从历史记录中选择命令列表
fg 将作业以前台模式运行
getopts 分析指定的位置参数
hash 查找并记住指定命令的全路径名
help 显示帮助文件
history 显示命令历史记录
jobs 列出活动作业
kill 向指定的进程 ID(PID) 发送一个系统信号
let 计算一个数学表达式中的每个参数
local 在函数中创建一个作用域受限的变量
logout 退出登录 shell
mapfile 从 STDIN 读取数据行,并将其加入索引数组
popd 从目录栈中删除记录
printf 使用格式化字符串显示文本
pushd 向目录栈添加一个目录
pwd 显示当前工作目录的路径名
read 从 STDIN 读取一行数据并将其赋给一个变量
readarray 从 STDIN 读取数据行并将其放入索引数组
readonly 从 STDIN 读取一行数据并将其赋给一个不可修改的变量
return 强制函数以某个值退出,这个值可以被调用脚本提取
set 设置并显示环境变量的值和 shell 属性
shift 将位置参数依次向下降一个位置
shopt 打开/关闭控制 shell 可选行为的变量值
source 读取并执行指定文件中的命令(在当前 shell 环境中)
suspend 暂停 Shell 的执行,直到收到一个 SIGCONT 信号
test 基于指定条件返回退出状态码 0 或 1
times 显示累计的用户和系统时间
trap 如果收到了指定的系统信号,执行指定的命令
type 显示指定的单词如果作为命令将会如何被解释
typeset 声明一个变量或变量类型。
ulimit 为系统用户设置指定的资源的上限
umask 为新建的文件和目录设置默认权限
unalias 刪除指定的别名
unset 刪除指定的环境变量或 shell 属性
wait 等待指定的进程完成,并返回退出状态码
- 使用type命令检测是否shell内置命令
[root@localhost ~]# type cd
cd is a Shell builtin
[root@localhost ~]# type ifconfig
ifconfig is /sbin/ifconfig
- alias&& unalias 给命令创建(删除)别名,格式alias new_name='command'
eg:
关机命令:
alias myShutdown='shutdown -h now'
- read 读取键盘输入
read命令格式:read [-options] [variables]
read相关参数
选项 说明
-a array 把读取的数据赋值给数组 array,从下标 0 开始。
-d delimiter 用字符串 delimiter 指定读取结束的位置,而不是一个换行符(读取到的数据不包括 delimiter)。
-e 在获取用户输入的时候,对功能键进行编码转换,不会直接显式功能键对应的字符。
-n num 读取 num 个字符,而不是整行字符。
-p prompt 显示提示信息,提示内容为 prompt。
-r 原样读取(Raw mode),不把反斜杠字符解释为转义字符。
-s 静默模式(Silent mode),不会在屏幕上显示输入的字符。当输入密码和其它确认信息的时候,这是很有必要的。
-t seconds 设置超时时间,单位为秒。如果用户没有在指定时间内输入完成,那么 read 将会返回一个非 0 的退出状态,表示读取失败。
-u fd 使用文件描述符 fd 作为输入源,而不是标准输入,类似于重定向。
eg:
#! /bin/bash
read -p "enter params:" name url total
echo "网站名: $name"
echo "网站地址: $url"
echo "网站访问量: $total"
结果:
[root@localhost shell_study]# bash read_info.sh
enter params:自学网 51about.com 1000
网站名: 自学网
网站地址: 51about.com
网站访问量: 1000
- exit退出当前进程,$?查看退出当前进程状态
- declare 和 typeset(废弃):设置变量属性
declare命令格式:declare [+/-] [aAfFgilprtux] [变量名=变量值]
其中,-表示设置属性,+表示取消属性,aAfFgilprtux都是具体的选项,它们的含义如下表所示:
选项 含义
-f [name] 列出之前由用户在脚本中定义的函数名称和函数体。
-F [name] 仅列出自定义函数名称。
-g name 在 Shell 函数内部创建全局变量。
-p [name] 显示指定变量的属性和值。
-a name 声明变量为普通数组。
-A name 声明变量为关联数组(支持索引下标为字符串)。
-i name 将变量定义为整数型。
-r name[=value] 将变量定义为只读(不可修改和删除),等价于 readonly name。
-x name[=value] 将变量设置为环境变量,等价于 export name[=value]。
eg:
#! /bin/bash
declare -a arr array result
arr=(1 2 3 4 5)
array=('aa' 'bb' 'cc')
result=(${arr[*]} ${array[*]})
echo ${result[@]}
结果:
[root@localhost shell_study]# bash string_declare.sh
1 2 3 4 5 aa bb cc
- 逻辑运算时,注意如下
[root@localhost shell_study]# a=100
[root@localhost shell_study]# echo $((a++))
100 //注意输出结果为100
[root@localhost shell_study]# echo $a
101 //注意输出结果为101
[root@localhost shell_study]# a=10
[root@localhost shell_study]# echo $((a--))
10 //输出结果为10
[root@localhost shell_study]# echo $a
9 //输出结果为9
- 多项逻辑运算,格式:((a=3+5, b=a+10))
- test
1.用法:test expression,当 test 判断 expression 成立时,退出状态为 0,否则为非 0 值。
2.文件类型判断
选 项 作 用
-b filename 判断文件是否存在,并且是否为块设备文件。
-c filename 判断文件是否存在,并且是否为字符设备文件。
-d filename 判断文件是否存在,并且是否为目录文件。
-e filename 判断文件是否存在。
-f filename 判断文件是否存在,井且是否为普通文件。
-L filename 判断文件是否存在,并且是否为符号链接文件。
-p filename 判断文件是否存在,并且是否为管道文件。
-s filename 判断文件是否存在,并且是否为非空。
-S filename 判断该文件是否存在,并且是否为套接字文件。
3.文件权限判断
选 项 作 用
-r filename 判断文件是否存在,并且是否拥有读权限。
-w filename 判断文件是否存在,并且是否拥有写权限。
-x filename 判断文件是否存在,并且是否拥有执行权限。
-u filename 判断文件是否存在,并且是否拥有 SUID 权限。
-g filename 判断文件是否存在,并且是否拥有 SGID 权限。
-k filename 判断该文件是否存在,并且是否拥有 SBIT 权限
4.文件比较
选 项 作 用
filename1 -nt filename2 判断 filename1 的修改时间是否比 filename2 的新。
filename -ot filename2 判断 filename1 的修改时间是否比 filename2 的旧。
filename1 -ef filename2 判断 filename1 是否和 filename2 的 inode 号一致,可以理解为两个文件是否为同一个文件。这个判断用于判断硬链接是很好的方法
eg:
#! /bin/bash
read a
read b
if test $a>$b
then
echo 1
else
echo 0
fi
结果:
[root@localhost shell_study]# bash test.sh
1
2
1
1.if elif结构
if condition1
then
statement1
elif condition2
then
statement2
elif condition3
then
statement3
……
else
statementn
fi
2.if else结构
if condition
then
statement1
else
statement2
fi
3.case结构
case expression in
pattern1)
statement1
;;
pattern2)
statement2
;;
pattern3)
statement3
;;
……
*)
statementn
esac
1.while循环
while condition
do
statements
done
2.until循环(条件不成立时才进行循环,一旦判断条件成立,就终止循环)
until condition
do
statements
done
3.for循环
for((exp1; exp2; exp3))
do
statements
done
4.for in循环
for variable in value_list
do
statements
done
5.select in循环
select variable in value_list
do
statements
done
格式一:
function name() {
statements
[return value]
}
格式二:
name() {
statements
[return value]
}
格式三:
function name {
statements
[return value]
}
eg:
#! /bin/bash
function getsum(){
local sum=0
for n in $@
do
((sum+=n))
done
return $sum
}
getsum 10 20 30 40 50 #调用函数并传递参数
echo $?
运行结果:150
eg:
#!/bin/bash
function getsum(){
local sum=0
for n in $@
do
((sum+=n))
done
echo $sum
return 0
}
#调用函数并传递参数,最后将结果赋值给一个变量
total=$(getsum 10 20 55 15)
echo $total
#也可以将变量省略
echo $(getsum 10 20 55 15)
----------------shell未完待续--------------------