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

Linux笔记9——shell编程基础-3

补充

  1. shell解释器是可以手动开启的,可以开启多个shell、也可以开启子shell
  2. 最明显的感觉就是当你新开启一个shell后,你刚才执行的历史命令调用不出来
  3. 使用bash命令可以打开一个新的bash,查看pstree结果中的sshd部分
[root@localhost ~]# pstree
systemd─┬─NetworkManager───2*[{NetworkManager}]├─rsyslogd───2*[{rsyslogd}]├─sshd───sshd───sshd───bash───pstree├─systemd───(sd-pam)[root@localhost ~]# bash
[root@localhost ~]# pstree
systemd─┬─NetworkManager───2*[{NetworkManager}]├─rsyslogd───2*[{rsyslogd}]├─sshd───sshd───sshd───bash───bash───pstree

一、大括号、小括号

  • {}:定义了命令在本bash中运行
  • ():定义了命令在子bash中运行,脱离当前变量环境

注:父bash定义的环境变量能够被子bash继承,但子不传父,且没法继承局部变量

[root@localhost ~]# name=lisi
[root@localhost ~]# bash
[root@localhost ~]# echo $name[root@localhost ~]# exit
exit
[root@localhost ~]# (echo $name)
lisi
#虽然bash和(echo $name)都会创建子Shell,但它们的创建时机和方式有本质区别,这导致了行为的不同
[root@localhost ~]# (name=zhangsan;echo $name)
zhangsan
[root@localhost ~]# echo $name
lisi
#虽然在小括号的子bash中修改了变量值,但不会影响到父bash

{}和()的区别

相同:都是把一串命令放在括号里,并且命令之间用;隔开

不同

  • ()执行命令时需要重开一个子bash去执行,{}在当前shell执行
  • ()命令最后可以不加分号,但{}命令最后不加分好则无法正确执行
  • ()里各命令和括号之间可以没有空格,{}第一个命令和左括号之间必须有一个空格
#{ } 执行命令时,就在本shell中进行
[root@localhost ~]# { name=wangwu;echo $name;}
wangwu
[root@localhost ~]# echo $name
wangwu

二、shell变量

  • 变量:即可变的量(变量包含字母、数字、下划线,但数字不能作开头)
  • 声明变量:变量名=值(字符串、常量、命令结果、变量的值,等号两边不能有空格)
  • 调用变量:echo  $变量名

注:变量是有类型的,默认是字符串

#可以把一个现有变量的值作为变量值赋给变量
$ lujing="$PATH"
$ echo $lujing
#可以把一个命令的结果作为变量值赋给变量
$ shijian=`date`
或:shijian=$(date)
$ echo $shijian
#调用变量值时,为了保证不与后面的字符(字母、数字、下划线)被误判成新的变量名,需要加花括号
进行分隔
$ shijian="$(date)"
$ echo "now time is $shijian ma?"
now time is 2023年 09月 15日 星期五 00:19:48 CST ma?
$ echo "nowtimeis$shijianma?"
nowtimeis?
$ echo "nowtimeis${shijian}ma?"
nowtimeis2023年 09月 15日 星期五 00:19:48 CSTma?
#变量是可以叠加的
$ a=10;b=20
$ echo $a+$b -- 10+20

变量的分类

  • 自定义变量:由用户自由定义变量的名和值
  • 环境变量:保存的值是和系统操作环境相关的数据(一般为系统预先设定)
  • 预定义变量:bash中已经 定义好的变量,变量名不能自定义,作用也是固定的
  • 位置参数变量:用来向脚本中传递参数或数据的,变量名不能自定义,作用是固定的

注:set命令会将当前定义好的变量都给列出来

自定义变量

  • 增:名=值
  • 删:unset 名
  • 改:名=新值
  • 查:echo $变量名
[root@localhost ~]# shijian=$(date)    #增
[root@localhost ~]# echo $shijian 
2025年 08月 25日 星期一 18:44:16 CST
[root@localhost ~]# set | grep shijian    #查
shijian='2025年 08月 25日 星期一 18:44:16 CST'
[root@localhost ~]# unset shijian    #删
[root@localhost ~]# set | grep shijian
_=shijian
[root@localhost ~]# echo $shijian[root@localhost ~]# 

注:用echo输出,无论是没有变量还是有变量但值为空,输出结果是一样的;因此要用set做区分

[root@localhost ~]# echo $nnn[root@localhost ~]# shijian=
[root@localhost ~]# echo $shijian[root@localhost ~]# set | grep nnn
[root@localhost ~]# set | grep shijian
shijian=
[root@localhost ~]# 

set命令

  • set -u:提示未定义的变量,开启校验模式(或set | grep 变量名,查找)
  • set -x:执行命令前先打印出来(bash -x可以起到相同的效果)
  • set +u:可以取消校验变量名的模式
[root@localhost ~]# set -u
[root@localhost ~]# echo $nnn    #调用没有声明的变量时会报错
-bash: nnn:未绑定的变量
[root@localhost ~]# echo $shijian[root@localhost ~]# set -x
++ printf '\033]0;%s@%s:%s\007' root localhost '~'
[root@localhost ~]# echo "nihao"
+ echo nihao
nihao
++ printf '\033]0;%s@%s:%s\007' root localhost '~'
[root@localhost ~]# set +u +x
#调试脚本时,可以在脚本中写入set -x,每次运行脚本(bash 脚本名)都会先打印
[root@localhost ~]# cat for1.sh
#!/bin/bash
set -x
for i in 1 2 3 4
doecho $i
done
#也可以有问题时打印一次,bash -x 脚本名

环境变量

  • 定义:export 变量名=值

备注:环境变量一般都大写,但一般很少自定义环境变量,都是使用系统设置好的

  • 增:export 名=值(名大写)或名=值   &&  export  名
  • 删:unset  名
  • 改:名=新值
  • 查:set查看所有变量(普通或环境)或env
#增
[root@localhost ~]# SIZE=1000
[root@localhost ~]# export SIZE
或
[root@localhost ~]# export SIZE=1000
#查
[root@localhost ~]# set | grep SIZE
HISTFILESIZE=1000
HISTSIZE=1000
SIZE=1000
_=SIZE=1000
或
[root@localhost ~]# env | grep SIZE
HISTSIZE=1000
SIZE=1000
#删
[root@localhost ~]# unset SIZE
[root@localhost ~]# env | grep SIZE
HISTSIZE=1000
[root@localhost ~]#

1.PATH:存放命令路径

#系统中的环境变量
#PATH变量:系统命令存放路径
[root@localhost ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin#问题:将一个系统外部命令使用命令名就可以执行
方法一:可以考虑把自己写的脚本放入PATH对应的目录内
[root@localhost bik.d]# bash prin.sh 
Bash
also
a
of
[root@localhost bik.d]# cp -a prin.sh /usr/bin/
[root@localhost ~]# chmod +x /usr/bin/prin.sh
[root@localhost ~]# prin.sh
Bash
also
a
of
[root@localhost ~]#方法二:修改PATH变量的值,将我们存放脚本的目录叠加到PATH变量中
[root@localhost ~]# rm -rf /usr/bin/prin.sh 
[root@localhost ~]# echo $PATH
/root/.local/bin:/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
[root@localhost ~]# PATH=$PATH:/root/bik.d
[root@localhost ~]# echo $PATH
/root/.local/bin:/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bik.d
[root@localhost ~]# chmod +x /root/bik.d/prin.sh 
[root@localhost ~]# prin.sh 
Bash
also
a
of
[root@localhost ~]# #永久设置PATH变量:
单用户生效:~/.bash_profile
所有用户生效:/etc/profile
PATH=$PATH:/root/bik.d  #在末行写入命令,保存退出后重载#相关的配置文件(顺序执行):
/etc/profile => ~/.bash_profile => ~/.bashrc => /etc/bashrc
#修改/etc路径下的配置文件将会应用到整个系统,属于系统级的配置
#修改用户目录下的.bashrc则只是限制在用户应用上,属于用户级设置

2.PS1:命令提示符设置

[root@localhost ~]# echo $PS1
[\u@\h \W]\$
  • \u:显示当前用户名
  • \h:显示简写主机名。如默认主机名“localhost”,全名是“localhost.localdomain”
  • \W:显示当前所在目录的最后一个目录
  • \$:提示符。如果是root提示符为“#”,如果是普通用户提示符为“$”
  • \H:显示完整的主机名。如默认主机名“localhost.localdomain”
  • \d:显示日期,格式为“星期月日”Ø
  • \t:显示24小时制时间,格式为“HH:MM:SS”
  • \T:显示12小时制时间,格式为“HH:MM:SS”
  • \A:显示24小时制时间,格式为“HH:MM”
  • \@:显示12小时制时间,格式为“HH:MM am/pm”
  • \v:显示Bash的版本信息
  • \w:显示当前所在目录的完整名称
  • \#:执行的第几个命令
[root@localhost ~]# echo $PS1
[\u@\h \W]\$
[root@localhost ~]# PS1='[\u@\H \w]'
[root@localhost ~]cd bik.d/
[root@localhost ~/bik.d]

注:跟系统环境相关的变量,但env命令查不到;自定义PS1时需要使用单引号,否则不生效

永久设置:vim /etc/bashrc

3.LANG:系统语系变量

查:localectl list-locales——查看Linux支持的所有语系

改:localectl set-locale LANG=en_US(退出当前终端后生效)或cat /etc/locale.conf

永久修改:vim /etc/locale.conf

预定义变量

  • $?:判断命令是否正确执行
  • $$:当前进程的进程号(PID)
  • $!:后台运行的最后一个进程的进程号(PID)
[root@19:52 ~]# echo $$
878
[root@19:53 ~]# echo $![root@19:53 ~]# top &
[1] 1304
[root@19:53 ~]# echo $!
1304

位置参数变量

作用:根据调用脚本时传入参数值的位置,进行变量赋值或取值

  • $n:n可以是0,1,2,3....,但是10以后要加大括号,$0是脚本名
  • $*/$@:取所有的值

区别:$*取值是一个整体;$@取的每一个值都是可以分开的

实验:编写一个test.sh脚本,输出位置参数

[root@20:01 ~]# bash test.sh 1 2 3 4 5 6 7 8 9 10
$0的值是:test.sh
$1的值是:1
$2的值是:2
$10的值是:10

注:$n按顺序取值,但是十以及十以后的值需要加大括号,否则

[root@20:03 ~]# bash test.sh 1 2 3 4 5 6 7 8 9 abs
$0的值是:test.sh
$1的值是:1
$2的值是:2
$10的值是:10

[root@20:05 ~]# bash test.sh 1 2 3 4 5 6 7 8 9 abs
$0的值是:test.sh
$1的值是:1
$2的值是:2
$10的值是:abs

$*和$@取值:在test.sh中写入命令

[root@20:08 ~]# bash test.sh 1 2 3 4 5 6 7 8 9 abs
$0的值是:test.sh
$1的值是:1
$2的值是:2
$10的值是:abs
$*的值是1 2 3 4 5 6 7 8 9 abs
$@的值是1 2 3 4 5 6 7 8 9 abs

测试两者的不同,用for循环​​​​​​​

http://www.xdnf.cn/news/1365841.html

相关文章:

  • Tesseract OCR之页面布局分析
  • Linux系统的网络管理(一)
  • c# 读取xml文件内的数据
  • 网络编程-HTTP
  • zookeeper-znode解析
  • 【动态规划】309. 买卖股票的最佳时机含冷冻期及动态规划模板
  • 深入浅出 ArrayList:从基础用法到底层原理的全面解析(中)
  • 【C语言16天强化训练】从基础入门到进阶:Day 11
  • 信号处理的核心机制:从保存、处理到可重入性与volatile
  • 系统架构设计师-计算机系统存储管理的模拟题
  • 【数据结构】栈和队列——队列
  • AR远程协助:能源电力行业智能化革新
  • 数据库迁移幂等性介绍(Idempotence)(Flyway、Liquibase)ALTER、ON DUPLICATE
  • 05 开发环境和远程仓库Gitlab准备
  • coze工作流200+源码,涵盖AI文案生成、图像处理、视频生成、自动化脚本等多个领域
  • 向量库Qdrant vs Milvus 系统详细对比
  • 智能专网升级:4G与5G混合组网加速企业数字化转型
  • FunASR基础语音识别工具包
  • 【Canvas与标牌】维兰德汤谷公司logo
  • JavaScript 中类(class)的super 关键字
  • 【YOLOv5部署至RK3588】模型训练→转换RKNN→开发板部署
  • UniApp文件上传大小限制问题解决方案
  • kafka 副本集设置和理解
  • kafka常用命令
  • 宋红康 JVM 笔记 Day07|本地方法接口、本地方法栈
  • Linux(四):进程状态
  • python项目中pyproject.toml是做什么用的
  • SDC命令详解:使用set_timing_derate命令进行约束
  • K8s高可用:Master与候选节点核心解析
  • 基于MalConv的恶意软件检测系统设计与实现