Shell是核心程序(kernel)之外的指令解析器,是一个程序,同时是一种命令语言和程序设计语言。
Shell环境:只要有一个能编写代码的文本编辑器和一个能解释执行的脚本解释器就可以了。
Shell的类型sh、ash、bash、ksh、csh、tcsh、dash等
当前系统支持的Shell类型可以互相切换(如:输入命令/bin/csh则当前使用的是csh类型,退出当前的csh,执行exit)
#查看系统支持的类型
[root@hadoop02 ~]# cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/bin/dash
/bin/tcsh
/bin/csh
#查看系统默认的类型
[root@hadoop02 ~]# echo $SHELL
/bin/bash
#支持的类型之间可以相互切换,如切换为/bin/csh
[root@hadoop02 ~]# /bin/csh
#切换后尝试执行以下ls命令,可以执行
[root@hadoop02 ~]# ls
anaconda-ks.cfg
Desktop
......
#退出刚才的切换执行,退回到/bin/bash
[root@hadoop02 ~]# exit
exit
#查看当前使用的类型
[root@hadoop02 ~]# echo $SHELL
/bin/bash
vim 脚本名称.sh (如:vim Demo1.sh) #直接用vi/vim 编辑 **.sh文件即可。(建议先cd切换进入自己用来保存Shell脚本的目录下,接下来的操作建立在新建的用于存放Shell脚本的/root/Desktop/shell01目录下)
进入编辑脚本程序的第一行输入:#!/bin/bash (#! 是一个约定的标记,告诉系统这个脚本需要用的解释器,用哪一类型的Shell);然后写入程序内容,保存并退出。添加文件可执行权限(chmod +x Demo1.sh),最后用 sh Demo1.sh 命令执行脚本。
[root@hadoop02 shell01]# echo $SHELL
in/bash
[root@hadoop02 shell01]# vim Demo1.sh
#!/bin/bash ## 脚本使用的解释器,通常用幻数 "#!" 指定
echo "hello world !"
~
"Demo1.sh" 3L, 97C written
[root@hadoop02 shell01]# chmod +x Demo1.sh
[root@hadoop02 shell01]# ll
total 4
-rwxr-xr-x. 1 root root 97 Oct 17 19:41 Demo1.sh
[root@hadoop02 shell01]# sh Demo1.sh
hello world !
echo表示输出:
[root@hadoop02 shell01]# vim Demo0.sh
#!/bin/bash
echo "OK!"
echo -e "OK! \c" # -e 开启转义 \c 不换行
echo -e "xiaoxiao \n" # -e 开启转义 \n 换行
echo -e "OK! huahua\n"
#显示结果定向至文件
echo -e "OK! xiaoxiao" > myfile.txt
#显示结果追加至文件
echo -e "OK! \n huahua" >> myfile.txt
~
"Demo0.sh" [New] 8L, 280C written
[root@hadoop02 shell01]# sh Demo0.sh
OK!
OK! xiaoxiao
OK! huahua
[root@hadoop02 shell01]# cat myfile.txt
OK! xiaoxiao
OK!
huahua
定义变量注意:
命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
中间不能有空格,可以使用下划线(_)。
不能使用标点符号。
不能使用bash里的关键字(可用help命令查看保留关键字)。
如:your_name="baidu.com"
除了显式地直接赋值,还可以用语句给变量赋值,如:
for file in `ls /etc`或for file in $(ls /etc)
以上语句将 /etc 下目录的文件名循环出来。
使用变量:echo ${变量名}
其中{},变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界。
[root@hadoop02 shell01]# vim Demo.sh
#!/bin/bash
you_name="baidu.com"
echo ${you_name}
for skill in Ada Coffe Action Java;
do
echo "I am good at ${skill}Script"
done
"Demo.sh" 9L, 136C written
[root@hadoop02 shell01]# sh Demo.sh
baidu.com
I am good at AdaScript
I am good at CoffeScript
I am good at ActionScript
I am good at JavaScript
只读变量:readonly 变量名
使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。
删除变量:unset 变量名
变量被删除后不能再次使用。unset 命令不能删除只读变量。
变量类型:
运行shell时,会同时存在三种变量:
字符串是shell编程中最常用最有用的数据类型(除了数字和字符串,也没啥其它类型好用了),字符串可以用单引号,也可以用双引号,也可以不用引号。单双引号的区别跟PHP类似。
拼接字符串
[root@hadoop02 shell01]# vim Demo.sh
#!/bin/bash
your_name="hadoop"
# 使用双引号拼接
greeting="hello, "$your_name" !"
greeting_1="hello, ${your_name} !"
echo $greeting $greeting_1
# 使用单引号拼接
greeting_2='hello, '$your_name' !'
#下面这句将直接输出hello, ${your_name} !
greeting_3='hello, ${your_name} !'
echo $greeting_2 $greeting_3
~
"Demo.sh" 11L, 325C written
[root@hadoop02 shell01]# sh Demo.sh
hello, hadoop ! hello, hadoop !
hello, hadoop ! hello, ${your_name} !
输出字符串长度、截取字符串、查找子字符串位置
[root@hadoop02 shell01]# vim Demo.sh
#!/bin/bash
your_name="hadoop"
# 使用双引号拼接
greeting="hello, ${your_name} !"
echo ${greeting} #输出字符串
echo ${#greeting} #输出字符串长度
echo ${greeting:1:4} #从第2个开始截取4个字符,并输出
echo `expr index "${greeting}" hd` #查找h或者d最先出现的位置,开头和结尾是`反引号,不是'单引号
~
"Demo.sh" 8L, 349C written
[root@hadoop02 shell01]# sh Demo.sh
hello, hadoop !
15
ello
1
[root@hadoop02 shell01]# vim Demo.sh
#!/bin/bash
#定义数组
array_name=(value0 value1 'value_2' "value_3" 'value n')
#读取数组,@符号获取所有元素
value0=${array_name[0]}
valuen=${array_name[4]}
value=${array_name[@]}
#获取数组长度
length=${#array_name}
#或者
length=${#array_name[*]}
#获取元素长度
length0=${#array_name[4]}
#单行注释#,多行注释:<
在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$n。n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推……
[root@hadoop02 shell01]# vim /root/Desktop/shell01/Demo2.sh
#!/bin/bash
echo "Shell传递参数案例"
echo "执行的文件名称:$0" #输出执行的文件名,默认输出不用传入参数
echo "执行的第1个参数:$1"
echo "执行的第2个参数:$2"
echo "执行的第3个参数:$3"
echo "执行的第4个参数:$4"
echo "传递到脚本的参数个数:$#"
echo "以一个单字符串显示传递的参数:$*"
echo "以"$1 $2 … $n"的形式输出所有参数:"$*""
echo "脚本运行的当前进程ID号:$$"
echo "后台运行的最后一个进程的ID号:$!"
echo "以一个单字符串显示传递的参数:$@"
echo "以"$1" "$2" … "$n" 的形式输出所有参数:"$@""
echo "显示Shell使用的当前选项,与set命令功能相同:$-"
echo "显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误:$?"
~
"Demo2.sh" 16L, 807C written
[root@hadoop02 shell01]# sh Demo2.sh params1 params2 params3 params4
Shell传递参数案例
执行的文件名称:Demo2.sh
执行的第1个参数:params1
执行的第2个参数:params2
执行的第3个参数:params3
执行的第4个参数:params4
传递到脚本的参数个数:4
以一个单字符串显示传递的参数:params1 params2 params3 params4
以params1 params2 … 的形式输出所有参数:params1 params2 params3 params4
脚本运行的当前进程ID号:6578
后台运行的最后一个进程的ID号:
以一个单字符串显示传递的参数,字符加引号:params1 params2 params3 params4
以params1 params2 … 的形式输出所有参数:params1 params2 params3 params4
显示Shell使用的当前选项,与set命令功能相同:hB
显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误:0
[root@hadoop02 shell01]# vim Demo3.sh
#!/bin/bash
echo "2 * 3 = " `expr 2 \* 3`
#传递参数作算术运算符的计算
echo "$1 + $2 = " `expr $1 + $2` #加
echo "$1 - $2 = " `expr $1 - $2` #减
echo "$1 / $2 = " `expr $1 / $2` #除
echo "$1 * $2 = " `expr $1 \* $2` #乘
echo "$1 % $2 = " `expr $1 % $2` #求余
#if...then...fi 是条件语句,判断两个参数是否相等
if [ $1 == $2 ]
then
echo " $1 == $2 "
fi
if [ $1 != $2 ]
then
echo " $1 != $2 "
fi
#关系运算符
#(-eq:等于;-ne:不等于;-gt:大于;-lt:小于;-ge:大于等于;-le:小于等于)
if [ $1 -eq $2 ]
then
echo "关系运算符 :$1 == $2"
elif [ $1 -ne $2 ]
then
echo "关系运算符 :$1 != $2"
fi
if [ $1 -gt $2 ]
then
echo "关系运算符 :$1 > $2"
elif [ $1 -lt $2 ]
then
echo "关系运算符 :$1 < $2"
fi
if [ $1 -ge $2 ]
then
echo "关系运算符 :$1 >= $2"
elif [ $1 -le $2 ]
then
echo "关系运算符 :$1 <= $2"
fi
#布尔运算符、逻辑运算符
#(!:非; -o:或; -a:与)
#(&& :与 || : 或),使用时多加一层[],如下面示例
if [ $1 != $2 ]
then
echo "输出: $1 != $2 "
else
echo "输出: $1 == $2 "
fi
if [ $1 -ne $2 -a $1 -gt $2 ] #[[ $1 -ne $2 && $1 -gt $2 ]]
then
echo "输出 :$1 >= $2"
else
echo "输出 :$1 < $2"
fi
if [ $1 -lt $2 -o $1 -eq $2 ] #[[ $1 -lt $2 || $1 -eq $2 ]]
then
echo "输出 :$1 <= $2"
else
echo "输出 :$1 > $2"
fi
[root@hadoop02 shell01]# sh Demo3.sh 20 10
2 * 3 = 6
20 + 10 = 30
20 - 10 = 10
20 / 10 = 2
20 * 10 = 200
20 % 10 = 0
20 != 10
关系运算符 :20 != 10
关系运算符 :20 > 10
关系运算符 :20 >= 10
输出: 20 != 10
输出 :20 >= 10
输出 :20 > 10
#字符串运算符: = (判断字符串相等 );!= (判断不相等); -z (判断长度为0);-n(判断长度不为0);$ (判断不为空:如[ $a ] :表示a变量不为空时返回true)
[root@hadoop02 shell01]# vim Demo6.sh
#!/bin/bash
#字符串运算符: = (判断字符串相等 );!= (判断不相等);
# -z (判断长度为0); -n(判断长度不为0);
# $ (判断不为空:如[ $a ] :表示a变量不为空时返回true)
a=$1
b=$2
c=$3
if [[ ${a} = ${b} && ${a} = ${c} ]]
then
echo "a:${a} = b:${b} = c:${c}"
elif [ ${a} = ${b} -a ${b} != ${c} ]
then
echo "a:${a} = b:${b} != c:${c}"
elif [ ${a} != ${b} -a ${b} = ${c} ]
then
echo "a:${a} != b:${b} =c :${c}"
elif [ ${a} != ${b} -a ${a} = ${c} ]
then
echo "a:${a} = c:${c} != c:${b}"
else
echo "a:${a} != b:${b} != c:${c}"
fi
array_name=(${a} ${b} ${c})
if [ ${array_name[0]} ]
then
echo "传参1:${a}"
else
echo "传参1:为空"
fi
if [ -z ${array_name[1]} ]
then
echo "传参2:为空"
else
echo "传参2:${b}"
fi
if [ -n ${array_name[2]} ]
then
echo "传参3:${c},长度:${#c}"
else
echo "传参3:为空"
fi
[root@hadoop02 shell01]# sh Demo6.sh a11 b23 cdf
a:a11 != b:b23 != c:cdf
传参1:a11
传参2:b23
传参3:cdf,长度:3
操作符 | 说明 | 举例 |
-r file | 检测文件是否可读,如果是,则返回 true。 | [ -r $file ] 返回 true。 |
-w file | 检测文件是否可写,如果是,则返回 true。 | [ -w $file ] 返回 true。 |
-x file | 检测文件是否可执行,如果是,则返回 true。 | [ -x $file ] 返回 true。 |
-f file | 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 | [ -f $file ] 返回 true。 |
-s file | 检测文件是否为空(文件大小是否大于0),不为空返回 true。 | [ -s $file ] 返回 true。 |
-S file | 判断某文件是否 socket。 | [ -S $file ] 返回false。 |
-e file | 检测文件(包括目录)是否存在,如果是,则返回 true。 | [ -e $file ] 返回 true。 |
-L file | 检测文件是否存在并且是一个符号链接。 | [ -L $file ] 返回 false。 |
-b file | 检测文件是否是块设备文件,如果是,则返回 true。 | [ -b $file ] 返回 false。 |
-c file | 检测文件是否是字符设备文件,如果是,则返回 true。 | [ -c $file ] 返回 false。 |
-d file | 检测文件是否是目录,如果是,则返回 true。 | [ -d $file ] 返回 false。 |
-g file | 检测文件是否设置了 SGID 位,如果是,则返回 true。 | [ -g $file ] 返回 false。 |
-k file | 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 | [ -k $file ] 返回 false。 |
-p file | 检测文件是否是有名管道,如果是,则返回 true。 | [ -p $file ] 返回 false。 |
-u file | 检测文件是否设置了 SUID 位,如果是,则返回 true。 | [ -u $file ] 返回 false。 |
[root@hadoop02 shell01]# vim Demo7.sh
#!/bin/bash
file="/root/Desktop/shell01/Demo3.sh"
if [ -e ${file} ]
then
echo "Demo3.sh文件存在"
else
echo "Demo3.sh文件不存在"
fi
if [ -r ${file} ]
then
echo "文件可读"
else
echo "文件不可读"
fi
if test -f ${file}
then
echo "普通文件"
else
echo "非普通文件"
fi
if [ -s ${file} ]
then
echo "文件不为空"
else
echo "为空文件"
fi
if [ -L ${file} ]
then
echo "文件是一个符号链接"
else
echo "文件是非符号链接"
fi
[root@hadoop02 shell01]# sh Demo7.sh
Demo3.sh文件存在
文件可读
普通文件
文件不为空
文件是非符号链接
[root@hadoop02 shell01]#
Linux的shell编程基础(下):https://blog.csdn.net/weixin_41685388/article/details/102630781