Shell编程基础语法

1、Shell编程概述

Shell是一个命令行解释器,它接收应用程序或用户的命令,然后调用操作系统内核。
在这里插入图片描述

Shell还是一个功能强大的编程语言,易编写、易调试、灵活性强。

①Linux系统提供的Shell解析器

[root@hadoop101 ~]$ cat /etc/shells 
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
/bin/tcsh
/bin/csh

其中最常用的是/bin/sh和/bin/bash

②bash和sh的关系

[root@apple w]# ll /usr/bin | grep bash$
-rwxr-xr-x. 1 root root     964544 4月  11 2018 bash
lrwxrwxrwx. 1 root root          4 7月   9 16:42 sh -> bash

sh是bash的软链接

③Linux默认的解析器是bash

[root@apple w]# echo $SHELL
/bin/bash

④Shell语法总述

在这里插入图片描述

2、Shell编程HelloWorld

①创建脚本文件

通常以.sh作为扩展名。

②脚本内容

第一行指定当前脚本的解析器:

#!/bin/bash

实现具体功能:

echo "hello world"

③Shell脚本的运行方式

命令名在当前进程运行新建子进程运行
source
.
sh
bash
chmod +x后直接运行

其中“.”是source的另一种写法。在当前进程中发布的全局变量可以在当前进程的其他脚本中继续沿用,也可以在子进程中使用;但是子进程export发布的变量仅限于子进程内部使用。
在这里插入图片描述

从上面进程树中能够看到,sh、bash、直接运行这三种方式确实是开辟新的子进程运行脚本中的代码。

3、变量

①系统预定义变量

常用系统变量包括: U S E R 、 USER、 USERHOME、 P W D 、 PWD、 PWDSHELL等,可以使用echo命令输出它们的值。

②使用set命令查看所有变量

ABRT_DEBUG_LOG=/dev/null
BASH=/bin/bash
BASHOPTS=checkwinsize:cmdhist:expand_aliases:extglob:extquote:force_fignore:histappend:interactive_comments:login_shell:progcomp:promptvars:sourcepath
BASH_ALIASES=()
BASH_ARGC=()
BASH_ARGV=()
……

③自定义变量

[1]基本语法

(1)定义变量
USER_NAME=tom
(2)撤销变量
[root@apple ~]# USER_NAME=tom
[root@apple ~]# echo $USER_NAME
tom
[root@apple ~]# unset USER_NAME
[root@apple ~]# echo $USER_NAME

(3)声明静态变量
[root@apple ~]# readonly COMPANY_NAME=atguigu
[root@apple ~]# echo $COMPANY_NAME
atguigu
[root@apple ~]# COMPANY_NAME=uuu
-bash: COMPANY_NAME: 只读变量
[root@apple ~]# unset COMPANY_NAME
-bash: unset: COMPANY_NAME: 无法反设定: 只读 variable

不能修改,不能撤销

[2]语法规则

  • 变量名称可以由字母、数字和下划线组成,但是不能以数字开头,环境变量名建议大写。
  • 等号两侧不能有空格
  • 在bash中,变量默认类型都是字符串类型,无法直接进行数值运算。
  • 变量的值如果有空格,需要使用双引号或单引号括起来。

④特殊变量

[1]$n

n是数字,$0代表当前脚本名称。从 1 开 始 代 表 对 应 的 脚 本 参 数 。 从 1开始代表对应的脚本参数。从 1{10}开始数字需要使用{}括起来。

[root@hadoop101 datas]$ touch parameter.sh 
[root@hadoop101 datas]$ vim parameter.sh

#!/bin/bash
echo "$0  $1   $2"

[root@hadoop101 datas]$ chmod 777 parameter.sh

[root@hadoop101 datas]$ ./parameter.sh cls  xz
./parameter.sh  cls   xz

[2]$#

返回输入参数的个数

[root@hadoop101 datas]$ vim parameter.sh

#!/bin/bash
echo "$0  $1   $2"
echo $#

[root@hadoop101 datas]$ chmod 777 parameter.sh

[root@hadoop101 datas]$ ./parameter.sh cls  xz
parameter.sh cls xz 
2

[3] ∗ 和 *和 @

都能够返回全部参数,但是只有在循环中且放在引号中能够体现出它们的区别。

[root@hadoop101 datas]$ vim parameter.sh

#!/bin/bash
echo "$0  $1   $2"
echo $#
echo $*
echo $@

[root@hadoop101 datas]$ bash parameter.sh 1 2 3
parameter.sh  1   2
3
1 2 3
1 2 3

[4]$?

返回上一条命令的执行结果。

  • 条件判断语句
    • 返回0表示true
    • 返回1表示false
  • 普通语句
    • 返回0表示成功
    • 返回非0数表示失败

4、运算符

( ( 表 达 式 ) ) 或 ((表达式))或 (())[表达式]

[root@apple ~]# echo $((20+30))
50
[root@apple ~]# echo $(((15+15)*2))
60
[root@apple ~]# echo $[(15+15)*2]
60

5、条件判断

①基本语法

  • 写法1:test condition
  • 写法2:[ condition ]
    • 注意condition前后有空格
    • 空字符串视为false,非空字符串视为true

②常用判断条件

数据类型写法含义
数值-ltless than小于
数值-leless equal小于等于
数值-eqequal等于
数值-gtgreater than大于
数值-gegreater equal大于等于
数值-nenot equal不等于
文件-rread有读权限
文件-wwrite有写权限
文件-xexecute有执行权限
文件-ffile文件存在并且是一个常规的文件
文件-eexistence文件存在
文件-ddirectory文件存在并是一个目录

6、流程控制

①三目运算

[root@apple w]# [ 10 -gt 5 ] && echo "10大于5" || echo "10小于5"
10大于5

②if判断

注意:if后面有空格

[1]单if

if [ 10 -gt 5 ]
then
echo "10大于5"
fi

[2]if…else

if [ 10 -gt 5 ]
then
echo "10大于5"
else
echo "10小于5"
fi

[3]if…elif

if [ 10 -gt 5 ]
then
echo "10大于5"
elif [ 10 -lt 5 ]
then
echo "10小于5"
else
echo "10等于5"
fi

③case判断

AGE=10
case $AGE in
"10")
echo 10
;;
"20")
echo 20
;;
*)
echo other
;;
esac

④for循环

for (( i=1;i<=10;i++ ))
do
echo $i
done

⑤for in循环

for i in $*
do
echo $i
done

没有引号的时候 ∗ 和 *和 @一样,加了引号就有区别

for i in "$*"
do
echo $i
done

上面代码输出的结果是:

[root@apple w]# sh shell42.sh a b c d e
a b c d e

⑥while循环

s=0
i=1
while [ $i -le 100 ]
do
        s=$[$s+$i]
        i=$[$i+1]
done

echo $s

7、函数

Shell编程中的函数和我们以前熟悉的函数最大的区别是:Shell编程中要求函数的返回值只能是整数。并且只能通过$?方式获得。可以显示加:return返回,如果不加,将以最后一条命令运行结果,作为返回值。return后跟数值n(0-255)。

function sum() {
    echo $[$1+$2]
}

sum 10 20
function sum() {
    return $[$1+$2]
}

sum 33 55

echo $?

8、获取脚本外部数据

①获取参数

这个前面说过了,通过$1、 2 、 … … 方 式 获 取 , 从 2、……方式获取,从 2{10}开始需要使用大括号。

②使用read读取用户输入

read命令有两个常用参数

  • -t用于指定输入等待时间,单位是秒
  • -p用于指定提示文字
read -t 10 -p "please enter:" NAME
echo $NAME

9、Shell工具

①basename

返回路径字符串中的资源(文件或目录本身)部分

[root@apple w]# basename /aa/bb/cc/dd
dd

如果指定了后缀,basename会帮我们把后缀部分也去掉

[root@apple workspace]# basename /aa/bb/cc/dd.txt .txt
dd

②dirname

返回路径字符串中的目录部分

[root@apple w]# dirname /aa/bb/cc/dd
/aa/bb/cc

③cut

根据指定符号拆分字符串并提取。默认根据\t拆分。

  • -f参数:指定要提取的列
  • -d参数:指定拆分依据的字符

准备测试数据:

[root@hadoop101 datas]$ touch cut.txt
[root@hadoop101 datas]$ vim cut.txt
dong shen
guan zhen
wo  wo
lai  lai
le  le

切割提取第一列:

[root@hadoop101 datas]$ cut -d " " -f 1 cut.txt 
dong
guan
wo
lai
le

切割提取第二、第三列:

[root@apple w]# cut -d " " -f 2,3 cut.txt 
shen
zhen
 wo
 lai
 la

在cut.txt中切出guan

[root@hadoop101 datas]$ cat cut.txt | grep "guan" | cut -d " " -f 1
guan

选取系统PATH变量值,第2个“:”开始后的所有路径:

[root@hadoop101 datas]$ echo $PATH
/usr/lib64/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/atguigu/bin

[root@hadoop101 datas]$ echo $PATH | cut -d : -f 2-
/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/atguigu/bin

切割ifconfig 后打印的IP地址:

[root@apple w]# ifconfig | grep "netmask" | cut -d "i" -f 2 | cut -d " " -f 2
192.168.41.100
127.0.0.1
192.168.122.1

另一种做法:

[root@apple workspace]# ifconfig | grep netmask | cut -d " " -f 10
192.168.41.100
127.0.0.1
192.168.122.1

④sed(了解)

sed是一种流编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。

准备测试数据:

[root@hadoop101 datas]$ touch sed.txt
[root@hadoop101 datas]$ vim sed.txt
dong shen
guan zhen
wo  wo
lai  lai

le  le

在第二行下面添加字符串:

[root@hadoop101 datas]$ sed '2a mei nv' sed.txt 
dong shen
guan zhen
mei nv
wo  wo
lai  lai

le  le
[root@hadoop101 datas]$ cat sed.txt 
dong shen
guan zhen
wo  wo
lai  lai

le  le

删除带有“wo”的行:

[root@hadoop101 datas]$ sed '/wo/d' sed.txt
dong shen
guan zhen
lai  lai

le  le

将“wo”替换为”ni“

[root@hadoop101 datas]$ sed 's/wo/ni/g' sed.txt 
dong shen
guan zhen
ni  ni
lai  lai

le  le

先删除第二行,再执行替换

[root@hadoop101 datas]$ sed -e '2d' -e 's/wo/ni/g' sed.txt 
dong shen
ni  ni
lai  lai

le  le

⑤awk

一个强大的文本分析工具,把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理。

[1]基本用法

awk [选项参数] ‘pattern1{action1} pattern2{action2}…’ filename

pattern:表示AWK在数据中查找的内容,就是匹配模式

action:在找到匹配内容时所执行的一系列命令

使用-F参数指定分隔符。

awk命令的内置变量包括:

变量名说明
FILENAME文件名
NR已读取的记录
NF浏览记录的域的个数(切割后,列的个数)

[2]测试

# 准备数据
[root@hadoop101 datas]$ sudo cp /etc/passwd ./
# 搜索passwd文件以root关键字开头的所有行,并输出该行的第7列。
[root@hadoop101 datas]$ awk -F: '/^root/{print $7}' passwd 
/bin/bash
# 搜索passwd文件以root关键字开头的所有行,并输出该行的第1列和第7列,中间以“,”号分割。
[root@hadoop101 datas]$ awk -F: '/^root/{print $1","$7}' passwd 
root,/bin/bash
# 只显示/etc/passwd的第一列和第七列,以逗号分割,且在所有行前面添加列名user,shell在最后一行添加"dahaige,/bin/zuishuai"。
[root@hadoop101 datas]$ awk -F : 'BEGIN{print "user, shell"} {print $1","$7} END{print "dahaige,/bin/zuishuai"}' passwd
user, shell
root,/bin/bash
bin,/sbin/nologin
。。。
atguigu,/bin/bash
dahaige,/bin/zuishuai
# 将passwd文件中的用户id增加数值1并输出
[root@hadoop101 datas]$ awk -v i=1 -F: '{print $3+i}' passwd
1
2
3
4
# 统计passwd文件名,每行的行号,每行的列数
[root@hadoop101 datas]$ awk -F: '{print "filename:"  FILENAME ", linenumber:" NR  ",columns:" NF}' passwd 
filename:passwd, linenumber:1,columns:7
filename:passwd, linenumber:2,columns:7
filename:passwd, linenumber:3,columns:7
# 切割IP
[root@apple workspace]# ifconfig | awk -F " " '/netmask/{print $2}'
192.168.41.100
127.0.0.1
192.168.122.1
# 查询sed.txt中空行所在的行号
[root@hadoop101 datas]$ awk '/^$/{print NR}' sed.txt 
5

PS:如果命令很长,可以使用反斜杠换行输入

[root@apple workspace]# awk -F : \
> 'BEGIN{print "user\t\tshell"} {print $1"\t\t"$7} END{print "dahaige\t\t/bin/zuishuai"}' \
> passwd

⑥sort

sort命令是在Linux里非常有用,它将文件进行排序,并将排序结果标准输出。

参数名作用
-n依照数值大小排序
-r相反顺序排序
-t设置排序时使用的分隔字符
-k指定需要排序的列
# 准备数据
[root@hadoop101 datas]$ touch sort.sh
[root@hadoop101 datas]$ vim sort.sh 
bb:40:5.4
bd:20:4.2
xz:50:2.3
cls:10:3.5
ss:30:1.6
# 测试
[root@hadoop101 datas]$ sort -t : -nrk 3  sort.sh 
bb:40:5.4
bd:20:4.2
cls:10:3.5
xz:50:2.3
ss:30:1.6

[root@apple workspace]# sort -nrt : -k 3 sort.txt 
bb:40:5.4
bd:20:4.2
cls:10:3.5
xz:50:2.3
ss:30:1.6

⑦wc

wc命令用来计算数字。利用wc指令我们可以计算文件的Byte数、字数或是列数。

参数作用
-l统计行数
-w统计单词数
-m统计字符数
-c统计字节数

10、正则表达式入门

符号含义
^匹配字符串开始位置的字符
$匹配字符串结束位置的字符
.匹配任何一个字符
*匹配前面的字符出现0~n次
[a,m,u]匹配字符a或m或u
[a-z]匹配所有小写字母
[A-Z]匹配所有大写字母
[a-zA-Z]匹配所有字母
[0-9]匹配所有数字
\特殊符号转义

11、企业面试真题

①京东

[1]问题1:

使用Linux命令查询file1中空行所在的行号

[root@hadoop101 datas]$ awk '/^$/{print NR}' sed.txt 
5

[2]问题2:

有文件chengji.txt内容如下:

张三 40

李四 50

王五 60

使用Linux命令计算第二列的和并输出

[root@hadoop101 datas]$ cat chengji.txt | awk -F " " '{sum+=$2} END{print sum}'
150
[root@apple workspace]# awk '{sum+=$2} {print $1","$2} END{print "总分:"sum}' chengji.txt 
张三,50
小红,60
小刚,100
总分:210

②搜狐&和讯网

Shell脚本里如何检查一个文件是否存在?如果不存在该如何处理?

#!/bin/bash

if [ -f file.txt ]
then
   echo "文件存在!"
else
   echo "文件不存在!"
fi

③新浪

用shell写一个脚本,对文本中无序的一列数字排序

[root@CentOS6-2 ~]# cat test.txt
9
8
7
6
5
4
3
2
10
1
[root@CentOS6-2 ~]# sort -n test.txt|awk '{a+=$1;print $1}END{print "SUM="a}'
1
2
3
4
5
6
7
8
9
10
SUM=55

④金和网络

请用shell脚本写出查找当前文件夹(/home)下所有的文本文件内容中包含有字符”shen”的文件名称

[root@hadoop101 datas]$ grep -r "shen" /home | cut -d ":" -f 1
/home/atguigu/datas/sed.txt
/home/atguigu/datas/cut.txt
[root@apple workspace]# grep -r "shen" /root/workspace/
/root/workspace/sed.txt:dong shen
/root/workspace/cut.txt:dong shen
[root@apple workspace]# grep -r "shen" /root/workspace/ | awk -F : '{print $1}'
/root/workspace/sed.txt
/root/workspace/cut.txt
[root@apple workspace]# grep -r "shen" /root/workspace/ | awk -F : '{print $1}' | awk -F '/' '{print $4}'
sed.txt
cut.txt

l写一个脚本,对文本中无序的一列数字排序

[root@CentOS6-2 ~]# cat test.txt
9
8
7
6
5
4
3
2
10
1
[root@CentOS6-2 ~]# sort -n test.txt|awk '{a+=$1;print $1}END{print "SUM="a}'
1
2
3
4
5
6
7
8
9
10
SUM=55

④金和网络

请用shell脚本写出查找当前文件夹(/home)下所有的文本文件内容中包含有字符”shen”的文件名称

[root@hadoop101 datas]$ grep -r "shen" /home | cut -d ":" -f 1
/home/atguigu/datas/sed.txt
/home/atguigu/datas/cut.txt
[root@apple workspace]# grep -r "shen" /root/workspace/
/root/workspace/sed.txt:dong shen
/root/workspace/cut.txt:dong shen
[root@apple workspace]# grep -r "shen" /root/workspace/ | awk -F : '{print $1}'
/root/workspace/sed.txt
/root/workspace/cut.txt
[root@apple workspace]# grep -r "shen" /root/workspace/ | awk -F : '{print $1}' | awk -F '/' '{print $4}'
sed.txt
cut.txt
  • 2
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值