编辑
2024-08-15
系统运维-Linux
00
请注意,本文编写于 603 天前,最后修改于 0 天前,其中某些信息可能已经过时。

目录

获取脚本参数
获取脚本变量参数的值
判断命令是否执行成功
检查命令的退出状态
在文件 /root/test.txt 的第三行前 插入 Hello World
在文件 /root/test.txt 另起一行 插入 Hello World
在当前目录(.)下, 查询后缀名称为md的文件(-type f), 并强制删除
这个命令看着像是多此一举, 定睛一看确实是多次一举
方法一:利用grep查找(简单,推荐)
方法二:利用字符串运算符(超简单,推荐)
方法三:利用通配符(简单,推荐)
方法四:利用case in 语句(复杂,不推荐)
方法五:利用替换(复杂,不推荐)
方法六:利用expr,如果包含会返回位置
方法一:使用for循环遍历
方法二:使用while循环和索引遍历
方法三:使用for循环和索引遍历
command-to-run 是你想要在后台运行的命令。
> 是重定向输出的符号,表示将标准输出(stdout)重定向到 output.log 文件。
2>&1 表示将标准错误(stderr)也定向到标准输出(stdout),即 output.log 文件。
& 在命令的最后使得该命令在后台运行。
重复输出 Hello World 5次

Shell 脚本是 Linux 系统运维与自动化任务的核心工具,掌握常用表达式和语法能显著提升脚本编写效率。本文整理了一份全面的 Shell 表达式与语法速查清单,涵盖:脚本参数获取($0$1$2)、命令执行状态判断($?)、文件测试运算符(-d-f-e-z-n 等详解)、字符串比较与子串判断(===~*$B*grepexpr 等多种方法)、数值比较(-eq-ne-lt-le-gt-ge)、文件内容操作(sed 插入、echo 追加)、批量删除(find + xargs rm)、批量执行(xargs -I{})、数组遍历(for 循环、while 索引)、后台运行(nohup)、进程存在判断(ps -ef | grep -w)、带参运行 Java 应用(JVM 11 G1GC 调优参数)、重复执行命令(for i in $(seq 1 5))。

本文适用于 Linux 运维人员和 Shell 脚本开发者。

获取脚本参数

shell
$0 获取脚本文件名本身 $1 获取第一个参数 $2 获取第二个参数 # 以此类推...

获取脚本变量参数的值

shell
# eg. demo.sh hostname=xxxxx hostname=$(echo $1 | cut -d'=' -f2) echo $hostname

判断命令是否执行成功

shell
# 写法一 #!/bin/sh # 执行一个命令 ls /root # 检查命令的退出状态 if [ $? -eq 0 ]; then echo "命令执行成功" else echo "命令执行失败" fi ## 判断命令是否执行失败 ```shell ls /root # 检查命令的退出状态 if [ $? -ne 0 ]; then echo "命令执行失败" else echo "命令执行成功" fi

if -z至-d含义

text
[ -a FILE ] 如果 FILE 存在则为真。 [ -b FILE ] 如果 FILE 存在且是一个块特殊文件则为真。 [ -c FILE ] 如果 FILE 存在且是一个字特殊文件则为真。 [ -d FILE ] 如果 FILE 存在且是一个目录则为真。 [ -e FILE ] 如果 FILE 存在则为真。 [ -f FILE ] 如果 FILE 存在且是一个普通文件则为真。 [ -g FILE ] 如果 FILE 存在且已经设置了SGID则为真。 [ -h FILE ] 如果 FILE 存在且是一个符号连接则为真。 [ -k FILE ] 如果 FILE 存在且已经设置了粘制位则为真。 [ -p FILE ] 如果 FILE 存在且是一个名字管道(F如果O)则为真。 [ -r FILE ] 如果 FILE 存在且是可读的则为真。 [ -s FILE ] 如果 FILE 存在且大小不为0则为真。 [ -t FD ] 如果文件描述符 FD 打开且指向一个终端则为真。 [ -u FILE ] 如果 FILE 存在且设置了SUID (set user ID)则为真。 [ -w FILE ] 如果 FILE 如果 FILE 存在且是可写的则为真。 [ -x FILE ] 如果 FILE 存在且是可执行的则为真。 [ -O FILE ] 如果 FILE 存在且属有效用户ID则为真。 [ -G FILE ] 如果 FILE 存在且属有效用户组则为真。 [ -L FILE ] 如果 FILE 存在且是一个符号连接则为真。 [ -N FILE ] 如果 FILE 存在 and has been mod如果ied since it was last read则为真。 [ -S FILE ] 如果 FILE 存在且是一个套接字则为真。 [ FILE1 -nt FILE2 ] 如果 FILE1 has been changed more recently than FILE2, or 如果 FILE1 exists and FILE2 does not则为真。 [ FILE1 -ot FILE2 ] 如果 FILE1 比 FILE2 要老, 或者 FILE2 存在且 FILE1 不存在则为真。 [ FILE1 -ef FILE2 ] 如果 FILE1 和 FILE2 指向相同的设备和节点号则为真。 [ -o OPTIONNAME ] 如果 shell选项 “OPTIONNAME” 开启则为真。 [ -z STRING ] “STRING” 的长度为零则为真。 [ -n STRING ] or [ STRING ] “STRING” 的长度为非零 non-zero则为真。 [ STRING1 == STRING2 ] 如果2个字符串相同。 “=” may be used instead of “==” for strict POSIX compliance则为真。 [ STRING1 != STRING2 ] 如果字符串不相等则为真。 [ STRING1 < STRING2 ] 如果 “STRING1” sorts before “STRING2” lexicographically in the current locale则为真。 [ STRING1 > STRING2 ] 如果 “STRING1” sorts after “STRING2” lexicographically in the current locale则为真。 [ ARG1 OP ARG2 ] “OP” is one of -eq, -ne, -lt, -le, -gt or -ge. These arithmetic binary operators return true if “ARG1” is equal to, not equal to, less than, less than or equal to, greater than, or greater than or equal to “ARG2”, respectively. “ARG1” and “ARG2” are integers.

在文件第几行前插入文本内容

shell
# 在文件 /root/test.txt 的第三行前 插入 Hello World sed -i "3i Hello World" /root/test.txt

在文件末尾追加一行文本内容

shell
# 在文件 /root/test.txt 另起一行 插入 Hello World echo 'Hello World' >> root/test.txt

批量删除之xargs

它可以将管道或标准输入转换成命令行参数,并用这些参数来执行指定的命令。默认情况下, xargs 命令会将输入按照空格、制表符、换行符等符号进行分隔,并将它们作为一组参数传递给指定的命令。如果没有输入,则 xargs 命令会读取用户的键盘输入,并将其用作参数

shell
# 在当前目录(.)下, 查询后缀名称为md的文件(-type f), 并强制删除 find . -name '*.md' -type f|xargs rm -f

批量执行之xargs

-I<替代字符串>,它允许我们在命令行中使用替代字符串来代替 xargs 接收到的参数。特别地,{} 符号通常用作替代字符串。当 xargs 命令遇到 {} 符号时,它会将其替换为输入中的值,然后执行指定的命令

shell
# 这个命令看着像是多此一举, 定睛一看确实是多次一举 find . -name '*.md' -type f|xargs -I{} echo {}

判断字符串是否不为空

shell
#!/bin/bash string="example" if [[ -n $string ]]; then echo "字符串不为空" else echo "字符串为空" fi

判断字符串是否为空

shell
#!/bin/bash string="example" if [[ -z $string ]]; then echo "字符串为空" else echo "字符串不为空" fi

判断字符串是否包含子串

shell
# 方法一:利用grep查找(简单,推荐) strA="long string" strB="string" result=$(echo $strA | grep "${strB}") if [[ "$result" != "" ]] then echo "包含" else echo "不包含" fi # 方法二:利用字符串运算符(超简单,推荐) strA="helloworld" strB="low" if [[ $strA =~ $strB ]] then echo "包含" else echo "不包含" fi # 方法三:利用通配符(简单,推荐) A="helloworld" B="low" if [[ $A == *$B* ]] then echo "包含" else echo "不包含" fi # 方法四:利用case in 语句(复杂,不推荐) thisString="1 2 3 4 5" # 源字符串 searchString="1 2" # 搜索字符串 case $thisString in *"$searchString"*) echo "包含";; *) echo "不包含" ;; esac # 方法五:利用替换(复杂,不推荐) STRING_A="helloworld" STRING_B="low" if [[ ${STRING_A/${STRING_B}//} == $STRING_A ]] then echo "不包含" else echo "包含" fi # 方法六:利用expr,如果包含会返回位置 STRING1="hello world" STRING2="wor" if [[ `expr index "$STRING1" $STRING2` == 0 ]] then echo "name dont contain $STRING2" else echo `expr index "$STRING1" $STRING2` fi

判断两个字符串是否相等

shell
#!/bin/bash string1="Hello, World!" string2="World" if [ "$value1" = "$value2" ]; then echo "两个值相等" else echo "两个值不相等" fi

判断两个数字是否相等

shell
#!/bin/bash num1=10 num2=20 if [ "$num1" -eq "$num2" ]; then echo "两个数字相等" else echo "两个数字不相等" fi

遍历数组

shell
# 方法一:使用for循环遍历 array=("Apple" "Banana" "Orange") for item in "${array[@]}" do echo $item done # 方法二:使用while循环和索引遍历 array=("Apple" "Banana" "Orange") index=0 while [ $index -lt ${#array[@]} ] do echo ${array[$index]} index=$((index + 1)) done # 方法三:使用for循环和索引遍历 array=("Apple" "Banana" "Orange") for ((index=0; index<${#array[@]}; index++)) do echo ${array[$index]} done

后台运行命令 nohup

用来运行另一个命令,使得该命令在后台执行,并且即使终端关闭也不会被中断。

shell
nohup command-to-run > output.log 2>&1 & # command-to-run 是你想要在后台运行的命令。 # > 是重定向输出的符号,表示将标准输出(stdout)重定向到 output.log 文件。 # 2>&1 表示将标准错误(stderr)也定向到标准输出(stdout),即 output.log 文件。 # & 在命令的最后使得该命令在后台运行。

判断进程是否存在

每秒检查一次名为my_process的进程是否存在,如果存在则继续等待,直到进程不存在为止。

shell
#!/bin/bash process_name="my_process" until ! ps -ef | grep -w $process_name > /dev/null; do echo "等待 $process_name 退出..." sleep 1 done echo "$process_name 已退出."

带参运行java应用(jvm11调优)

G1GC 不必明确设置新生代大小,其自动调优也十分可靠,对于停顿时间往往在长时间运行后可以达到预期效果。 不建议进行过多的配置,对于 gc log 我认为还是很有必要,各位同学可以按照自己的实际需求进行配置。

shell
java -server \ -Xmx2g \ -Xms2g \ -Xss256k \ -XX:MaxDirectMemorySize=256m \ -XX:+UseG1GC \ -XX:+UseCompressedOops \ -XX:+UseCompressedClassPointers \ -XX:+SegmentedCodeCache \ -verbose:gc \ -XX:+PrintCommandLineFlags \ -XX:+ExplicitGCInvokesConcurrent \ -Djava.security.egd=file:/dev/./urandom \ -Xlog:gc*,safepoint:/boot/logs/gc.log:time,uptime:filecount=100,filesize=50M \ -Dconfig.file=application-${APP_ENV}.yaml

重复执行命令

shell
# 重复输出 Hello World 5次 for i in $(seq 1 5); do echo 'Hello World!' done
如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:Odboy

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 CC 4.0 BY-SA 许可协议。转载请注明出处!