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

shell脚本编译与解析

文章目录

    • shell
      • 变量
        • 全局变量(环境变量)
        • 局部变量
        • 设置PATH 环境变量
        • 修改变量属性
      • 启动文件
        • 环境变量持久化
      • ./和. 的区别
      • 脚本编写
      • 判断 和循环
      • 命令行参数
        • 传入参数
        • 循环读取命令行参数
        • 获取用户输入
      • 处理选项
        • 处理简单选项
        • 处理带值选项
      • 重定向
        • 显示并且同时输出到文件
      • 替换目录下的所有文件中某个关键字
      • 删除关键字所在行

shell

shell的作用是将我们输入的命令与内核沟通。

linux默认使用的是bash shell
echo $SHELL可以查看当前使用的shell版本

shell中如果想一次执行多条命令,可以用分号隔开,多条命令的组合可以放到一个文件中,我们把它叫做脚本。
date ; cd这样就编写了一个非常简单的shell脚本。

变量

存储shell会话和工作环境的相关信息。
环境变量存储在内存中,以便shell中运行的脚本和程序能够访问。
环境变量分为:全局变量和局部变量
全局变量:对当前shell以及所有子shell可见
局部变量:只在当前shell可见,子shell不可见

所以全局变量和局部变量差异就是是否 可以被子进程使用

全局变量(环境变量)

set 查看当前shell所有变量,包括全局和局部
env 查看当前shell下所有环境变量(只能查看全局变量)
printenv HOME 查看某个全局环境变量的值
echo $HOME 查看环境变量
echo $$ 查看当前shell的pid

export作用是将局部变量转换成全局变量
export my_all_home=/lib/lib 设定全局环境变量

子shell可以查看和使用但不能修改父shell中的全局环境变量

unset my_all_home 删除环境比哪里

局部变量

没有命令能够查看所有局部变量
设定局部变量 myhome=/lib/
查看某个局部变量
变量内若有空格可以使用双引号或者单引号myhome=/lib/ jj

设置PATH 环境变量

当输入一个外部命令时,shell会搜索系统从中找到对应程序。
PATH环境变量定义了用于查找命令和程序的目录。
如果要执行的外部命令在PATH中查找不到应用程序,则会报错。

如果要在PATH后继续添加路径,我们可以使用冒号累加
export PATH=$PATH:/lib

修改变量属性

变量默认是字符串类型
可以使用declare改变变量类型
declare -a var 将变量修改为数组类型

启动文件

  1. 在系统的启动shell中会启动/etc/profile 一旦启动shell就会执行该文件中的命令
  2. HOME目录下的启动文件。在启用一个新shell时会用到下面的启动文件
    ls -a home目录可以看到
    ./bashrc ubuntu的home目录启动文件
环境变量持久化

所以./bashrc文件的作用就是我们可以将要使用的全局环境变量放到这个文件中,那么我们一旦开启新的shell则自动拥有这个环境变量

如果不想重启立即生效,则执行source ~/.bashrc

./和. 的区别

  1. 点空格斜杠执行脚本,是相当于source 执行脚本,也就是说在当前进程中执行命令,所以其中所有变量的设置会对当前Shell其作用

  2. 点斜杠执行脚本是外部命令,所以他会启动子进程然后运行,所以一些局部变量就不起作用。

也就是说设置环境变量的时候我们使用source或者说. 空格可以直接生效。

脚本编写

使用shell脚本文件,必须在第一行指明所使用的shell版本
#!/bin/bash
表示使用的是bash shell

#!/bin/bashdate
# 打印字符串
echo "let's go"
# 将下一行打印到当前行连到一起
echo -n "let's go at:"
date
# 打印环境变量,两种均可
echo "HOME: $HOME"
echo "user: ${USER}"# 用户自定义变量,只在本脚本中生效
var1=10
echo "var1= $var1"
var2=$var1
echo "var2= $var2"# 将shell的输出赋值给变量
var_date=`date`
echo "$var_date"

判断 和循环

在这里插入图片描述在这里插入图片描述


# if后面的命令执行成功返回0,则可以进入then
if date
thenecho "date works"
elseecho "date not work"
fi
# if后面只能跟命令,如果要进行条件判断则需要加大括号
if [ 1 -eq 2 ]
thenecho "1 = 2"
elseecho "1 != 2"
fi
# while
var2=5
while [ $var2 -gt 0 ]
doecho "$var2 test"var2=$[ $var2-1 ]
done# for var in list 读取列表
for i in Ala Alb Alc
doecho "test: $i"
donelist="Ala Alb Alc"
if date
thenecho "date works"
elseecho "date not work"
fi
# if后面只能跟命令,如果要进行条件判断则需要加大括号
if [ 1 -eq 2 ]
thenecho "1 = 2"
elseecho "1 != 2"
fi
# while
var2=5
while [ $var2 -gt 0 ]
doecho "$var2 test"var2=$[ $var2-1 ]
done# for var in list 读取列表
for i in Ala Alb Alc
doecho "test: $i"
donelist="Ala Alb Alc"
for i in $list
doecho "test: $i"
done# for in c style
for ((i=1; i<10; i++))
doecho "for in c $i"
done
# for遍历目录
for file in /home/*
doif [ -d "$file" ]thenecho "$file is a dir"elif [ -f "$file" ]thenecho "$file is a file"fi
done

命令行参数

传入参数

对传入参数检查,如果缺少参数会产生很糟糕的结果

# args
echo $0  #./1.sh 不单单是程序名称
echo $1
if [ -n "$2" ] # 如果有参数2
# if [ -z "$2" ] 如果没有参数2
thenecho $2
elseecho no args 2
fi
循环读取命令行参数
#当前进程pid
# $$
#统计参数个数
echo "param count $#" for param in "$*"
doecho "Parameter * = $param"
done
for param in "$@"
doecho "Parameter @ = $param"
done

./1.sh a b c d
param count 4
Parameter * = a b c d
Parameter @ = a
Parameter @ = b
Parameter @ = c
Parameter @ = d

获取用户输入

当执行脚本到后,还可以使用read在脚本运行中获取用户输入以做下一步判断。

处理选项

处理简单选项

遍历所有选项,选择符合条件的

while [ -n "$1" ] #循环检测第一个参数,如果第一个参数存在则进入循环
docase "$1" in-a) echo "found the -a option";; # 双引号为语法-b) echo "found the -b option";;-c) echo "found the -c option";;*) echo "no matching option";; # 默认序列esac # case结束符shift # 将参数左移一个位置
done

(base) [user1@sysqa-h3c-b10 ~]$ ./1.sh -b -c -d -a
found the -b option
found the -c option
no matching option
found the -a option

处理带值选项

脚本检测选项中附加的参数,然后进行处理

while [ -n "$1" ] #循环检测第一个参数,如果第一个参数存在则进入循环
#while [ $# -gt 0 ] # 也可以使用这个判断,如果参数个数非0
docase "$1" in-a) echo "found the -a option";; # 双引号为语法-b) param="$2"echo "found the -b option, param=$param"shift;; #因为加了个参数所以要移一位-c) echo "found the -c option";;--) shift   #发现破折号,则选项列表结束,脚本将剩余参数作为参数而不是选项处理break;; #退出循环去处理剩余参数*) echo "no matching option";; # 默认序列esac # case结束符shift # 将参数左移一个位置
done

(base) [user1@sysqa-h3c-b10 ~]$ ./1.sh -a -b 4 -d -c
found the -a option
found the -b option, param=4
no matching option
found the -c option

#!/bin/bash  # 定义长短选项  
while [[ $# -gt 0 ]]; do  case "$1" in  -h|--help)  echo "Usage: $0 [-o|--output=FILE] [-v|--verbose] [file...]"  echo "  -o, --output=FILE   Specify output file"  echo "  -v, --verbose       Enable verbose mode"  echo "  -h, --help          Display this help message"  exit 0  ;;  -o|--output)  shift # 跳过选项本身  output_file="$1"  shift # 跳过值  ;;  -v|--verbose)  verbose_flag=true  ;;  --) # 结束选项解析  shift  break  ;;  *) # 未知选项  echo "Error: Unknown option $1"  exit 1  ;;  esac  shift # 跳过当前参数  
done  # 检查是否提供了至少一个非选项参数  
if [ $# -eq 0 ]; then  echo "Error: No input files provided."  echo "Usage: $0 [-o|--output=FILE] [-v|--verbose] [file...]"  exit 1  
fi  # 处理非选项参数(这里简单打印出来)  
echo "Processing files:"  
for file in "$@"; do  echo "  $file"  # 在这里可以添加处理文件的代码,例如使用cat, grep, sed等命令  
done  # 根据选项执行相应的操作  
if [ -n "$output_file" ]; then  echo "Output file specified: $output_file"  # 在这里可以添加将处理结果写入文件的代码  
fi  if $verbose_flag; then  echo "Verbose mode is enabled."  # 在这里可以添加冗余输出的代码  
fi  # 脚本结束  
exit 0

重定向

在这里插入图片描述标准输入是键盘
输入重定向符号为 < ,也就是输入不再从键盘,而是从其他地方比如文件

标准输出是显示器
输出重定向符号为 >, 也就是输出不再到显示器二十到其他地方比如文件
使用 >> 重定向输出追加

标准错误输出
shell是将错误消息与正常输出分开处理,所以如果发生错误,还是会输出到屏幕
ls badfile 2> a.txt 可以将标准错误输出到文件

数据和错误同时输出到一个文件
ls badfile &> a.txt或者 2&>1
数据和错误分别输出
ls badfile 1> a.txt 2>b.txt

如果想把一个命令的输出作为另一个命令的输入,可以使用重定向
date > 1.log
sort < 1.log

但是需要两条命令, 看起来有点笨拙。
使用管道符则可以直接完成这个功能
date | sort

显示并且同时输出到文件

tee命令
date | tee 1.txt
如果希望追加则加 -a

替换目录下的所有文件中某个关键字

#!/bin/bash
# find path and replace all .c file keywords is "while" to "for"
find ./ -name "*.c" -exec sed -i 's/hip/mc/g' {} \;

删除关键字所在行

find ./ -name "*.c" -exec sed -i '/load_json_helper/d' {} \;
http://www.lryc.cn/news/298662.html

相关文章:

  • 第64讲个人中心用户操作菜单实现
  • 线性代数的本质——1 向量
  • 工业以太网交换机引领现代工厂自动化新潮流
  • Linux第46步_通过“添加自定义菜单”来学习menuconfig图形化配置原理
  • 推荐高端资源素材图库下载平台整站源码
  • Redis实现:每个进程每30秒执行一次任务
  • 【AI之路】使用RWKV-Runner启动大模型,彻底实现大模型自由
  • Dockerfile和.gitlab-ci.yml文件模板
  • Linux--基础开发工具篇(2)(vim)(配置白名单sudo)
  • Learn LaTeX 017 - LaTex Multicolumn 分栏
  • Android 9.0 禁用adb install 安装app功能
  • 华为第二批难题五:AI技术提升六面体网格生成自动化问题
  • 【FFmpeg】ffplay 命令行参数 ⑤ ( 设置音频滤镜 -af 参数 | 设置统计信息 -stats 参数 | 设置同步时钟类型 -sync 参数 )
  • vscode开发FPGA(0)--windows平台搭建
  • Java String源码剖析+面试题整理
  • 探索未来:集成存储器计算(IMC)与深度神经网络(DNN)的机遇与挑战
  • [C/C++] -- CMake使用
  • 笔记本选购配置参数详解
  • 临睡之际的生死思索与生命哲学的启示
  • QT学习(五)C++函数重载
  • 微服务OAuth 2.1扩展额外信息到JWT并解析(Spring Security 6)
  • Python@setter用法介绍
  • 格子表单GRID-FORM | 文档网站搭建(VitePress)与部署(Github Pages)
  • mac无法往硬盘里存东西 Mac硬盘读不出来怎么办 Mac硬盘格式 硬盘检测工具
  • DataX源码分析 reader
  • openssl3.2 - exp - RAND_bytes_ex
  • Oracle中怎么设置时区和系统时间
  • 常见的物联网操作系统介绍
  • 二级C语言笔试10
  • 【WebSocket】微信小程序原生组件使用SocketTask 调用星火认知大模型