文章目录
- 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
启动文件
- 在系统的启动shell中会启动/etc/profile 一旦启动shell就会执行该文件中的命令
- 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' {} \;