ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

shell脚本编译与解析

2026/9/19 16:06:44 拓冰建站 浏览量
shell脚本编译与解析

文章目录

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

shell

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

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

环境变量

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

全局变量

printenv 查看所有全局变量(只能查看全局变量)
printenv HOME 查看某个全局环境变量的值
echo $HOME 查看环境变量

export my_all_home=/lib/lib 设定全局环境变量

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

unset my_all_home 删除环境比哪里

局部变量

没有命令能够查看所有局部变量
设定局部变量
myhome=/lib/
查看某个局部变量

设置PATH 环境变量

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

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

启动文件

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

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

脚本编写

使用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"

重定向

输出重定向到文件
date > test1.txt 覆盖
date >> test1.txt 追加

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

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

判断 和循环

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


# 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
数据和错误分别输出
ls badfile 1> a.txt 2>b.txt

显示并且同时输出到文件

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' {} \;