当前位置: 首页 > news >正文

01Shell脚本入门:基础命令与变量解析

什么是shell

shell是命令解释器,负责解释用户输入的命令传递给内核,内核执行调用硬件,然后将结果返回给shell

linux的默认shell是bash

Shell分交互式与非交互式

交互式:输入命令可以得到响应
非交互式:通过脚本运行Shell命令,无需等待用户输入命令

什么是 Shell脚本

将命令写入到文件中,称为 shell脚本。增加了判断循环函数等语法

创建第一个shell脚本

[root@laoli ~]# mkdir -p shell
[root@laoli ~]# cd shell
[root@laoli shell]# touch test.sh
[root@laoli shell]# cat test.sh 
#!/bin/bash
echo hello
[root@laoli shell]# . test.sh
hello

执行shell脚本的三种方式:

1,sh 或 bash,不需要执行权限,在子shell中执行

[root@laoli shell]# sh test.sh 
hello
[root@laoli shell]# bash test.sh 
hello

2,路径执行方式: 需要给脚本增加执行权限,在子shell中执行

[root@laoli shell]# ll
total 4
-rw-r--r--. 1 root root 23 Aug 23 04:27 test.sh
[root@laoli shell]# chmod +x test.sh 
[root@laoli shell]# /root/shell/test.sh 
hello

3, 点 .  或者source执行脚本,不需要执行权限,在父shell中执行

[root@laoli shell]# . test.sh 
hello
[root@laoli shell]# source test.sh 
hello

解释器分为父shell和子shell

父shell: 登录系统默认为父shell
子shell: 在默认的父shell中执行bash 进入到了一个子shell中在执行脚本的时候,调用子shell执行内容

其他的shell脚本执行方式

[root@laoli shell]# bash  < test.sh 
hello
[root@laoli shell]# cat test.sh|bash
hello

Shell变量

1:什么是变量?

用一个固定的值表示一堆不固定的值,称为变量

2:变量的分类:

环境变量(全局变量),对于系统所有的bash生效,默认系统定义好的,都是大写

普通变量(局部变量),自己来定义的变量,一般都在脚本文件中定义

全局变量先生效,局部变量后生效,所以全局变量与局部变量重复时候,局部变量生效

3:按照变量的生存周期

1.临时变量:只在当前的shell中生效

使用export定义,则变量在全局(所有shell)生效,但是其他连接的会话不会生效

2.永久变量:写入到文件中或者/etc/profile变量文件中

4:变量相关的配置文件

/etc/profile 常用的变量配置文件,每次开机和每次的远程连接都会执行此文件

用户变量文件:

.bashrc

.bash_profile

/etc/bashrc

5: 变量定义规则

变量名只能由字母,数字和下划线组成,可以由字母或下划线开头,不能以数字开头,等号两端不允许有空格,尽量不要使用关键字命名变量(和c语言差不多)

6:变量值定义规则

一:字符串定义,通常为连续字符串,如果需要不连续需要加双引号

[root@laoli etc]# name=helloworld
[root@laoli etc]# echo $name
helloworld
[root@laoli etc]# name=hello world
bash: world: command not found...
定义不连续则报错[root@laoli etc]# name="hello world"
[root@laoli etc]# echo $name
hello world----------------------------------------------------------------------------------
定义文件路径
[root@laoli etc]# dir=/etc/sysconfig/network-scripts/ifcfg-eno16777736 
[root@laoli etc]# cat $dir
HWADDR=00:0C:29:82:C6:4E
TYPE=Ethernet
BOOTPROTO=static
DEFROUTE=yes
PEERDNS=yes
PEERROUTES=yes
IPV4_FAILURE_FATAL=no
NAME=eno16777736
UUID=075c43f5-42b0-4725-b27b-a3e85c8b2c75
ONBOOT=yes
IPADDR=192.168.74.128
GATEWAY=192.168.74.2
DNS1="8.8.8.8"
----------------------------------------------------------------------------------
定义命令
[root@laoli etc]# hehe="echo hehe"
[root@laoli etc]# $hehe
hehe

二:数字定义,不连续需要加双引号

[root@laoli etc]# age=18
[root@laoli etc]# echo $age
18[root@laoli etc]# idcard=3230230230
[root@laoli etc]# echo $idcard
3230230230[root@laoli etc]# idcard=32302 30230
bash: 30230: command not found...
#不连续报错,需要加双引号
[root@laoli etc]# idcard="32302 30230"
[root@laoli etc]# echo $idcard
32302 30230

三:命令定义

[root@laoli etc]# test01=`pwd`
[root@laoli etc]# echo $test01
/etc
先执行``里的命令,把结果赋值给test01[root@laoli etc]# test01=pwd
[root@laoli etc]# $test01
/etc
将命令赋值给变量,变量值本身现在就代表这个命令[root@laoli etc]# test01='pwd'
[root@laoli etc]# echo $test01
pwd
查看变量看的是字符串,echo后面跟的全是字符串案例: 定义一个变量,在脚本任意的位置执行nginx -t命令
[root@laoli nginx]# nginx_n='nginx -t'
[root@laoli nginx]# $nginx_n
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

补充:


Time=`` # 将执行后的结果赋值给Time
Time=$() # 将执行后的结果赋值给Time双引号可以解析变量
[root@laoli nginx]# test02="$test01"
[root@laoli nginx]# echo $test02
pwd变量之间要加{}
[root@laoli nginx]# ip=10.0.0.1
[root@laoli nginx]# host=web01
[root@laoli nginx]# echo "$ip_$host"
web01
不加括号无法都显示出来[root@laoli nginx]# echo "${ip}_$host"
10.0.0.1_web01

Shell核心位置变量

$n 获取脚本的第n个参数

$0 代表脚本本身名称,如果执行脚本带路径,则名称也带路径。

[root@laoli shell]# cat test.sh 
#!/bin/bash
echo 123
echo $0
[root@laoli shell]# . test.sh 
123
bash

$n 获取脚本的第n个参数,$0被名字占用,从$1开始,可以传递数字、字符串和序列

$1 表示脚本的第1个参数

$7表示脚本的第7个参数

注意:从10开始,参数要用{ }引起来,否则不能正常传参,例如${10},${11}

[root@laoli shell]# cat test.sh 
#!/bin/bash
echo $1 $2 $4[root@laoli shell]# . test.sh 1 2 3 4
1 2 4
没有$3则跳过.未传参的变量默认为空[root@laoli shell]# cat test.sh 
#!/bin/bash
[root@laoli shell]# . test.sh 'hello world' 2
hello world 2
单引号中的字符串为一个变量的值[root@laoli shell]# cat test.sh 
#!/bin/bash
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} 
[root@laoli shell]# . test.sh {a..z}
a b c d e f g h i j k[root@laoli shell]# cat test.sh 
#!/bin/bash
echo name:$1
echo age:$2
[root@laoli shell]# . test.sh lisan 23
name:lisan
age:23

$# 获取脚本的传参个数

[root@laoli shell]# cat test.sh 
#!/bin/bash
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} 
echo $#
[root@laoli shell]# . test.sh {a..f}
a b c d e f
6
只传了6个参数,所以显示六个值,$#为6案例: 判断传入参数必须为2个,否则提示错误[root@laoli shell]# cat test.sh 
#!/bin/bash
[ $# -ne 2 ]&&echo '请输入两个参数'&&exit
echo name: $1
echo age: $2
[root@laoli shell]# . test.sh laoli 23
name: laoli
age: 23
[root@laoli shell]# . test.sh laoli 
请输入两个参数

shell中的比较运算符

shell中,-eq表示等于   ,    -ne表示不等于

与变量结合时的格式:在 [ ] 中使用时,变量和运算符前后必须有空格,例如 [ $a -eq $b ] 不能写成 [$a-eq$b]

返回值:条件成立时返回状态码 0(真),不成立时返回非 0(假),符合 Shell 命令的通用规则

案例: 判断传入参数必须为2个,否则提示错误-eq写法#!/bin/bash
[ $# -eq 2 ] || { echo '请输入两个参数'&&exit ;}
echo name: $1
echo age: $2-ne写法#!/bin/bash
[ $# -ne 2 ] && echo "请输入两个参数" && exit
echo name: $1
echo age: $2

补充:常见的命令连接符&&和||

&&(逻辑与):前真后行,结合规则遵循从左到右(左结合)

意思就是左边的为真才执行右边的

||(逻辑或):前假后行,结合规则遵循从左到右(左结合)

意思就是左边的为假才执行右边的

获取脚本传参的所有参数$*  ;  $@

$* 获取脚本传参的所有参数,默认和$@相同,在循环体中加双引号表示一个整体

$@ 获取脚本传参的所有参数,默认和$*相同,在循环体中加双引号表示独立的参数

[root@laoli shell]# cat ceshi.sh 
#!/bin/bash
echo $1 $2 $3
echo $*
echo $@
echo $#
[root@laoli shell]# . ceshi.sh 1 2 3
1 2 3
1 2 3
1 2 3
3

Shell状态变量:

$? 存储上条命令执行结果,成功为0,失败不为0

案例: 通过传参的方式传入域名,然后ping是否在线[root@laoli shell]# cat ceshi.sh 
#!/bin/bash
ping -c1 -w1 $1 &>/dev/null
[ $? -eq 0 ]&&echo "$1 tong"||echo "$1 butong"
[root@laoli shell]# . ceshi.sh www.baidu.com
www.baidu.com tong

$$ 获得脚本的pid号

[root@laoli shell]# cat get_pid.sh 
#!/bin/bash
echo $$
[root@laoli shell]# . get_pid.sh 
23717

$! 获取上一个在后台运行脚本的PID号

$_ 获取脚本的最后一个参数

小结:

$0   获取脚本名称 
$n   获取脚本n个参数 $1开始 
$#   获取传参的总个数 
$?   获取上一条命令的执行结果 0成功 非0 失败
$$   获取脚本的PID号 
$!   获取上一个在后台运行的脚本PID号 
$*   获取所有传参的参数 
$@   获取所有传参的参数 

Shell传参三种方式:

1:直接传参

[root@laoli shell]# cat chuancan.sh 
#!/bin/bash
echo $1 $2
[root@laoli shell]# . chuancan.sh 1 2
1 2

2:赋值传参

[root@laoli shell]# cat chuancan.sh 
#!/bin/bash
a=$1
b=$2
echo name:$a
echo age:$b
[root@laoli shell]# . chuancan.sh cx 12
name:cx
age:12

3:read交互式传参

这个和python的input语句很像,read -p可以输入提示语

直接执行脚本不需要参数,进入脚本后开始交互式传参

[root@laoli shell]# cat chuancan.sh 
#!/bin/bash
read -p 'write your name:' a
echo name:$a
[root@laoli shell]# . chuancan.sh 
write your name:cxk
name:cxk

这是我的个人学习笔记,主要用于记录自己对知识点的理解和梳理。由于目前仍在学习探索阶段,内容中难免存在理解偏差或表述疏漏,恳请各位大佬不吝赐教,多提宝贵意见~ 若有不同看法,欢迎理性交流探讨,感谢包容与指正!

http://www.dtcms.com/a/347955.html

相关文章:

  • JVM之【类加载系统】
  • 【Qt开发】常用控件(六)
  • Golang云端编程深度指南:架构本质与高阶实践
  • Flink Slot 不足导致任务Pending修复方案
  • 互联网大厂Java面试实录:从Spring到微服务的全面考察
  • 【软件安全】ARM64、x86、32 位与 64 位架构的区别、定义、应用背景
  • 个人搭建小网站教程(云服务器Ubuntu版本)
  • 【数据结构】二叉树的顺序存储、堆的实现及其应用:堆排序与Top-K问题
  • 以国产IoTDB为代表的主流时序数据库架构与性能深度选型评测
  • kanass V1.1.4版本发布,支持Mysql数据库、ubuntu安装与Mantis数据导入
  • Thonny+MicroPython搭建ESP32芯片开发环境
  • 代码性能测试——benchmark库
  • Elasticsearch Ruby 客户端故障排查实战指南
  • AI与SEO关键词协同优化
  • DBeaver连接SQL Server集成认证问题解决方案
  • xxl-job 启动后导致pod内存使用率持续增加
  • 从 Unity UGUI 到 Unreal UMG 的交互与高效实践:UI 事件、坐标系适配与性能优化
  • MATLAB 与 Simulink 联合仿真:控制系统建模与动态性能优化
  • C#_gRPC
  • RabbitMQ--消费端异常处理与 Spring Retry
  • 阿里云拉取dockers镜像
  • 在JavaScript中,比较两个数组是否有相同元素(交集)的常用方法
  • 今日科技热点 | AI加速创新,5G与量子计算引领未来
  • wpf之DockPanel
  • 3D打印机管理后台与RabbitMQ集成的业务场景
  • RabbitMQ面试精讲 Day 29:版本升级与平滑迁移
  • 【图像处理基石】基于 Python 的图像行人删除技术:实现街景无干扰化处理
  • 性能比拼: .NET (C#) vs. Fiber (Go)
  • Kaggle项目:一次 Uber 出行数据分析的完整思路
  • 高空作业安全监控难题突破!陌讯自适应识别算法实现安全带穿戴检测准确率↑93%