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

linux下脚本文件如何写

在 Linux 中创建脚本文件,首行添加 #!/bin/bash(或其他解释器路径),编写命令后保存为 .sh 文件,通过 chmod +x 赋予

以下是关于 Linux脚本文件编写 的完整指南,涵盖从基础到进阶的全流程操作、语法规范及实用技巧:


脚本文件的本质与准备工作

什么是 Linux 脚本?

Linux 脚本本质是由一系列命令构成的文本文件,通过指定的解释器(如 /bin/bash)逐行执行,其核心优势在于自动化任务、批量操作和可复用性。

特性 说明
跨平台性 依赖 Unix/Linux 环境,可在多数类 Unix 系统运行
灵活性 支持条件判断、循环、函数等结构化编程
轻量化 无需编译,直接通过解释器执行
集成能力 可调用系统命令、管道符 、重定向 >/< 实现复杂功能

创建脚本文件的基础步骤

# 示例:创建名为 myscript.sh 的脚本
touch myscript.sh          # 创建空文件
nano myscript.sh           # 编辑内容(推荐新手使用 nano)
chmod +x myscript.sh       # 添加可执行权限
./myscript.sh             # 执行脚本

关键注意点

  • 文件扩展名无强制要求(.sh 是约定俗成),但需通过 明确指定解释器。
  • 若未添加执行权限(chmod +x),需用 bash myscript.sh 显式调用解释器。

脚本头部规范:Shebang 的必要性

所有正规脚本的第一行必须是 Shebang(),用于声明解释器路径,常见形式如下:

linux下脚本文件如何写  第1张

目标解释器 Shebang 写法 适用场景
Bash #!/bin/bash 默认 shell,兼容性最好
Dash (POSIX) #!/bin/sh 最小化依赖,适配旧系统
Zsh #!/bin/zsh 仅当用户默认 shell 为 zsh
Python #!/usr/bin/python3 混合编程时需精确路径

错误示范:省略 Shebang 会导致脚本以不确定的默认 shell 执行,可能引发兼容性问题。


核心语法详解

变量操作

操作类型 语法示例 说明
定义变量 name="value" 双引号内可包含空格和特殊字符
读取输入 read var_name 等待用户输入并存入变量
数组定义 arr=("item1" "item2") 支持索引访问:${arr[0]}
字符串拼接 echo "Hello ${USER}!" 花括号 用于变量替换
删除变量 unset var_name 彻底移除变量定义

最佳实践:变量名全大写(如 MAX_COUNT=10)用于区分环境变量,避免与命令冲突。

条件判断

# 单条件判断
if [ $AGE -gt 18 ]; then
    echo "Adult"
elif [ $AGE -eq 18 ]; then
    echo "Teenager"
else
    echo "Minor"
fi
# 多条件组合(逻辑与/或)
if [[ ( "$OS" == "Ubuntu" ) && ( "$VERSION" > "20.04" ) ]]; then
    echo "Supported OS"
fi

关键点

  • [ ] 等同于 test 命令,[[ ]] 是增强版,支持正则表达式。
  • 数值比较运算符:-eq(等于)、-ne(不等于)、-gt(大于)。
  • 字符串比较:(完全匹配)、(不等)、</>(字典序)。

循环结构

循环类型 语法模板 典型场景
For 循环 for i in {1..5}; do echo $i; done 固定次数迭代
While 循环 count=0; while [ $count -lt 5 ]; do echo $count; count=$((count+1)); done 条件控制循环
Until 循环 until false; do sleep 1; done 无限循环(需手动终止)
遍历文件 for file in .txt; do cat "$file"; done 批量处理同类文件

嵌套循环示例:打印九九乘法表

for i in {1..9}; do
    for j in {1..$i}; do
        printf "%d x %d = %dt" $j $i $(($j  $i))
    done
    echo # 换行
done

参数处理

脚本可通过 $n 获取命令行参数($0 是脚本名,$1~$9 是前九个参数):

#!/bin/bash
echo "Total arguments: $#"      # 参数总数
echo "All arguments: $@"        # 所有参数(带引号)
echo "First argument: $1"       # 第一个参数
# 移位处理(依次消耗参数)
while [ $# -gt 0 ]; do
    echo "Processing: $1"
    shift # 左移一位,丢弃第一个参数
done

高级用法:使用 getopts 解析短选项:

while getopts ":ahv" opt; do
    case $opt in
        a) ALGO=fast;;
        h) HELP=true;;
        v) VERBOSE=true;;
        ?) echo "Invalid option: -$OPTARG" >&2; exit 1;;
    esac
done

调试与错误处理

启用调试模式

#!/bin/bash
set -euxo pipefail # 推荐组合:显示命令+出错退出+未定义变量报错+管道失败即退出
  • set -e:任一命令失败则退出脚本。
  • set -u:使用未定义变量时报错。
  • set -x:打印每条执行的命令(调试利器)。
  • pipefail:管道中任意环节失败则整个管道失败。

自定义错误处理

trap 'echo "Error occurred at line $LINENO"; exit 1' ERR
# 当发生错误时触发陷阱,打印行号并退出

实战案例:日志分析脚本

#!/bin/bash
# log_analyzer.sh 统计指定日志文件中的错误次数
LOGFILE=${1:-"/var/log/syslog"} # 默认日志路径
ERROR_PATTERN="error|fail|exception" # 正则匹配模式
if [ ! -f "$LOGFILE" ]; then
    echo "Error: Log file not found!" >&2
    exit 1
fi
grep -E "$ERROR_PATTERN" "$LOGFILE" | wc -l > error_count.tmp
total_errors=$(cat error_count.tmp)
rm error_count.tmp
echo "Found $total_errors errors in $LOGFILE"
exit 0 # 成功退出

执行方式./log_analyzer.sh /path/to/custom.log


最佳实践清单

类别 建议做法 原因说明
可移植性 始终使用 #!/bin/bash 而非 #!/bin/sh sh 可能是 Dash,功能受限
安全性 对外部输入进行转义:input=$(echo "$user_input" | base64) 防止命令注入攻击
性能优化 将频繁调用的命令放入函数,减少磁盘 I/O 提升重复执行效率
日志记录 重定向输出到文件:command >> script.log 便于事后排查问题
版本控制 将脚本纳入 Git 管理,标注修改日期 追踪变更历史

相关问答 FAQs

Q1: 为什么我的脚本提示 “Permission denied”?

A: 可能原因及解决方案:

  1. 缺少执行权限 → 执行 chmod +x script.sh
  2. Shebang 路径错误 → 确保 后跟的是系统中存在的解释器路径(可用 which bash 查看)
  3. 文件格式问题 → Windows 下创建的文件可能有 CRLF 换行符,用 dos2unix script.sh 转换。

Q2: 如何在脚本中后台运行长时间任务?

A: 两种常用方法:

  1. & 符号long_task & → 任务在后台运行,立即返回控制权。
  2. nohup + &nohup long_task > output.log & → 即使关闭终端,任务仍继续运行,输出重定向到文件。
    ️ 注意:后台任务的标准输出/错误不会自动显示,建议重
0