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

面试 Linux 运维相关问题

标题Q1Shell脚本是什么、它是必需的吗?

Shell脚本是一种用于自动化执行命令行任务的脚本程序,通常运行在Unix/Linux系统的Shell环境中(如Bash)。它通过将多个命令、逻辑控制(如条件判断、循环)和系统功能整合到一个文件中,实现任务的批量处理或复杂操作。

是否必需?

  • 非必需:如果只是简单使用命令行,手动输入命令即可满足需求。
  • 但高度推荐:在以下场景中,Shell脚本能显著提升效率:
    1. 重复性任务(如批量重命名文件、定期备份)。
    2. 系统管理(自动化安装软件、监控资源)。
    3. 复杂流程(组合多个命令,添加逻辑判断)。

示例

#!/bin/bash
# 统计当前目录下所有.txt文件的行数
for file in *.txt; doecho "$file: $(wc -l < "$file") lines"
done

替代方案

  • 其他脚本语言(如Python、Perl)也可实现类似功能,但Shell脚本在直接调用系统命令时更简洁高效。

总结:是否需要取决于任务复杂度,但掌握基础Shell脚本能大幅提升工作效率。

标题Q2什么是默认登录shell,如何改变指定用户的登录shell

默认登录Shell与修改方法

1. 默认登录Shell说明
Linux系统中默认登录Shell由以下因素决定:

  • 发行版策略:Ubuntu/Debian 默认使用 /bin/bash,Alpine Linux 使用 /bin/ash
  • 用户创建规则:通过 /etc/default/useradd 文件中的 SHELL 参数定义

2. 修改用户登录Shell方法
(需root权限)

方法一:chsh 命令

sudo chsh -s /bin/zsh username  # 将username用户的shell改为zsh

方法二:usermod 命令

sudo usermod --shell /bin/fish username  # 修改为fish shell

方法三:手动编辑配置文件

sudo vipw  # 安全编辑/etc/passwd
# 找到用户行,将路径修改为:username:x:1000:1000::/home/username:/bin/sh

关键验证步骤

  1. 检查目标shell是否在合法列表:
cat /etc/shells  # 显示所有可用shell
# 若没有需先安装并添加:echo "/usr/local/bin/my-shell" | sudo tee -a /etc/shells
  1. 立即生效验证:
su - username  # 重新登录测试
echo $SHELL    # 显示当前登录shell
注意事项
系统服务账户不要随意修改shell(如mysql、www-data等)
远程SSH用户修改shell后需重新建立连接才能生效
若/etc/passwd中指定的shell不存在,用户将无法正常登录

标题Q3可以在shell脚本中使用哪些类型的变量?

Shell脚本变量类型详解

在Shell脚本编程中,主要支持以下7类变量:

  1. 局部变量 (Local Variables)
var1="hello"        # 普通定义
function demo() {local var2=100  # 函数内局部变量
}
  1. 环境变量 (Environment Variables)
export PATH="/usr/local/bin:$PATH"  # 全局可访问
env | grep PATH                     # 查看环境变量
  1. 位置参数 (Positional Parameters)
#!/bin/bash
# 执行方式:./script.sh apple banana
echo $0    # 输出脚本名称 → ./script.sh
echo $1    # 第一个参数 → apple
echo $@    # 所有参数列表 → apple banana
  1. 特殊变量 (Special Variables)
echo $$    # 当前进程PID
echo $?    # 上条命令退出码
echo $#    # 参数个数
echo $*    # 所有参数合并为单个字符串
  1. 数组变量 (Array Variables)
colors=("red" "green" "blue")  # 索引数组
echo ${colors[1]}              # 输出 greendeclare -A dict                # 关联数组(Bash4+)
dict["key1"]=100
dict["key2"]=200
  1. 只读变量 (Read-only Variables)
readonly MAX=100
MAX=200  # 报错:MAX: readonly variable
  1. 命令行参数变量
while getopts ":a:bc" opt; docase $opt ina) arg_a=$OPTARG;;  # -a 参数值存入arg_ab) flag_b=true;;    # 处理-b标志esac
done

变量操作技巧

  • 默认值设置:${var:-default}
  • 长度获取:${#string}
  • 子字符串:${string:0:5}
  • 变量删除:unset var_name

作用域示意图

+-----------------------+
|   Environment Vars    | ← 被子进程继承
+-----------------------+
|   Script Global Vars  | ← 整个脚本可见
+-----------------------+
|  Function Local Vars  | ← 仅函数内部可见
+-----------------------+

标题Q4如何将标准输出和错误输出同时重定向到同一位置?

在Shell中实现标准输出(stdout)和错误输出(stderr)合并重定向有以下三种常用方式:

1. 传统格式(兼容所有Bourne shell)

command > output.log 2>&1
  • > 先重定向stdout到文件
  • 2>&1 再将stderr指向stdout的当前位置(即文件)

2. 现代简写(Bash/Zsh专用)

command &> output.log
# 或等价的
command >& output.log

3. 追加模式(保留原文件内容)

# 传统追加写法
command >> combined.log 2>&1# Bash简写追加
command &>> combined.log

管道处理技巧
同时输出到终端和文件:

command 2>&1 | tee combined.log

执行过程分解示例

# 生成两种输出的测试命令
ls exist_file non_exist_file > out.log 2>&1# 结果文件内容示例:
# exist_file
# ls: cannot access 'non_exist_file': No such file or directory

重定向顺序的重要性
错误示范(stderr不会进入文件):

command 2>&1 > output.log
# 分解:
# 1. 2>&1 → stderr指向当前stdout(终端)
# 2. > output.log → stdout重定向到文件

高级用法:全局重定向

# 对整个脚本生效
exec > >(tee -a script.log) 2>&1
echo "正常信息"
ls invalid_file  # 错误信息也会进入script.log

标题Q5shell脚本中“if”语法如何嵌套?

在Shell脚本中实现if条件嵌套需遵循特定的语法结构:

基础嵌套结构

if [ 条件1 ]
thenif [ 条件1-A ]then命令组1else命令组2fi
elif [ 条件2 ]
then命令组3
else命令组4
fi

多层嵌套示例(文件检测)

#!/bin/bash
file="/data/report.log"if [ -e "$file" ]
thenecho "文件存在"if [ -s "$file" ]thenif [ -w "$file" ]thenecho "可写非空文件,开始处理..."# 处理逻辑elseecho "错误:文件不可写" >&2exit 1fielseecho "警告:文件内容为空" >&2fi
elseecho "错误:文件不存在" >&2exit 2
fi

嵌套优化技巧

  1. 使用逻辑运算符简化
# AND 组合条件
if [[ -f "$file" && -r "$file" ]]
thenecho "可读的常规文件"
fi# OR 组合条件
if [ "$status" -eq 0 ] || [ "$force" = "true" ]
then执行操作
fi
  1. Case语句替代深层嵌套
case "$OS_TYPE" in"Linux")case "$DISTRO" in"Ubuntu") echo "APT包管理" ;;"CentOS") echo "YUM包管理" ;;esac ;;"Darwin") echo "Homebrew" ;;
esac

常见错误处理

  • 错误:未闭合的fi
# 错误示例
if [ cond1 ]; thenif [ cond2 ]; then...
# 缺少两个fi# 正确写法
if [ cond1 ]; thenif [ cond2 ]; then...fi
fi
  • 错误:条件格式错误
# 错误:缺少空格
if [$var -eq 0]# 正确
if [ $var -eq 0 ]

调试建议
使用-x参数跟踪执行:

bash -x script.sh
# 显示实际执行的嵌套逻辑

标题Q6shell脚本中“$?”标记的用途是什么?

$? 是Shell脚本中的 退出状态码捕获变量,其核心作用与使用场景如下:

1. 基本功能
存储最近执行命令的退出状态码(exit code)

  • 0 → 命令执行成功
  • 1-255 → 执行失败(具体含义由程序定义)

2. 典型使用场景

# 示例1:直接检查
ls /invalid/path
if [ $? -ne 0 ]; thenecho "错误代码: $? → 路径不存在"
fi# 示例2:保存状态码
tar -czf backup.tgz /data
backup_status=$?
[ $backup_status -eq 0 ] && echo "备份成功" || echo "备份失败"# 示例3:错误分级处理
curl -s http://example.com
case $? in0) echo "请求成功" ;;6) echo "DNS解析失败" ;;7) echo "连接拒绝" ;;*) echo "未知错误: $?" ;;
esac

3. 特殊场景注意事项

  • 管道命令 只捕获最后一条命令的状态
grep 'error' log.txt | wc -l
echo $?  # 显示的是wc命令的退出码
  • 复合命令 的状态捕获
(command1 && command2) || command3
echo $?  # 显示整个逻辑链的最终状态

4. 常用状态码对照表

状态码典型含义
0成功
1一般错误
2错误使用shell命令
126命令不可执行
127命令未找到
130通过Ctrl+C终止
143通过SIGTERM终止

5. 自定义退出码
在脚本中通过exit命令设置:

#!/bin/bash
if [ ! -f config.ini ]; thenecho "配置文件缺失" >&2exit 25  # 自定义错误码
fi

调试技巧
实时跟踪状态码变化:

set -x  # 启用调试模式
your_command
echo "状态码: $?"
set +x  # 关闭调试

标题Q7在shell脚本中如何比较两个数字 ?

在Shell脚本中进行数字比较时,需根据具体场景选择合适的比较方式:

1. 基础整数比较(推荐使用双括号)

a=15
b=20# 最佳实践方式
if (( a < b )); thenecho "$a 小于 $b"
elif (( a == b )); thenecho "数值相等"
elseecho "$a 大于 $b"
fi

2. 带类型检查的安全比较

#!/bin/bash
read -p "输入第一个数字: " num1
read -p "输入第二个数字: " num2# 验证输入有效性
if ! [[ "$num1" =~ ^[0-9]+$ ]] || ! [[ "$num2" =~ ^[0-9]+$ ]]; thenecho "错误:必须输入整数" >&2exit 1
fi# 执行比较
if [ "$num1" -gt "$num2" ]; thenecho "$num1 大于 $num2"
elif [ "$num1" -lt "$num2" ]; thenecho "$num1 小于 $num2"
elseecho "两个数字相等"
fi

3. 浮点数比较解决方案

# 使用awk进行精确比较
float1=3.1415
float2=2.71828if awk -v n1="$float1" -v n2="$float2" 'BEGIN {exit (n1 > n2)}'; thenecho "$float1 大于 $float2"
elseecho "$float2 大于或等于 $float1"
fi

4. 多数字排序实践

# 三个数字排序示例
x=5
y=3
z=7if (( x > y )); thentemp=$xx=$yy=$temp
fiif (( y > z )); thentemp=$yy=$zz=$temp
fiif (( x > y )); thentemp=$xx=$yy=$temp
fiecho "排序结果: $x $y $z"

5. 性能对比测试

# 测试不同比较方式的效率
time for i in {1..10000}; do[ $i -gt 5000 ] > /dev/null
donetime for i in {1..10000}; do(( i > 5000 )) > /dev/null
done

注意事项总结

  1. 使用-eq-ne等test运算符时,确保变量值为整数
  2. 双括号(( ))结构支持更丰富的算术运算
  3. 处理用户输入时务必进行类型验证
  4. 浮点比较推荐使用bcawk工具
  5. 在循环体内尽量使用算术扩展方式提升性能

标题shell脚本中break命令的作用 ?

在Shell脚本中,break命令用于提前终止循环(如forwhileuntil),直接跳出当前循环体,继续执行循环之后的代码。


核心作用

  1. 单层循环跳出

    # 示例:找到数字3时立即终止循环
    for i in {1..5}; doif [[ $i -eq 3 ]]; thenbreak  # 跳出循环fiecho "当前值: $i"
    done
    

    输出:

    当前值: 1
    当前值: 2
    
  2. 多层循环跳出
    通过break n指定跳出n层循环(默认n=1):

    # 示例:跳出两层循环
    for i in {1..3}; dowhile true; doecho "i=$i, 内层循环"break 2  # 直接跳出外层for循环done
    done
    

    输出:

    i=1, 内层循环
    

对比continue

  • break完全终止循环,后续迭代不再执行。
  • continue跳过当前迭代,直接进入下一次循环。

典型场景

  • 满足条件时提前终止循环(如搜索到目标后停止)。
  • 避免因异常逻辑导致无限循环。

总结break是控制循环流程的关键命令,合理使用可提升脚本执行效率。

标题Q9shell脚本中continue命令的作用 ?

在Shell脚本中,continue命令用于跳过当前循环迭代的剩余代码,直接进入下一次循环(forwhileuntil),而非终止整个循环。


核心作用

  1. 单层循环跳过

    # 示例:跳过偶数的输出
    for i in {1..5}; doif [[ $i%2 -eq 0 ]]; thencontinue  # 跳过本次循环fiecho "奇数: $i"
    done
    

    输出:

    奇数: 1
    奇数: 3
    奇数: 5
    
  2. 多层循环跳过
    通过continue n指定跳过n层循环的当前迭代(默认n=1):

    # 示例:外层循环i=2时,跳过内层循环
    for i in {1..3}; doecho "外层i=$i"for j in {A..C}; doif [[ $i -eq 2 ]]; thencontinue 2  # 跳过外层循环的当前迭代fiecho "内层j=$j"done
    done
    

    输出:

    外层i=1
    内层j=A
    内层j=B
    内层j=C
    外层i=2
    外层i=3
    内层j=A
    内层j=B
    内层j=C
    

对比break

  • continue:仅跳过当前迭代,继续下一次循环。
  • break完全终止循环,后续迭代不再执行。

典型场景

  • 过滤特定条件的数据(如忽略空文件、排除某些文件名)。
  • 优化循环效率,避免执行不必要的操作。

总结continue是精细化控制循环流程的工具,特别适合需要条件性跳过的场景。

Q10告诉我shell脚本中Case语句的语法 ?

在Shell脚本中,case语句用于实现多条件分支判断,语法结构如下:

case 变量 in模式1)对应模式1的命令;;模式2|模式3)  # 多个模式用|分隔对应模式2/3的命令;;*)  # 默认匹配(类似else)默认命令;;
esac

关键语法说明

  1. 模式匹配

    • 支持通配符:*(任意字符)、?(单个字符)、[0-9](字符范围)
    • 支持逻辑或:模式A|模式B
    • 示例:
      case $input in[Yy]|Yes) echo "确认操作" ;;[Nn]o?)   echo "取消操作" ;;*)        echo "无效输入" ;;
      esac
      
  2. 执行规则

    • 从上到下匹配,首个匹配的模式会触发对应命令
    • ;; 表示结束当前模式块(类似break
    • ;&(Bash 4.0+)可继续执行下一个模式的命令(类似fallthrough

实际应用示例

#!/bin/bash
echo "选择操作:"
read -p "1.启动 2.停止 3.重启: " optcase $opt in1|启动)systemctl start service;;2|停止)systemctl stop service;;3|重启)systemctl restart service;;*)echo "错误:无效选项"exit 1;;
esac

对比if-elif

  • case更适合模式匹配场景(如字符串、通配符)
  • if-elif更适合复杂条件判断(如数值比较、逻辑运算)

Q11shell脚本中while循环语法 ?

在Shell脚本中,while循环用于重复执行命令块,直到条件变为假。其基本语法如下:

while [ 条件判断 ]
do# 循环体(要重复执行的命令)
done

语法详解

  1. 条件判断

    • 支持所有Shell条件表达式(如数值比较、字符串判断、文件测试等)
    • 示例:
      # 数值比较
      while [[ $i -lt 5 ]]# 文件存在性检查
      while [ -f "/tmp/lockfile" ]# 命令返回值判断
      while grep -q "error" log.txt
      
  2. 无限循环

    while true  # 或 while :
    doecho "持续运行..."sleep 1
    done
    
  3. 从文件/输入流读取数据

    while read line
    doecho "行内容: $line"
    done < input.txt
    

典型示例

  1. 计数器循环

    #!/bin/bash
    i=0
    while [ $i -lt 3 ]
    doecho "当前计数: $i"((i++))  # 等同于 i=$((i+1))
    done
    

    输出:

    当前计数: 0
    当前计数: 1
    当前计数: 2
    
  2. 条件动态变化

    # 监控进程是否存在
    while ps -p 1234 > /dev/null
    doecho "进程1234仍在运行"sleep 5
    done
    

流程控制

  • break:立即终止循环
  • continue:跳过当前迭代,进入下一次循环

对比until循环

  • while:条件为时执行
  • until:条件为时执行(until [ 条件 ]; do ... done

总结while循环是自动化重复任务的核心工具,特别适合处理动态条件或流式数据。

Q12如何使脚本可执行 ?

要让Shell脚本可执行,需要通过chmod命令添加执行权限。具体步骤如下:

  1. 添加执行权限

    chmod +x script.sh
    

    或指定具体权限:

    chmod 755 script.sh  # 用户:rwx,组和其他:rx
    
  2. 执行脚本

    • 直接运行(需指定路径):
      ./script.sh
      
    • 全局调用(将脚本放入PATH环境变量目录):
      sudo mv script.sh /usr/local/bin/
      script.sh  # 任意位置直接执行
      

原理说明

  • Linux文件系统中,执行权限(x)是运行脚本的必要条件。
  • #!/bin/bash(Shebang行)指定解释器,确保脚本被正确解析。

验证权限

ls -l script.sh

输出示例:

-rwxr-xr-x 1 user group 0 Jan 1 00:00 script.sh

x表示已获得执行权限)

标题Q13“#!/bin/bash”的作用 ?

#!/bin/bash 称为 Shebang(或 Hashbang),其核心作用是指定脚本的解释器路径,确保脚本使用正确的程序执行。以下是详细说明:


核心功能

  1. 解释器声明

    • 告诉系统使用/bin/bash作为解释器执行脚本内容
    • 若未指定,默认使用当前用户的默认Shell(可能是shzsh等)
  2. 跨环境一致性

    • 避免因不同Shell的语法差异导致脚本执行错误
    • 示例:bash支持数组,而sh不支持

使用规范

  • 必须为文件首行(前两字符#!不可有空格或空行)
  • 路径可调整(根据实际解释器位置):
    #!/usr/bin/env bash  # 推荐:通过环境变量查找bash,增强兼容性
    

对比实验

  1. 无Shebang的脚本

    echo "Hello World"
    
    • 执行方式:bash script.sh(必须显式指定解释器)
  2. 有Shebang的脚本

    #!/bin/bash
    echo "Hello World"
    
    • 执行方式:./script.sh(直接运行)

常见Shebang示例

解释器Shebang行
Python 3#!/usr/bin/python3
Perl#!/usr/bin/perl
Shell(系统默认)#!/bin/sh

验证方法

# 查看当前脚本使用的解释器
ps -p $$ -o comm=
# 输出:bash(若Shebang生效)

总结:Shebang是Shell脚本的“身份证”,明确解释器路径能确保脚本行为可预期。

Q14shell脚本中for循环语法 ?

Shell脚本中常见的for循环语法有以下几种形式:

  1. 基础列表循环
for var in item1 item2 item3
do# 循环体echo $var
done

示例:for i in apple banana cherry; do echo $i; done

  1. 通配符扩展循环
for file in *.txt
doecho "Processing file: $file"
done
  1. C语言风格循环(bash特有)
for ((i=0; i<10; i++))
doecho "Count: $i"
done
  1. 数组遍历
arr=("one" "two" "three")
for item in "${arr[@]}"
doecho $item
done
  1. 数字范围循环(bash 4.0+)
for i in {1..5}
doecho $i
done
  1. 命令输出循环
for user in $(cut -d: -f1 /etc/passwd)
doecho "User: $user"
done

注意:

  • 使用$var时建议加上引号:"$var"
  • 修改IFS可以改变字段分隔方式
  • 不同shell(bash/zsh/sh)可能有细微差异
  • 处理文件名时建议使用for file in *.txt; do ...而不是解析ls输出

Q15如何调试shell脚本 ?

Shell脚本调试常用方法如下:

  1. 基础调试选项
# 执行时启用调试
bash -x script.sh        # 显示执行过程
bash -v script.sh        # 显示原始命令
bash -n script.sh        # 只检查语法不执行# 脚本内启用调试
#!/bin/bash -x           # 直接在shebang启用
set -x                   # 开启调试模式
set +x                   # 关闭调试模式
  1. 组合调试模式
#!/bin/bash -ex          # 同时启用 -e(出错退出)和 -x(调试)
# 或脚本内设置
set -euxo pipefail       # 常用严格模式组合:# -e 遇到错误立即退出# -u 未定义变量报错# -x 打印执行命令# -o pipefail 管道错误捕获
  1. 分段调试
( set -x; 要调试的代码块; set +x )
  1. 输出调试
echo "DEBUG: 当前变量值=$var" >&2   # 输出到标准错误
printf "Processing file: %s\n" $file
  1. trap调试
trap 'echo "Line $LINENO: var=$var"' DEBUG  # 每行执行前触发
trap 'echo "Exit with code $?"' EXIT       # 退出时触发
  1. 日志记录
exec 3>&1 4>&2          # 保存原始输出
exec 1>script.log       # 重定向标准输出
exec 2>&1               # 合并错误输出到日志
  1. 调试工具
bashdb script.sh        # 使用bash调试器# 支持断点/单步执行/变量检查

调试技巧:

  • 使用PS4='+ $LINENO: ' 显示行号
  • 临时注释代码块使用:<<'COMMENT' ... COMMENT
  • 检查隐藏字符:cat -A script.sh
  • 测试条件判断:[[ ]]替换[ ]获得更好调试信息

示例调试流程:

#!/bin/bash -ex
# 严格模式运行trap 'echo "Error at line $LINENO"' ERRfor file in *.txt
doecho "Processing: $file"wc -l "$file"
done

Q16shell脚本如何比较字符串?

在 Shell 脚本中,比较字符串主要使用 test 命令(即 [ ... ])或 [[ ... ]],以下是常用的字符串比较方法:

1. 使用 [ ... ] 进行字符串比较

[ ... ] 是基本的测试命令,适用于 POSIX 标准的 Shell(如 sh)。

  • 相等=
    if [ "$str1" = "$str2" ]; thenecho "字符串相等"
    fi
    
  • 不相等!=
    if [ "$str1" != "$str2" ]; thenecho "字符串不相等"
    fi
    
  • 空字符串-z
    if [ -z "$str" ]; thenecho "字符串为空"
    fi
    
  • 非空字符串-n
    if [ -n "$str" ]; thenecho "字符串不为空"
    fi
    

注意

  • 始终将变量用双引号 "" 括起来(如 "$str1"),以避免变量未定义或为空时的语法错误。
  • [ ... ] 中必须在 [] 两侧各留一个空格。

2. 使用 [[ ... ]] 进行字符串比较

[[ ... ]] 是 Bash/Ksh/Zsh 的扩展测试命令,功能更强大,推荐在 Bash 脚本中使用。

  • 相等=, ==
    if [[ "$str1" == "$str2" ]]; thenecho "字符串相等"
    fi
    
  • 不相等!=
    if [[ "$str1" != "$str2" ]]; thenecho "字符串不相等"
    fi
    
  • 空字符串-z
    if [[ -z "$str" ]]; thenecho "字符串为空"
    fi
    
  • 非空字符串-n
    if [[ -n "$str" ]]; thenecho "字符串不为空"
    fi
    
  • 模式匹配=~(正则表达式)
    if [[ "$str" =~ ^[0-9]+$ ]]; thenecho "字符串是数字"
    fi
    
  • 字典序比较
    • 小于:<
    • 大于:>
    if [[ "$str1" < "$str2" ]]; thenecho "$str1 小于 $str2(字典序)"
    fi
    

注意

  • [[ ... ]] 不需要像 [ ... ] 那样严格处理变量引用,变量未定义时更安全。
  • 字典序比较(<>)只在 [[ ... ]] 中有效,且基于 ASCII 顺序。

3. 常见问题与注意事项

  • 大小写敏感:默认情况下,字符串比较是大小写敏感的。如果需要忽略大小写,可以在比较前将字符串转换为同一大小写:

    if [[ "${str1,,}" == "${str2,,}" ]]; thenecho "字符串相等(忽略大小写)"
    fi
    

    这里的 ${str,,} 是 Bash 的参数扩展,将字符串转换为小写。

  • 空格敏感:字符串比较会考虑空格,确保比较前处理好字符串(如使用 trim)。

    str1=" hello "
    str2="hello"
    if [[ "${str1// /}" == "${str2// /}" ]]; thenecho "字符串相等(忽略空格)"
    fi
    
  • 性能:对于简单比较,[ ... ][[ ... ]] 性能差异不大,但 [[ ... ]] 更适合复杂场景(如正则匹配)。

4. 示例脚本

以下是一个综合示例,展示字符串比较的几种用法:

#!/bin/bashstr1="hello"
str2="HELLO"# 相等比较
if [[ "$str1" == "$str2" ]]; thenecho "字符串相等"
elseecho "字符串不相等"
fi# 忽略大小写比较
if [[ "${str1,,}" == "${str2,,}" ]]; thenecho "字符串相等(忽略大小写)"
fi# 检查是否为空
if [[ -z "$str1" ]]; thenecho "str1 为空"
elseecho "str1 不为空"
fi# 正则匹配
if [[ "$str1" =~ ^h.*o$ ]]; thenecho "str1 以 h 开头,o 结尾"
fi

5. 总结

  • 简单脚本或 POSIX 兼容性要求高时,使用 [ ... ]
  • 复杂脚本或需要正则、字典序比较时,使用 [[ ... ]]
  • 始终用双引号包裹变量,确保脚本健壮性。
  • 根据需要处理大小写、空格等特殊情况。

相关文章:

面试 Linux 运维相关问题

标题Q1Shell脚本是什么、它是必需的吗? Shell脚本是一种用于自动化执行命令行任务的脚本程序&#xff0c;通常运行在Unix/Linux系统的Shell环境中&#xff08;如Bash&#xff09;。它通过将多个命令、逻辑控制&#xff08;如条件判断、循环&#xff09;和系统功能整合到一个文…...

阿里巴巴 1688 数据接口开发指南:构建自动化商品详情采集系统

在电商行业数据驱动决策的趋势下&#xff0c;高效获取商品详情数据成为企业洞察市场、优化运营的关键。通过阿里巴巴 1688 数据接口构建自动化商品详情采集系统&#xff0c;能够快速、精准地采集海量商品信息。本文将从开发准备、接口分析、代码实现等方面&#xff0c;详细介绍…...

python的宫崎骏动漫电影网站管理系统

目录 技术栈介绍具体实现截图系统设计研究方法&#xff1a;设计步骤设计流程核心代码部分展示研究方法详细视频演示试验方案论文大纲源码获取/详细视频演示 技术栈介绍 Django-SpringBoot-php-Node.js-flask 本课题的研究方法和研究步骤基本合理&#xff0c;难度适中&#xf…...

答题pk小程序道具卡的获取与应用

道具卡是答题PK小程序中必不可少的一项增加趣味性的辅助应用&#xff0c;那么道具卡是如何获取与应用的呢&#xff0c;接下来我们来揭晓答案&#xff1a; 一、道具卡的获取&#xff1a; 签到获取&#xff1a;在每日签到中签到不仅可获得当日的签到奖励积分&#xff0c;同时连…...

从零开始创建一个 Next.js 项目并实现一个 TodoList 示例

Next.js 是一个基于 React 的服务端渲染框架&#xff0c;它提供了很多开箱即用的功能&#xff0c;如自动路由、API 路由、静态生成、增量静态再生等。本文将带你一步步创建一个 Next.js 项目&#xff0c;并实现一个简单的 TodoList 功能。 效果地址 &#x1f9f1; 安装 Next.j…...

全面掌握JSR303校验:从入门到实战

一、JSR303校验简介 JSR303是Java EE 6中的一项规范&#xff0c;全称为"Bean Validation 1.0"&#xff0c;它定义了一套基于注解的JavaBean校验机制。通过简单的注解&#xff0c;我们可以优雅地完成参数校验工作&#xff0c;避免在业务代码中编写大量的校验逻辑。 …...

「Java EE开发指南」如何使用MyEclipse的可视化JSF编辑器设计JSP?(二)

Visual JSF Designer&#xff08;可视化JSF设计器&#xff09;的目标是使创建JSF应用程序的特定于组件工作更容易可视化&#xff0c;在本教程中&#xff0c;您将使用可视化设计器设计JSF登录页面。您将学习如何&#xff1a; 创建一个JSF项目创建一个新的JSF页面设计JSF页面 该…...

Python 翻译词典小程序

一、概述 本工具是基于Python开发的智能翻译系统&#xff0c;采用有道词典进行翻译&#xff0c;并具有本地词典缓存以及单词本功能。 版本号&#xff1a;v1.0 (2025-05-15) 二、核心功能说明 1. 基础翻译功能 即时翻译&#xff1a;输入英文单词自动获取中文释义 词性识别&…...

kafka调优

以下是 Kafka 性能调优的核心策略与参数配置建议&#xff0c;综合生产环境和硬件层面的优化方案&#xff0c;覆盖生产者、消费者、Broker 三个关键组件&#xff1a; 一、生产者调优 批量发送优化 • batch.size&#xff1a;增大批量消息大小&#xff08;默认 16KB&#xff0c;建…...

【hadoop】sqoop案例 hive->mysql

将temperature.log中的气象数据导入到Hive的temperature表中&#xff0c; 根据气象站id分组计算每个气象站30年来的*最高*气温&#xff0c; 然后将统计结果导出到MySQL当中。 思路&#xff1a; 1.在hive中创建表 2.数据导入到表中 3.计算后的结果写入另外的表 4.用sqoop导出…...

Git/GitLab日常使用的命令指南来了!

在 GitLab 中拉取并合并代码的常见流程是通过 Git 命令来完成的。以下是一个标准的 Git 工作流&#xff0c;适用于从远程仓库&#xff08;如 GitLab&#xff09;拉取代码、切换分支、合并更新等操作。 &#x1f310; 一、基础命令&#xff1a;拉取最新代码 # 拉取远程仓库的所…...

遗传算法求解旅行商问题分析

目录 一、问题分析 二、实现步骤 1&#xff09;初始化种群 2&#xff09;计算适应度 3&#xff09;选择操作 4&#xff09;交叉操作 5&#xff09;变异操作 三、求解结果 四、总结 本文通过一个经典的旅行商问题&#xff0c;详细阐述在实际问题中如何运用遗传算法来进…...

【Hadoop】伪分布式安装

【Hadoop】伪分布式安装 什么是 Hadoop 伪分布式安装&#xff1f; Hadoop 伪分布式安装&#xff08;Pseudo-Distributed Mode&#xff09; 是一种在单台机器上模拟分布式集群环境的部署方式。它是介于 本地模式&#xff08;Local Mode&#xff09; 和 完全分布式模式&#xf…...

微服务概述

什么是微服务 微服务是一个架构方案,属于分布式架构的一种。 微服务提倡将模块以独立服务的方式独立管理,整个项目依靠多个小型的服务(单独进程)同时运作来支撑,单个服务只关注自己的业务实现并且有专业的团队进行开发。服务之间使用轻量的协议进行消息传送,并且对于单个…...

【网工】华为配置基础篇①

目录 ■华为设备登录配置 ■VLAN与VLANIF地址配置 ■DHCP配置命令 ■ACL访问控制列表配置 ■NAT地址转换配置 ■华为设备登录配置 <AR> system-view //进入系统模式 [AR]sysname Huawei //设备命名为Huawei [Huawei] telnet server enable //开启设备telnet功…...

React19源码系列之 Diff算法

在之前文章中root.render执行的过程&#xff0c;beginWork函数是渲染过程的核心&#xff0c;其针对不同类型的fiber进行不同的更新处理&#xff0c;在FunctionComponent&#xff08;函数组件&#xff09;中&#xff0c;会针对新旧fiber进行对比处理生成新fiber。因此此次就详细…...

华为2024年报:鸿蒙生态正在取得历史性突破

华为于2025年03月31日发布2024年年度报告。报告显示&#xff0c;华为经营结果符合预期&#xff0c;实现全球销售收入 8,621 亿元人民币&#xff0c;净利润 626 亿元人民币。2024 年研发投入达到 1,797 亿元人民币&#xff0c;约占全年收入的 20.8%&#xff0c;近十年累计投入的…...

如何在Firefox火狐浏览器里-安装梦精灵AI提示词管理工具

第一步&#xff1a;进入《梦精灵跨平台AI提示词管理工具》官网 梦精灵 跨平台AI提示词管理助手 - 官网梦精灵是一款专为AI用户打造的跨平台提示词管理插件&#xff0c;支持一键收藏、快速复制、智能分类等功能&#xff0c;适用于即梦、豆包、Kimi、DeepSeek等多个AI平台&…...

【鸿蒙开发】性能优化

语言层面的优化 使用明确的数据类型&#xff0c;避免使用模糊的数据类型&#xff0c;例如ESObject。 使用AOT模式 AOT就是提前编译&#xff0c;将字节码提前编译成机器码&#xff0c;这样可以充分优化&#xff0c;从而加快执行速度。 未启用AOT时&#xff0c;一边运行一边进…...

Makefile与CMake

一、Makefile 核心内容 1. Makefile 基础结构与工作原理 三要素&#xff1a; 目标&#xff08;Target&#xff09;&#xff1a;要生成的文件或执行的操作&#xff08;如可执行文件、清理操作&#xff09;。依赖&#xff08;Dependency&#xff09;&#xff1a;生成目标所需的…...

P8803 [蓝桥杯 2022 国 B] 费用报销

P8803 [蓝桥杯 2022 国 B] 费用报销 - 洛谷 题目描述 小明在出差结束后返回了公司所在的城市&#xff0c;在填写差旅报销申请时&#xff0c;粗心的小明发现自己弄丢了出差过程中的票据。 为了弥补小明的损失&#xff0c;公司同意小明用别的票据进行报销&#xff0c;但是公司财…...

11 web 自动化之 DDT 数据驱动详解

文章目录 一、DDT 数据驱动介绍二、实战 一、DDT 数据驱动介绍 数据驱动&#xff1a; 现在主流的设计模式之一&#xff08;以数据驱动测试&#xff09; 结合 unittest 框架如何实现数据驱动&#xff1f; ddt 模块实现 数据驱动的意义&#xff1a; 通过不同的数据对同一脚本实现…...

15:00开始面试,15:06就出来了,问的问题有点变态。。。

从小厂出来&#xff0c;没想到在另一家公司又寄了。 到这家公司开始上班&#xff0c;加班是每天必不可少的&#xff0c;看在钱给的比较多的份上&#xff0c;就不太计较了。没想到4月一纸通知&#xff0c;所有人不准加班&#xff0c;加班费不仅没有了&#xff0c;薪资还要降40%…...

深入理解浏览器渲染引擎:底层机制与性能优化实战

现代浏览器背后是一个庞大而复杂的系统工程&#xff0c;渲染引擎作为核心模块之一&#xff0c;承担着从解析 HTML/CSS 到最终绘制页面的关键职责。本文将从底层机制出发&#xff0c;系统梳理渲染引擎&#xff08;如 Blink&#xff09;工作原理、V8 与渲染流程的协作方式&#x…...

【LeetCode 热题 100】56. 合并区间 —— 一文弄懂排序+遍历经典解法(附Python代码)

📌 题目链接 LeetCode 56. 合并区间 📖 一、引言:区间合并,刷题路上的绊脚石? 区间类问题是算法面试中常见的经典题型,尤其是“合并区间”问题,考察你对排序、区间重叠判断及边界处理的理解和编码能力。 很多同学在面对这题时,容易卡在: 什么时候两个区间算重叠?…...

使用Mathematica绘制Clifford奇异吸引子

Clifford Attractors 是一种由微分方程 生成的混沌吸引子&#xff0c;参数a,b,c,d不同会产生不同的分形图案。这类吸引子属于迭代函数系统&#xff0c;通过不断迭代参数方程来生成复杂的图形。其数学基础可能与 Clifford 代数或高维函数理论相关&#xff0c;例如 Clifford 代数…...

各个历史版本mysql/tomcat/Redis/Jdk/Apache下载地址

mysql 各版本下载地址&#xff1a; https://downloads.mysql.com/archives/community/ **************************************************************** tomcat 各版本下载地址&#xff1a; https://archive.apache.org/dist/tomcat/ ********************************…...

全面解析机器学习与深度学习中的模型权重文件格式与应用场景

概述 随着机器学习和人工智能技术的飞速发展&#xff0c;高效且安全地存储、共享和部署训练有素的模型的方法变得越来越重要。模型权重文件格式在这个过程中发挥着关键作用。这些格式不仅保存了模型的学习参数&#xff0c;还能够实现可复现性&#xff0c;并且便于在各种不同环…...

鸿蒙OSUniApp 实现的地图定位与导航功能#三方框架 #Uniapp

UniApp 实现的地图定位与导航功能 随着移动互联网的发展&#xff0c;地图定位与导航功能已成为众多应用的标配。本文将详细介绍如何在 UniApp 框架下实现地图定位与导航功能&#xff0c;并探讨如何适配鸿蒙系统&#xff0c;助力开发者打造更加流畅的地图体验。 前言 最近在做一…...

【HarmonyOS 5】鸿蒙星闪NearLink详解

【HarmonyOS 5】鸿蒙星闪NearLink详解 一、前言 鸿蒙星闪NearLink Kit 是 HarmonyOS 提供的短距离通信服务&#xff0c;支持星闪设备间的连接、数据交互。例如&#xff0c;手机可作为中心设备与外围设备&#xff08;如鼠标、手写笔、智能家电、车钥匙等&#xff09;通过星闪进…...

Java并发编程面试题总结

目录 线程有哪几种状态?状态如何流转? 创建线程的方式? 多线程有什么应用? 线程池的好处? 线程池的七个参数? 为什么不推荐使用jdk的Executors创建线程池? 线程池的执行流程? 任务拒绝策略有哪些&#xff0c;怎么选择? 线程池的核心线程数和最大线程数怎么设定…...

LAMP项目部署实战

一、LAMP部署前期准备 1.1 关闭防火墙 # systemctl stop firewalld # systemctl disable firewalld 1.2 关闭SELinux SELinux(Security-EnhancedLinux)是美国国家安全局&#xff08;NSA&#xff09;对于强制访问控制的实现&#xff0c;是Linux历史上最杰出的新安全子系统。 …...

Dify与n8n全面对比指南:AI应用开发与工作流自动化平台选择【2025最新】

Dify与n8n全面对比指南&#xff1a;AI应用开发与工作流自动化平台选择【2025最新】 随着AI技术与自动化工具的迅速发展&#xff0c;开发者和企业面临着多种平台选择。Dify和n8n作为两个备受关注的自动化平台&#xff0c;分别专注于不同领域&#xff1a;Dify主要面向AI应用开发&…...

VBA_NZ系列工具NZ10:VBA压缩与解压工具

我的教程一共九套及VBA汉英手册一部&#xff0c;分为初级、中级、高级三大部分。是对VBA的系统讲解&#xff0c;从简单的入门&#xff0c;到数据库&#xff0c;到字典&#xff0c;到高级的网抓及类的应用。大家在学习的过程中可能会存在困惑&#xff0c;这么多知识点该如何组织…...

EFT不过整改思路与调试经验

EFT是如何影响EUT的&#xff1a; EFT试验是为了验证电气和电子设备对诸如来自切换瞬态过程(切断感性负载、继电器触点弹跳等)的各种类型瞬变骚扰的抗扰度。EFT干扰是在电路中感性负载断开时产生的&#xff0c;它的特点是干扰信号不是单个脉而是一连串的脉冲群。EFT 干扰可以在…...

2.安卓逆向2-adb指令

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a;图灵Python学院 工具下载&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1bb8NhJc9eTuLzQr39lF55Q?pwdzy89 提取码&#xff1…...

VSCode CMake工作流

Foreword 之前看到CMake有这么多选项&#xff0c;感觉不简单&#xff0c;还是看下别人在这里设计了多少东西 CMake 整体来说CMake遵循这样一套结构 操作-操作预设&#xff08;如果有的话&#xff09;-操作目标&#xff08;如果有的话&#xff09;比如 Configure-Configure…...

【上位机——WPF】App.xml和Application类简介

App.xml和Application类简介 概述App.xamlApp.xaml.cs 入门代码App.xamlMainWindow.xml Application生命周期窗体的声明周期 概述 xaml类型的文件包含两部分&#xff0c;一部分以.xaml扩展名结尾的前端代码&#xff0c;另一部分以.xaml.cs结尾的后端代码&#xff0c;通常我们也…...

MySQL 8.0 OCP 1Z0-908 101-110题

Q101.which two queries are examples of successful SQL injection attacks? A.SELECT id, name FROM backup_before WHERE name‘; DROP TABLE injection; --’; B. SELECT id, name FROM user WHERE id23 oR id32 OR 11; C. SELECT id, name FROM user WHERE user.id (SEL…...

Linux/Centos7离线安装并配置MySQL 5.7

文章目录 前言1、安装包下载2、卸载MariaDB3、创建MySQL用户4、上传安装包5、创建数据目录和配置文件6、安装MySQL7、启动MySQL8、初始化MySQL9、退出验证新密码10、创建普通用户和库11、测试普通用户和库总结 前言 博主参考了一些大佬的文章&#xff0c;部分收费的就看不了了&…...

在Angular中使用Leaflet构建地图应用

Leaflet是一个用于创建地图的JavaScript库&#xff0c;它包含许多功能&#xff0c;并且非常适用于移动设备。 准备 nodejs: v20.15.0 npm: 10.7.0 angular: 19.2.10 创建一个地图应用工程 npx angular/cli new my-leaflet-app --stylecss --routingfalse --skip-tests提示 …...

GPU与NPU异构计算任务划分算法研究:基于强化学习的Transformer负载均衡实践

点击 “AladdinEdu&#xff0c;同学们用得起的【H卡】算力平台”&#xff0c;H卡级别算力&#xff0c;按量计费&#xff0c;灵活弹性&#xff0c;顶级配置&#xff0c;学生专属优惠。 引言 在边缘计算与AI推理场景中&#xff0c;GPU-NPU异构计算架构已成为突破算力瓶颈的关键技…...

iOS 抓包实战:从 Charles 到Sniffmaster 的日常工具对比与使用经验

iOS 抓包实战&#xff1a;从 Charles 到抓包大师 Sniffmaster 的日常工具对比与使用经验 抓包这件事&#xff0c;不是高级黑客才要做的。作为一名移动端开发&#xff0c;我几乎每天都要和网络请求打交道&#xff0c;尤其是 HTTPS 请求——加密、重定向、校验证书&#xff0c;各…...

【微服务】SpringBoot + Docker 实现微服务容器多节点负载均衡详解

目录 一、前言 二、前置准备 2.1 基本环境 2.2 准备一个springboot工程 2.2.1 准备几个测试接口 2.3 准备Dockerfile文件 2.4 打包上传到服务器 三、制作微服务镜像与运行服务镜像 3.1 拷贝Dockerfile文件到服务器 3.2 制作服务镜像 3.3 启动镜像服务 3.4 访问一下服…...

【Linux系统】从 C 语言文件操作到系统调用的核心原理

文章目录 前言lesson 15_基础IO一、共识原理二、回顾C语言接口2.1 文件的打开操作2.2 文件的读取与写入操作2.3 三个标准输入输出流 三、过渡到系统&#xff0c;认识文件系统调用3.1 open 系统调用1. 比特位标志位示例 3.2 write 系统调用1. 模拟实现 w 选项2. 模拟实现 a 选项…...

俄罗斯方块算法

俄罗斯方块是一款风靡全球 38 年的经典益智游戏&#xff0c;凭借其简单易学但难于精通的特点&#xff0c;成为游戏史上的不朽之作。 游戏界面与规则 游戏界面为 20 行10 列的可视区域。横向 X 轴区间为 [0&#xff0c;9]&#xff0c;共 10 列&#xff1b;纵向 Y 轴区间为 [0&a…...

Node.js 循环依赖问题详解:原理、案例与解决方案

文章目录 一、什么是循环依赖&#xff1f;二、循环依赖的典型表现三、解决方案四、如何检测循环依赖五、循环依赖的隐藏危害 一、什么是循环依赖&#xff1f; 当两个或者多个模块互相直接或者间接引用时&#xff0c;就会形成循环依赖。例如&#xff1a; A.js → 依赖 → B.js…...

Linux系统编程——vfork函数的使用方法以及与fork函数的区别

vfork() 是 Linux 系统编程中与 fork() 类似的系统调用&#xff0c;用于创建一个新的子进程。它们都能创建子进程&#xff0c;但在实现机制和使用场景上有明显区别。 以下是对 vfork() 的详细介绍&#xff0c;包括&#xff1a; 使用方法 注意事项 与 fork() 的联系与区别 使…...

.NET 无侵入自动化探针原理与主流实现详解

目录 引言 一、.NET 无侵入自动化探针的原理 1.1 CLR Profiling API 核心机制 示例代码 1.2 CLR Instrumentation 核心机制 示例代码 1.3 反射和动态代理 核心机制 示例代码 1.4 DiagnosticSource 核心机制 示例代码 二、主流实现与工具 2.1 AppDynamics 实现原…...

大数据:新能源汽车宇宙的未来曲率引擎

** 发布日期&#xff1a;2025-05-14** 关键词&#xff1a;大数据、新能源、机器学习、碳中和、CSDN爆款 1. 大数据科普&#xff1a;定义、特征与技术核心 1.1 什么是大数据&#xff1f; 大数据&#xff08;Big Data&#xff09;指规模巨大、类型多样、生成速度快且价值密度低…...