返回

Shell 脚本里遇到的一些坑

开发工具







## 一些常见的 Shell 脚本陷阱

### 1. 使用>或<等进行数字的大小比较

在 Shell 脚本里,使用>或<等进行数字的大小比较时,当数字变为两位数之后结果就会不对。这是因为 Shell 脚本默认将数字作为字符串处理。要进行数字比较,需要使用特殊符号,例如

```shell
#!/bin/bash

if [ $num1 -gt $num2 ]; then
  echo "$num1 is greater than $num2"
else
  echo "$num1 is less than or equal to $num2"
fi

2. 在脚本中使用Shell陷阱

Shell 陷阱是一种特殊机制,允许脚本在收到特定信号时执行指定的动作。例如,可以使用 Shell 陷阱来处理键盘中断 (SIGINT) 或终止信号 (SIGTERM)。在使用 Shell 陷阱时,需要特别注意以下几点:

  • 陷阱函数必须在脚本开头定义。
  • 陷阱函数只能处理一个信号。
  • 陷阱函数不能返回任何值。

例如:

#!/bin/bash

# 定义键盘中断陷阱函数
trap "echo 'Keyboard Interrupt'; exit 1" SIGINT

# 定义终止信号陷阱函数
trap "echo 'Terminated'; exit 1" SIGTERM

# 脚本的主体内容

3. 在脚本中使用特殊变量

Shell 脚本中提供了许多特殊变量,可以存储各种信息,例如脚本的名称、当前工作目录、正在运行的进程列表等。在使用特殊变量时,需要特别注意以下几点:

  • 特殊变量不能被重新赋值。
  • 特殊变量的值可能会在脚本运行过程中发生变化。

例如,可以使用特殊变量 $0 来获取脚本的名称:

#!/bin/bash

echo "This script is named $0"

4. 在脚本中进行字符串比较

在 Shell 脚本中进行字符串比较时,需要特别注意以下几点:

  • 字符串比较是区分大小写的。
  • 字符串比较可以使用 ==!= 操作符。
  • 字符串比较还可以使用 >< 操作符,但需要使用双引号将字符串括起来。

例如:

#!/bin/bash

if [ "$str1" == "$str2" ]; then
  echo "Strings are equal"
else
  echo "Strings are not equal"
fi

if [ "$str1" != "$str2" ]; then
  echo "Strings are not equal"
else
  echo "Strings are equal"
fi

if [ "$str1" > "$str2" ]; then
  echo "String1 is greater than String2"
else
  echo "String1 is less than or equal to String2"
fi

if [ "$str1" < "$str2" ]; then
  echo "String1 is less than String2"
else
  echo "String1 is greater than or equal to String2"
fi

5. 在脚本中进行重定向

在 Shell 脚本中进行重定向时,需要特别注意以下几点:

  • 重定向可以使用 >< 操作符。
  • 重定向可以将标准输出或标准输入重定向到文件或其他设备。
  • 重定向可以将文件或其他设备重定向到标准输出或标准输入。

例如:

#!/bin/bash

# 将标准输出重定向到文件
echo "Hello world" > hello.txt

# 将文件重定向到标准输入
cat hello.txt

# 将标准输入重定向到命令
echo "Hello world" | wc -l

6. 在脚本中使用通用选项

在 Shell 脚本中使用通用选项时,需要特别注意以下几点:

  • 通用选项是脚本运行时可以使用的选项。
  • 通用选项可以用来控制脚本的运行方式或行为。
  • 通用选项可以使用 --- 前缀。

例如:

#!/bin/bash

# 使用-h选项显示帮助信息
if [ "$1" == "-h" ]; then
  echo "Usage: $0 [-h] [-v] filename"
  exit 0
fi

# 使用-v选项启用详细模式
if [ "$1" == "-v" ]; then
  set -x
fi

# 处理脚本的主体内容

7. 在脚本中检查目录

在 Shell 脚本中检查目录时,需要特别注意以下几点:

  • 检查目录是否存在可以使用 -d 操作符。
  • 检查目录是否为空可以使用 -z 操作符。
  • 检查目录是否可读或可写可以使用 -r-w 操作符。

例如:

#!/bin/bash

# 检查目录是否存在
if [ -d "$dir" ]; then
  echo "Directory $dir exists"
else
  echo "Directory $dir does not exist"
fi

# 检查目录是否为空
if [ -z "$dir" ]; then
  echo "Directory $dir is empty"
else
  echo "Directory $dir is not empty"
fi

# 检查目录是否可读
if [ -r "$dir" ]; then
  echo "Directory $dir is readable"
else
  echo "Directory $dir is not readable"
fi

# 检查目录是否可写
if [ -w "$dir" ]; then
  echo "Directory $dir is writable"
else
  echo "Directory $dir is not writable"
fi