其他
【10-1】做数据分析,要不要掌握Linux系列:shell编程之变量!
1、shell的介绍
1)什么是shell?
Shell 本身是一个用c语言编写的程序
,它是用户使用Unix/Linux的桥梁,用户的大部分工作都是通过Shell完成的。Shell 既是一种命令语言,又是一种程序设计语言
:作为命令语言,它交互式地解释和执行用户输入的命令;作为程序设计语言,它定义了各种变量和参数,并提供了许多在高级语言中才具有的控制结构,包括循环和分支。Shell 它虽然不是Unix/Linux系统内核的一部分
,但它调用了系统核心的大部分功能来执行程序、建立文件并以并行的方式协调各个程序的运行。Shell 是用户与内核进行交互操作的一种接口,目前最流行的Shell称为bash Shell(Bourne Again Shell)。Shell是一门
编程语言(解释型的编程语言
,即shell脚本(就是在用linux的shell命令编程),Shell 脚本程序从脚本中一行一行读取并执行这些命令,相当于一个用户把脚本中的命令一行一行敲到Shell提示符下执行。Shell是一种脚本语言
,那么,就必须有解释器来执行这些脚本。Unix/Linux上常见的shell脚本解释器有bash、sh、csh、ksh
等,习惯上把它们称作一种Shell。sh是Unix标准默认的shell
,由Steve Bourne 开发,是Bourne Shell的缩写。bash是Linux标准默认的shell
,由Brian Fox 和Chet Ramey共同完成,是Bourne Again Shell的缩写。[hadoop@image_boundary ~]$ cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/bin/dash
2、shell语言
shell脚本
代码通常写在普通文本文件中,通常以.sh结尾
,虽然不是强制要求,但希望大家最好这么做
。1)基本语法
// a.sh存在,就是打开该文件;
// a.sh不存在,就是创建该文件。
[root@image_boundary ~]# vim a.sh
// 【#!/bin/bash】表示设置默认解释器类型。
// 但是如果【指定解释器执行】该脚本时,该行无效。
#!/bin/bash
echo "Hello World"
2)shell脚本的3种执行方式:大前提,都必须是在shell脚本所在目录下执行。
Ⅰ 指定解释器执行:【sh/bash + 脚本名称】。
Hello World
[root@image_boundary ~]# bash a.sh
Hello World
Ⅱ bash内部命令:【source + 脚本名称】或【. + 脚本名称】。
aa
[root@bigdata111 ~]# . a.sh
aa
注意1:source命令也称为“点命令”也就是一个点符号(.),是bash的内部命令。 注意2:source命令通常用于重新执行刚修改的初始化文件,使之立即生效,而不必注销并重新登录。 注意3:.和脚本名称之间是有空格的。
Ⅲ 直接执行:赋予文件可执行权限,才可以执行。
# chmod命令可以修改可读、可写、可执行的权限
chmod
# 2 相对路径执行法(每次执行,必须切换到文件所在目录)
# 这里的点(.)指的是“当前路径”。
./脚本文件名
# 3 绝对路径执行法(只要有权限,什么路径下都可以执行)
/root/脚本文件名
[root@image_boundary ~]# chmod 744 a.sh
[root@image_boundary ~]# ll
total 4
-rwxr--r--. 1 root root 31 Oct 18 09:18 a.sh
// 相对路径执行:必须切换到该文件的目录当中去,才可以执行。
[root@image_boundary ~]# ./a.sh
Hello World
// 绝对路径执行:在任何地方都可以执行。
[root@image_boundary ~]# /root/a.sh
Hello World
Ⅳ 这三种执行shell脚本命令的异同
3)shell脚本中【注释】的写法
3、变量
1)系统变量
[root@image_boundary ~]# set
// 常用的系统变量:$PWD $PATH $SHELL $USER $HOME
[root@image_boundary ~]# echo $PATH
/usr/local/tomcat/apache-tomcat-8.5.45/bin:/usr/local/java/jdk1.8.0_73/bin:/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
// echo $PWD :显示当前位置的绝对路径
[root@image_boundary ~]# echo $PWD
/root
// echo $USER : 显示当前你是哪一个用户登陆的虚拟机
[root@image_boundary ~]# echo $USER
root
[huangwei@image_boundary root]$ echo $USER
huangwei
// echo $HOME : 显示用户的家目录
[root@image_boundary ~]# echo $HOME
/root
[huangwei@image_boundary root]$ echo $HOME
/home/huangwei
// echo $SHELL : 显示linux系统默认的shell
[root@image_boundary ~]# echo $SHELL
/bin/bash
2)定义变量
注意1:在shell脚本中定义变量,等号两侧,绝对不能有空格;
注意2:值中有空格,需要使用引号;
注意3:单引号会内容脱意,双引号可以识别变量;
注意4:变量紧挨着其它单词,可以使用${A}来获取变量A的值;
[root@bigdata111 ~]# A = 12
bash: A: command not found
[root@bigdata111 ~]# A=12
// 使用$号,可以获取变量的值;
[root@bigdata111 ~]# echo $A
12
[root@bigdata111 ~]# A=abc
[root@bigdata111 ~]# echo $A
abc
[root@bigdata111 ~]# A="abc"
[root@bigdata111 ~]# echo $A
abc
// 值中用空格,值需要使用引号引起来;
[root@bigdata111 ~]# A=ab c
-bash: c: command not found
[root@bigdata111 ~]# A="ab c"
[root@bigdata111 ~]# echo $A
ab c
[root@bigdata111 ~]# B='I love $A'
// 单引号会导致内容脱意,双引号可以识别变量;
[root@bigdata111 ~]# echo $B
I love $A
[root@bigdata111 ~]# B="I love $A"
[root@bigdata111 ~]# echo $B
I love Chen Li
[root@bigdata111 ~]# C="dog"
[root@bigdata111 ~]# D="Those are $Cs"
[root@bigdata111 ~]# echo $D
This are
// 想要变量与其它单词区分,可以使用${C};
[root@bigdata111 ~]# D="Those are ${C}s"
[root@bigdata111 ~]# echo $D
Those are dogs
// 注意以下几种写法的不同点;
[root@image_boundary ~]# A="Dog"
// a放在$A前面:a$A
[root@image_boundary ~]# B="Those are a$A"
// a放在$A后面:$Aa;
[root@image_boundary ~]# C="Those are $Aa"
[root@image_boundary ~]# echo $B
Those are aDog
[root@image_boundary ~]# echo $C
Those are
3)其他用法
2)设置只读变量:readonly 变量名=值;
注意:设置只读变量后,修改、撤销只读变量,会报错。
① 撤销变量操作如下:
[root@image_boundary ~]# echo $A
12
// 撤销变量后,变量输出为空;
[root@image_boundary ~]# unset A
[root@image_boundary ~]# echo $A
[root@image_boundary ~]#
② 设置只读变量操作如下:
// 修改只读变量,会报错;
[root@image_boundary ~]# A=666
-bash: A: readonly variable
// 撤销只读变量,会报错;
[root@image_boundary ~]# unset A
-bash: unset: A: cannot unset: readonly variable
4、案例:变量的使用(有意思的案例)
1)绝对路径执行:才会有父进程、子进程
#!/bin/bash
A="A in a.sh"
echo $A
echo $B
/root/b. sh
// 脚本b.sh中的内容;
#!/bin/bash
B="B in b. sh"
echo $B
echo $A
① 先创建a.sh和b.sh文件,查看其权限:没有可执行的权限。
② 使用chmod命令修改权限。
[root@bigdata111 ~]# chmod 755 b.sh
③ 执行a.sh这个脚本文件。
2)内部命令执行:根本就没有父进程和子进程这一说,都是同一个进程。
为了更好地说明上述区别,我们在脚本中分别打印$$,显示进程数。
[root@image_boundary ~]# echo $$
9544
5、变量中几个常用符号
1)反引号``和$():先计算再赋值
[root@bigdata111 ~]# echo $A
Mon Sep 30 06:20:02 CST 2019
// $(变量):表示先计算,再赋值;
[root@bigdata111 ~]# B=$(date)
[root@bigdata111 ~]# echo $B
Mon Sep 30 06:20:36 CST 2019
// 练习:你可以尝试以下以下操作,看看结果是什么?
[root@bigdata111 ~]# ll
total 8
-rw-r--r--. 1 root root 390 Oct 2 01:04 a.txt
-rw-r--r--. 1 root root 0 Oct 2 01:03 b.txt
drwxr-xr-x. 2 root root 4096 Oct 2 01:04 study
[root@bigdata111 ~]# echo `ll` // 这个结果是什么
[root@bigdata111 ~]# echo $(ll) // 这个结果是什么
2)变量中有用的技巧
${var:-word}:判断某个变量是否存在。
变量存在且有值,输出变量var的值;
变量不存在,输出word。
${var:+word}:判断某个变量是否存在。
变量存在且有值,输出word;
变量不存在,输出为空。
${var:=word}:变量存在,返回变量var的值;
变量不存在,相当于创建一个新变量var,并赋值为word。
${var:?message}:变量存在,输出变量var的值;
变量不存在,报错误。
3)特殊变量:在测试的时候很常用!!!
$?表示上一个命令退出的状态码;
$$ 表示当前进程编号;
$0 表示当前脚本名称;
$n 表示n位置的输入参数(n代表数字,n>=1);
$# 表示获取参数的个数,常用于循环;
$*和$@都表示获取参数列表。
[root@bigdata111 ~]# cat uni_var.sh
#!/bin/bash
echo $? #表示上一个命令退出的状态码
echo $$ #表示当前的进程编号
echo $0 #表示当前的脚本名称
echo $1 #表示第1个位置参数
echo $2 #表示第2个位置参数
echo $3 #表示第3个位置参数
echo $# #表示参数的个数
echo $@ #输出参数列表
echo $* #输出参数列表
[root@bigdata111 ~]# sh uni_var.sh aa bb cc
0
4192
uni_var.sh
aa
bb
cc
3
aa bb cc
aa bb cc
----------End----------
为了公平起见,黄同学选择在朋友圈赠书,同时已经送了好多本书籍了。好处:这样一来,大家中奖概率也大,都会有机会的,很多都是刚刚加了我的好友,都中奖了!
方式一:复制我微信号aili1127421544,添加我微信;
方式二:长按扫描下方二维码,添加我微信;
备注:黄同学朋友圈福利多多,欢迎查阅!