Linux的shell编程基础(上)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_41685388/article/details/102616437

1、什么是Shell?

Shell是核心程序(kernel)之外的指令解析器,是一个程序,同时是一种命令语言和程序设计语言。

Shell环境:只要有一个能编写代码的文本编辑器和一个能解释执行的脚本解释器就可以了。

Shell的类型sh、ash、bash、ksh、cshtcshdash

  • cat /etc/shells   #查看当前系统支持的Shell类型
  • echo $SHELL  #查看当前系统默认使用的Shell类型

当前系统支持的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

2、Shell脚本的编写与执行

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 !

3、Shell echo命令、Shell 变量 

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

定义变量注意:

  • 定义变量时,变量名不加美元符号($,PHP语言中变量需要),
  • 变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样
  • 变量名的命名须遵循如下规则:
  • 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。

  • 中间不能有空格,可以使用下划线(_)。

  • 不能使用标点符号。

  • 不能使用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时,会同时存在三种变量:

  • 1) 局部变量 局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。
  • 2) 环境变量 所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。
  • 3) shell变量 shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行

4、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

5、Shell 数组

[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]}
#单行注释#,多行注释:<<EOF   EOF
:<<EOP
注释内容...
注释内容...
EOP
echo ${value0}
echo ${array_name[@]}
echo ${length}
echo ${length0}                                                                   
~                                                                      
"Demo.sh" 23L, 469C written                          

[root@hadoop02 shell01]# sh Demo.sh 
value0
value0 value1 value_2 value_3 value n
5
7

6、Shell 传递参数

在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$nn 代表一个数字,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

7、Shell 基本运算符---关系运算符、布尔运算符

  • 原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。
  • expr 是一款表达式计算工具,使用它能完成表达式的求值操作。
  • 完整的表达式要被 ` ` 包含,注意这个字符不是常用的单引号,在 Esc 键下边
  • 乘法符号\*,要在前面加转义字符\来表示
  • 表达式和运算符之间要有空格
[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

8、Shell 基本运算符---字符串运算符

#字符串运算符: =  (判断字符串相等 );!= (判断不相等); -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

9、Shell 基本运算符---文件测试运算符

操作符 说明 举例
-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

猜你喜欢

转载自blog.csdn.net/weixin_41685388/article/details/102616437