欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

shell编程基础补充整理

程序员文章站 2024-02-19 14:07:28
...

shell本身就是一门解释型、弱类型、动态语言,与python相对应,Python属于解释型、强类型、动态语言,我们平时登录成功一个用户后进入的就是bash解释器的交互式环境,我们敲的命令其实都属于shell这门语言的语法

如何区别强类型与弱类型语言

shell属于弱类型语言

echo "1+abc"
1+abc

python属于强类型语言

python
Python 2.7.5 (default, Oct 14 2020, 14:45:30) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> print(1+"abc")
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'

shell语言与python语言的差别

Shell 脚本的优势在于处理偏操作系统底层的业务,例如,Linux 内部的很多应用(有的是应用的一部分)都是使用 Shell 脚本开发的,因为有 1000 多个 Linux 系统命令为它作支撑,特别是 Linux 正则表达式以及三剑客 grep、awk、sed等命令。
对于一些常见的系统脚本,使用 Shell开发会更简单、更快速,例如,让软件一键自动化安装、优化,监控报警脚本,软件启动脚本,日志分析脚本等,虽然 Python也能做到这些,但是考虑到掌握难度、开发效率、开发习惯等因素,它们可能就不如 Shell 脚本流行以及有优势了。对于一些常见的业务应用,使用Shell 更符合 Linux 运维简单、易用、高效的三大原则。

Python 是近几年非常流行的语言,它不但可以用于脚本程序开发,也可以实现 Web程序开发(知乎、豆瓣、YouTube、Instagram 都是用Python 开发),甚至还可以实现软件的开发(大名鼎鼎的OpenStack、SaltStack 都是 Python 语言开发)、游戏开发、大数据开发、移动端开发。

现在越来越多的公司要求运维人员会 Python 自动化开发,Python 也成了运维人员必备的技能,每一个运维人员在熟悉了 Shell之后,都应该再学习 Python 语言。

Python 语言的优势在于开发复杂的运维软件、Web 页面的管理工具和 Web 业务的开发(例如 CMDB自动化运维平台、跳板机、批量管理软件 SaltStack、云计算OpenStack 软件)等。

运行shell脚本程序的几种方式

[[email protected] ~]# vim /a/b/a.sh
#!/bin/bash
echo "hello world"
方式一:绝对路径,此时采用的是文件头指定的解释器来解释执行文件内代码
# 权限:
# 1、对沿途文件夹有x权限
# 2、对目标文件有r和x权限

# 例
[[email protected] ~]# ll -d /a
d--------x. 3 root root 15 11月 15 11:05 /a
[[email protected] ~]# ll -d /a/b
d--------x. 2 root root 18 11月 15 11:06 /a/b
[[email protected] ~]# ll /a/b/a.sh
-rw-r--r-x. 1 root root 10 11月 15 11:06 /a/b/a.sh
[[email protected] ~]# su - nana
Last login: Tue Jun 15 17:00:30 CST 2021 on pts/0
[[email protected] ~]$ /a/b/a.sh
hello world
方式二:相对路径,需要加./作为前缀,此时采用的仍是文件头指定的解释器来解释执行文件内代码
# 权限:
# 1、对沿途文件夹有x权限
# 2、对目标文件有r和x权限

# 例
[[email protected] ~]# ll -d /a
d--------x. 3 root root 15 11月 15 11:05 /a
[[email protected] ~]# ll -d /a/b
d--------x. 2 root root 18 11月 15 11:06 /a/b
[[email protected] ~]# ll /a/b/a.sh
-rw-r--r-x. 1 root root 10 11月 15 11:06 /a/b/a.sh
[[email protected] ~]# su - nana
Last login: Tue Jun 15 17:06:46 CST 2021 on pts/0
[[email protected] ~]$ /a/b/a.sh				# 绝对路径的方式
hello world
[[email protected] ~]$ cd /a
[[email protected] a]$ ./b/a.sh				# 相对路径的方式
hello world
方式三:解释器+文件路径(绝对路径或相对路径都可以),此时采用的是我们自己指定的解释器来解释执行文件内代码
# 权限:
# 1、对沿途文件夹有x权限
# 2、对目标文件有r权限即可
因为我们执行的是解释器,当前用户对解释器有执行权限就可以了,这个权限默认就有,而解释器需要读文件内容来执行,所以需要对目标文件有r权限

# 例
[[email protected] ~]# chmod -R o=x /a
[[email protected] ~]# chmod o=r /a/b/a.sh
[[email protected] ~]# su - nana
Last login: Tue Jun 15 17:23:20 CST 2021 on pts/0
[[email protected] ~]$ cd /a
[[email protected] a]$ bash b/a.sh
hello world
方式四:上述三种方式都是在子shell进程中执行程序,而方式四则是在当前shell进程中执行
# 权限:
# 1、对沿途文件夹有x权限
# 2、对目标文件有r权限即可

上述三种方式都是在当前shell环境下开启了一个新的shell解释器环境/子shell来执行程序,
脚本程序在子shell中运行完毕后,子shell环境随即关闭,然后返回到父级shell即当前shell环境中,
如果就想在当前shell环境中执行,需要这么做

# 例
[[email protected] ~]# chmod -R o=x /a
[[email protected] ~]# chmod o=r /a/b/a.sh
[[email protected] ~]# su - nana
Last login: Tue Jun 15 17:26:48 CST 2021 on pts/0
[[email protected] ~]$ . /a/b/a.sh		# . 后跟空格,然后再跟绝对路径
hello world
[[email protected] ~]$ cd /a/b/
[[email protected] b]$ . a.sh		 # . 后跟空格,然后再跟相对路径
hello world
[[email protected] b]$ source a.sh	 # 跟上述方式一样
hello world

在当前shell解释器进程中执行脚本与在子shell进程中执行脚本的区别在于作用域

调试shell程序

vim login.sh
#!/bin/bash

read -p "name:" name
read -p "password:" pwd

if [[ $name == "nana" && $pwd == "123" ]];then
        echo "登陆成功"
else
        echo "账号或密码错误"
fi
调式方式1:以调试的方式运行
bash -vx login.sh 			 # 不加-v选项,只会显示程序中运行的代码,不会显示注释信息
#!/bin/bash

read -p "name:" name
+ read -p name: name
name:nana
read -p "password:" pwd
+ read -p password: pwd
password:123

if [[ $name == "nana" && $pwd == "123" ]];then
	echo "登陆成功"
else
	echo "账号或密码错误"
fi
+ [[ nana == \n\a\n\a ]]
+ [[ 123 == \1\2\3 ]]
+ echo 登陆成功
登陆成功
调试方式2:只调试语法是否有问题,比如if判断少了fi结尾
bash -n login.sh 
# login.sh: line 10: syntax error: unexpected end of file

cat login.sh 
#!/bin/bash

read -p "name:" name
read -p "password:" pwd

if [[ $name == "nana" && $pwd == "123" ]];then
	echo "登陆成功"
else
	echo "账号或密码错误"
调试方式3:仅调试脚本的一部分,用set -x与set +x包含,运行过程中会只打印它们包含的代码段的运行情况
cat login.sh 
#!/usr/bin/env bash
set -x
read -p "请输入您的名字: " name
read -p "请输入您的密码: " pwd
set +x
if [[ "$name" == "egon" && "$pwd" == "123" ]];then
    echo "登录成功"
else
    echo "账号或密码错误"
fi

. login.sh
cat login.sh 
#!/usr/bin/env bash
set -x
read -p "请输入您的名字: " name
read -p "请输入您的密码: " pwd
set +x

if [[ "$name" == "egon" && "$pwd" == "123" ]];then
    echo "登录成功"
else
    echo "账号或密码错误"
++ read -p '请输入您的名字: ' name
请输入您的名字: nana
++ read -p '请输入您的密码: ' pwd
请输入您的密码: 123
++ set +x
-bash: login.sh: line 12: syntax error: unexpected end of file

变量值的三种来源

1. 直接赋值
today=$(date +%F)
echo $today
# 2021-06-15

2. 从位置参数获取变量值
vim b.sh 
#!/bin/bash
echo ${0}
echo $1
echo $2
echo $3
echo $4
echo $5
echo $6
echo $7
echo $8
echo $9
echo ${10}
echo ${11}

bash b.sh a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 
b.sh
a1
a2
a3
a4
a5
a6
a7
a8
a9
a10
a11

企业使用:可以实现脚本的不同功能(服务程序管理脚本-启动功能 关闭功能 重启功能)
bash b.sh start|stop|restart

3. 与用户交互获取值
[[email protected] ~]# read nana
123
[[email protected] ~]# echo $nana
123

[[email protected] ~]# read -p "输入名字:" name				-p->添加提示信息
输入名字:nana
[[email protected] ~]# echo $name
nana

[[email protected] ~]# read -t 2 -p "name" name				-t->限制输入变量值的时间(2s)
name

[[email protected] ~]# read -n 5 name					-n->读取输入字符的个数
aaaaa
[[email protected] ~]# echo $name
aaaaa

预定变量

$*	所有的参数
[email protected] 	所有的参数
$# 	参数的个数
$$ 	当前进程的PID  # 此外,可以使用只读变量来获取父进程的PID:$PPID、获取执行脚本的用户ID:$UID
$?	上一个命令的返回值 0表示成功	

[[email protected] ~]# vim A.sh
echo $*
echo [email protected]
echo $#
echo $$
[[email protected] ~]# bash A.sh a1 a2 a3 a4 a5
a1 a2 a3 a4 a5
a1 a2 a3 a4 a5
5
17821

[[email protected] ~]# ping -c1 www.baidu.com &> /dev/null
[[email protected] ~]# echo $?
0

$*[email protected]的差别
[[email protected] ~]# vim B.sh 
#!/bin/bash

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

echo "================"

for i in "[email protected]"
do 
	echo $i
done

[[email protected] ~]# bash B.sh 1 2 3 "4 5"
1 2 3 4 5
================
1
2
3
4 5

常量

相对于变量,常量就是不可以被改变的量,即只能读不能改,所以又称之为只读变量

使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。
[[email protected] ~]# x=111
[[email protected] ~]# readonly x
[[email protected] ~]# x=666
-bash: x: readonly variable
相关标签: shell