Linux 学习笔记 shell 编程 1 bash 脚本

D25 

一:  普通变量和环境变量和特殊变量:

在Linux中,`.`(点号)和`source`是等价的命令,它们都用于在当前Shell会话中执行脚本或加载配置文件,而不是在新的子进程中运行。这样可以让脚本中定义的环境变量、函数等在当前会话中生效。

关于加载`/etc/profile`,这是一个系统级的Shell配置文件,通常用于设置全局环境变量和启动时的Shell行为(比如PATH、umask等)。下面我详细解释一下`.`或`source`加载`/etc/profile`的用法和作用:

### 用法
```bash
. /etc/profile
```
或者
```bash
source /etc/profile
```

### 作用
1. **执行并应用环境变量**:
   `/etc/profile`通常包含全局的环境变量设置,比如`PATH`、`LANG`等。用`.`或`source`加载后,这些变量会立刻在当前Shell会话中生效,而不是只在脚本运行的子进程中临时生效。

2. **更新当前会话**:
   如果你修改了`/etc/profile`(比如添加了新的PATH路径),直接运行`bash /etc/profile`只会影响新开的子Shell,而当前Shell不会受影响。用`.`或`source`则可以让当前会话立即应用这些更改。

### 举个例子
假设`/etc/profile`里有一行:
```bash
export MY_VAR="Hello, Linux!"
```
你在终端输入:
```bash
source /etc/profile
```
然后运行:
```bash
echo $MY_VAR
```
输出会是:
```
Hello, Linux!
```
如果不用`source`而是直接`bash /etc/profile`,`MY_VAR`不会在当前会话中生效。

### 注意事项
1. **权限**:
   普通用户可以加载`/etc/profile`,但如果里面有需要root权限的操作(比如修改系统级的设置),可能不会有预期效果。

2. **适用Shell**:
   `/etc/profile`通常是为Bourne Shell兼容的Shell(如bash、sh)设计的。如果用的是zsh或fish这样的非兼容Shell,可能需要加载对应的配置文件(比如`~/.zshrc`)。

3. **重复加载**:
   多次加载`/etc/profile`一般不会有什么问题,但如果里面有复杂的脚本逻辑(比如追加PATH),可能会导致重复定义,得看具体内容。

### 实际场景
- 你刚改了`/etc/profile`里的`PATH`,想马上用新路径?用`source /etc/profile`。
- 想临时测试`/etc/profile`的设置?直接`.`或`source`就行。

在Linux中,变量是Shell编程和系统配置的核心部分。它们可以用来存储数据、定义环境行为等。以下我将详细讲解Linux中的变量命名规则、分类,以及你提到的环境变量`$LANG`、`$PS1`和`$PATH`。

---

### 一、Linux变量命名规则
1. **合法字符**:
   - 变量名必须以字母(A-Z,a-z)或下划线(_)开头。
   - 后续字符可以是字母、数字(0-9)或下划线。
   - 不允许使用空格、特殊字符(如@、#、$)作为变量名的一部分。

2. **大小写敏感**:
   - `MY_VAR`和`my_var`是两个不同的变量。

3. **命名约定**:
   - 通常用全大写表示环境变量或全局变量(比如`PATH`)。
   - 小写或驼峰式命名(`myVar`)常用于脚本中的局部变量。
   - 避免使用保留关键字(如`if`、`for`)作为变量名。

示例:
```bash
MY_VAR=123    # 合法
_var2="test"  # 合法
2var="no"     # 非法,数字开头
my var="hi"   # 非法,包含空格
```

---

### 二、变量分类
Linux中的变量可以根据作用域和用途分为以下几类:

1. **局部变量**:
   - 只在当前Shell脚本或函数中有效。
   - 定义方式:直接赋值。
   - 示例:
     ```bash
     my_var="hello"
     echo $my_var
     ```
   - 在脚本结束后,`my_var`不会影响父Shell。

2. **环境变量**:
   - 通过`export`命令导出的变量,可被子进程继承。
   - 常用于配置系统或程序的行为。
   - 示例:
     ```bash
     export MY_ENV="world"
     bash  # 进入子Shell
     echo $MY_ENV  # 输出 "world"
     ```

3. **Shell内置变量**:
   - Shell预定义的变量,用于特定用途,比如`$HOME`、`$PWD`。
   - 示例:
     ```bash
     echo $HOME  # 输出用户主目录,如 "/home/user"
     ```

4. **只读变量**:
   - 用`readonly`或`declare -r`定义,不能修改。
   - 示例:
     ```bash
     readonly CONST="fixed"
     CONST="new"  # 会报错
     ```

5. **位置参数变量**:
   - 用于脚本参数,如`$1`、`$2`表示脚本的第一个、第二个参数。
   - 示例:
     ```bash
     # 脚本 test.sh
     echo "First arg: $1"
     # 调用:bash test.sh hello
     # 输出:First arg: hello
     ```

6. **特殊变量**:
   - 如`$?`(上个命令退出状态)、`$$`(当前进程ID)。
   - 示例:
     ```bash
     ls /not_exist
     echo $?  # 输出非0值,表示失败
     ```

---

### 三、常见环境变量解析
你提到的`$LANG`、`$PS1`和`$PATH`是Linux中非常重要的环境变量,以下是它们的详细说明:

#### 1. `$LANG`
- **作用**:定义系统的语言和区域设置(locale),影响字符编码、时间格式等。
- **常见值**:
  - `en_US.UTF-8`:美国英语,UTF-8编码。
  - `zh_CN.UTF-8`:简体中文,UTF-8编码。
- **用法**:
  ```bash
  echo $LANG  # 查看当前语言
  export LANG="zh_CN.UTF-8"  # 设置为中文
  ```
- **影响**:比如`ls`命令的输出语言、错误信息的语言。

#### 2. `$PS1`
- **作用**:定义Shell提示符的外观(Prompt String 1)。
- **常见值**:
  - 默认可能是`\u@\h:\w\$`,表示“用户名@主机名:当前目录$”。
  - 示例:`user@linux:/home$`
- **自定义**:
  ```bash
  PS1='\[\e[32m\]\u@\h:\w\$\[\e[0m\] '  # 绿色提示符
  ```
  - `\u`:用户名
  - `\h`:主机名
  - `\w`:当前工作目录
  - `\$`:普通用户显示`$`,root显示`#`
- **查看**:
  ```bash
  echo "$PS1"
  ```

#### 3. `$PATH`
- **作用**:定义可执行文件的搜索路径,Shell会按顺序在这些目录中查找命令。
- **默认值**(示例):
  - `/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin`
- **用法**:
  - 查看:
    ```bash
    echo $PATH
    ```
  - 添加路径:
    ```bash
    export PATH=$PATH:/my/new/path
    ```
- **影响**:如果某个命令不在`$PATH`中,运行时会报“command not found”。

---

### 四、实战示例
假设你想设置一个中文环境并自定义提示符:
```bash
export LANG="zh_CN.UTF-8"
export PS1="[\u@\h \w]\$ "
export PATH="$PATH:/usr/local/mybin"
```
运行后:
- 提示符变成 `[user@host /home/user]$`
- 系统语言变为中文
- 命令搜索路径多了`/usr/local/mybin`

---

其他:   echo ${week}_day

在Linux中,UID(User ID)是一个环境变量,表示当前用户的ID。root用户的UID始终是0。我们可以用Shell脚本通过检查$UID来判断当前用户是否为root。下面我给你几个实现方法,从简单到复杂,方便你选择使用。


方法一:简单判断

bash

WrapCopy

#!/bin/bash if [ "$UID" -eq 0 ]; then echo "你是root用户!" else echo "你不是root用户,UID是:$UID" fi

  • 解释
    • $UID:当前用户的ID。

    • -eq:等于(用于整数比较)。

    • 如果$UID等于0,说明是root。


    •  


  •  

方法二:更健壮的写法

考虑到某些环境可能未正确设置$UID,可以用id -u命令(返回当前用户的UID)作为备用:

bash

WrapCopy

#!/bin/bash uid=$(id -u) if [ "$uid" -eq 0 ]; then echo "你是root用户!" else echo "你不是root用户,UID是:$uid" fi

  • 解释
    • id -u:直接获取当前用户的UID,比依赖$UID更可靠。

    • 把结果存到变量uid中再判断。

 二: Linux Bash 脚本,可以显示主机名、IP 地址、总计内存、可用内存和系统负载,并按照你指定的格式输出:

方法2 

下面是一个简单的 Linux Bash 脚本,可以显示主机名、IP 地址、总计内存、可用内存和系统负载,并按照你指定的格式输出:

```bash
#!/bin/bash

# 获取主机名
hostname=$(hostname)

# 获取第一个网络接口的 IP 地址(通常是 eth0 或 enp0s3,排除回环地址)
ip_address=$(ip addr show | grep -oE 'inet [0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' | grep -v '127.0.0.1' | awk '{print $2}' | head -n 1)

# 获取总计内存(以 MB 为单位)
total_memory=$(free -m | awk '/^Mem:/{print $2}')

# 获取可用内存(以 MB 为单位)
available_memory=$(free -m | awk '/^Mem:/{print $7}')

# 获取系统负载(1分钟平均负载)
system_load=$(uptime | awk -F 'load average:' '{print $2}' | cut -d, -f1 | tr -d ' ')

# 输出指定格式的内容
echo "主机名: $hostname"
echo "地址: $ip_address"
echo "总计内存: ${total_memory}MB"
echo "可用内存: ${available_memory}MB"
echo "系统负载: $system_load"
```

### 脚本说明:
1. **主机名**:使用 `hostname` 命令获取。
2. **地址**:通过 `ip addr show` 获取第一个非回环的 IP 地址。
3. **总计内存和可用内存**:使用 `free -m` 命令以 MB 为单位获取内存信息。
4. **系统负载**:从 `uptime` 中提取 1 分钟的平均负载。

### 使用方法:
1. 将上述代码保存到一个文件,例如 `system_info.sh`。
2. 赋予执行权限:
   ```bash
   chmod +x system_info.sh
   ```
3. 运行脚本:
   ```bash
   ./system_info.sh
   ```

### 示例输出:
```
主机名: my-server
地址: 192.168.1.100
总计内存: 8192MB
可用内存: 5432MB
系统负载: 0.25
```

三:  特殊变量 `$n`、`$0`、`$#` 和 `$@ $?

在 Shell 编程中(特别是 Bash),`$n`、`$0`、`$#` 和 `$@` 是常用的特殊变量,用于处理脚本的参数。下面是对它们的详细解析:

---

### 1. `$n`(位置参数)
- **定义**: `$n` 表示传递给脚本或函数的第 `n` 个参数,其中 `n` 是一个数字。
  - `$1` 是第一个参数。
  - `$2` 是第二个参数。
  - 以此类推,`$3`、`$4` 等依次表示后续参数。
- **用法**: 当脚本接收命令行参数时,可以通过 `$n` 访问这些参数。
- **示例**:
  ```bash
  #!/bin/bash
  echo "第一个参数: $1"
  echo "第二个参数: $2"
  ```
  运行 `./script.sh hello world`,输出:
  ```
  第一个参数: hello
  第二个参数: world
  ```
- **注意**: 如果 `n` 超过实际参数数量,结果为空。

---

### 2. `$0`(脚本名称)
- **定义**: `$0` 表示脚本本身的名称(包括路径,取决于调用方式)。
- **用法**: 常用于提示用户脚本名称或在脚本中自我引用。
- **示例**:
  ```bash
  #!/bin/bash
  echo "脚本名称: $0"
  ```
  如果脚本名为 `test.sh`,运行 `./test.sh`,输出:
  ```
  脚本名称: ./test.sh
  ```
- **注意**: `$0` 的值取决于调用脚本的方式:
  - `./test.sh` 输出 `./test.sh`。
  - `/full/path/test.sh` 输出完整路径。
  - `bash test.sh` 输出 `test.sh`。

---

### 3. `$#`(参数个数)
- **定义**: `$#` 表示传递给脚本或函数的参数总数(不包括 `$0`)。
- **用法**: 用于检查脚本是否接收到预期数量的参数。
- **示例**:
  ```bash
  #!/bin/bash
  echo "参数总数: $#"
  ```
  运行 `./script.sh a b c`,输出:
  ```
  参数总数: 3
  ```
- **注意**: 如果没有传递参数,`$#` 为 `0`。

---

### 4. `$@`(所有参数的列表)
- **定义**: `$@` 表示所有传递给脚本或函数的参数,以单独的字符串形式保存。
- **用法**: 通常用于遍历所有参数,或者将参数传递给其他命令。
- **特点**: 
  - 与 `$*` 类似,但区别在于 `$@` 在被双引号 `"$@"` 包裹时,会保留每个参数的独立性(即空格分隔的完整参数)。
- **示例**:
  ```bash
  #!/bin/bash
  echo "所有参数: $@"
  for arg in "$@"; do
      echo "参数: $arg"
  done
  ```
  运行 `./script.sh "hello world" foo bar`,输出:
  ```
  所有参数: hello world foo bar
  参数: hello world
  参数: foo
  参数: bar
  ```
- **注意**: 
  - 如果不加双引号(即直接用 `$@`),效果类似于 `$*`,可能会丢失参数的边界。
  - 双引号 `"$@"` 是推荐用法,尤其是处理带空格的参数时。

---

### `$@` vs `$*`(补充说明)
- `$*`: 将所有参数视为一个整体字符串,用 `$IFS`(默认是空格)连接。
- `$@`: 将所有参数视为独立的字符串数组。
- **示例对比**:
  ```bash
  #!/bin/bash
  echo "用 \$*: $*"
  echo "用 \$@: $@"
  ```
  运行 `./script.sh "hello world" foo`,输出:
  ```
  用 $*: hello world foo
  用 $@: hello world foo
  ```
  但用循环时:
  ```bash
  for i in "$*"; do echo $i; done
  for i in "$@"; do echo $i; done
  ```
  输出:
  ```
  hello world foo  # $*: 一个整体
  hello world      # $@: 分别处理
  foo
  ```

---

### 综合示例
以下是一个综合使用这些变量的脚本:
```bash
#!/bin/bash
echo "脚本名称: $0"
echo "参数总数: $#"
echo "第一个参数: $1"
echo "第二个参数: $2"
echo "所有参数: $@"

if [ $# -eq 0 ]; then
    echo "错误:请提供至少一个参数!"
    exit 1
fi

for param in "$@"; do
    echo "处理参数: $param"
done
```

运行 `./script.sh one "two three" four`,输出:
```
脚本名称: ./script.sh
参数总数: 3
第一个参数: one
第二个参数: two three
所有参数: one two three four
处理参数: one
处理参数: two three
处理参数: four
```

---

### 总结
- `$n`: 第 `n` 个参数(`$1`, `$2`, ...)。
- `$0`: 脚本名称。
- `$#`: 参数数量。
- `$@`: 所有参数的列表(推荐用 `"$@"` 保留参数完整性)。

在 Linux/Unix 的 shell 脚本中,$? 是一个特殊的变量,它用于获取上一个执行命令的退出状态码(exit status)。理解 $? 的用法对于编写健壮的 shell 脚本至关重要。

基本概念:

  • 退出状态码:
    • 每个在 Linux 中执行的命令都会返回一个退出状态码,用来表明命令执行的结果。
    • 按照惯例,退出状态码为 0 表示命令成功执行。
    • 任何非零的退出状态码都表示命令执行过程中出现了错误。
    • 不同的非零值可能代表不同类型的错误。
  • $? 变量:
    • $? 变量会保存上一个执行命令的退出状态码。
    • 你可以通过访问 $? 变量的值来判断上一个命令是否成功执行。

常见用法:

  1. 检查命令是否成功:

Bash

command  # 执行某个命令
if [ $? -eq 0 ]; then
  echo "命令成功执行"
else
  echo "命令执行失败,退出状态码为:$?"
fi
  • 在这个例子中,$? 被用来检查 command 是否成功执行。
  • [ $? -eq 0 ],代表判断变量“$?”的值是否等于0,等于0则代表上一条命令执行成功。
  1. 在脚本中处理错误:

Bash

if grep "pattern" file.txt; then
  echo "找到了匹配的行"
else
  echo "没有找到匹配的行"
fi
  • grep 命令在找到匹配的行时返回 0,否则返回非零值。
  • 通过 if 语句,可以根据 grep 的返回值来执行不同的操作。
  1. 链式命令执行:

Bash

command1 && command2
  • && 运算符表示只有 command1 成功执行(返回 0)时,才会执行 command2
  • 这是一种简洁的写法,用于确保只有在前一个命令成功时才执行下一个命令。

重要注意事项:

  • $? 的值会在每次执行新命令后立即更新。
  • 因此,如果你想保存某个命令的退出状态码,需要立即将其赋值给另一个变量。

总结:

$? 变量是 shell 脚本中一个非常有用的工具,它允许你根据命令的执行结果来控制脚本的流程,并处理可能出现的错误。通过合理地使用 $?,你可以编写出更加健壮和可靠的 shell 脚本。

判断指定用户是否存在。

id $user >/dev/null 2>&1 是一个常用的 Linux shell 命令,让我们逐步解析它的含义:

1. id $user:

  • id 是一个 Linux 命令,用于显示用户的身份信息,包括用户 ID (UID)、用户组 ID (GID) 等。
  • $user 是一个变量,代表要检查的用户名。例如,如果 $user 的值为 "john",那么命令就会变成 id john
  • 如果用户存在,id 命令会输出该用户的身份信息。
  • 如果用户不存在,id 命令会输出错误信息。

2. >/dev/null:

  • > 是输出重定向符号,用于将命令的输出重定向到指定的文件或设备。
  • /dev/null 是一个特殊的设备文件,它会丢弃所有写入其中的数据。
  • 因此,>/dev/null 的作用是将 id 命令的标准输出(即用户的身份信息)丢弃,不显示在终端上。

3. 2>&1:

  • 2 是标准错误文件描述符,代表错误输出。
  • 1 是标准输出文件描述符,代表正常输出。
  • >&1 的作用是将标准错误重定向到标准输出。
  • 结合前面的 >/dev/null2>&1 的作用就是将 id 命令的错误输出(即用户不存在时的错误信息)也丢弃,不显示在终端上。

综合解释:

  • 整个命令 id $user >/dev/null 2>&1 的作用是:执行 id 命令检查用户是否存在,并将所有输出(包括正常输出和错误输出)都丢弃。
  • 这样做的目的是为了在脚本中静默地判断用户是否存在,而不产生任何输出。
  • 判断用户是否存在通常会配合判断上一条命令是否执行成功,也就是判断返回代码是否为0,如果为0则代表命令执行成功,也就是用户存在,反之用户则不存在。
  • 通常会配合“$?”来判断上一条命令是否执行成功。

实际应用:

  • 在 shell 脚本中,可以使用这个命令来判断用户是否存在,然后根据判断结果执行不同的操作。
  • 例如,可以这样写一个简单的脚本:

Bash

#!/bin/bash

user="testuser"

id $user >/dev/null 2>&1

if [ $? -eq 0 ]; then
  echo "用户 $user 存在"
else
  echo "用户 $user 不存在"
fi
  • 这个脚本会检查用户 "testuser" 是否存在,并输出相应的提示信息。

#-ne 不等于

#-eq 等于

下面是一个 Bash 脚本示例,通过输入用户名并判断该用户在系统中是否存在。脚本会使用 `id` 命令或检查 `/etc/passwd` 文件来验证用户是否存在。

```bash
#!/bin/bash
##########################################
####################
# File Name: check_user.sh
# Version: V1.0
# Author: oldboy lidao996
# Organization: www.oldboyedu.com
# Desc: 判断输入的用户名是否存在于系统中
##########################################

# 提示用户输入用户名
echo -n "请输入用户名: "
read username

# 判断输入是否为空
if [ -z "$username" ]; then
    echo "错误:用户名不能为空!"
    exit 1
fi

# 方法1:使用 id 命令检查用户是否存在
if id "$username" >/dev/null 2>&1; then
    echo "用户 $username 存在于系统中。"
else
    echo "用户 $username 不存在于系统中。"
fi

# 方法2(备用):检查 /etc/passwd 文件
# if grep -q "^$username:" /etc/passwd; then
#     echo "用户 $username 存在于系统中。"
# else
#     echo "用户 $username 不存在于系统中。"
# fi
```

---

### 脚本说明
1. **`read` 命令**:
   - `read username` 用于接收用户输入的用户名。
   - `echo -n` 使提示信息不换行,输入更友好。

2. **输入校验**:
   - 使用 `[ -z "$username" ]` 检查输入是否为空,若为空则退出脚本。

3. **用户存在性判断**:
   - **方法1**: 使用 `id "$username"` 检查用户是否存在。
     - `>/dev/null 2>&1` 将输出和错误信息重定向到空设备,避免显示无关信息。
     - 如果 `id` 返回成功(即用户存在),条件为真。
   - **方法2** (注释掉的备用方法): 使用 `grep` 检查 `/etc/passwd` 文件中是否有该用户名。
     - `^$username:` 确保匹配用户名的开头,`-q` 表示安静模式(不输出结果)。

4. **输出结果**:
   - 根据判断结果,输出用户是否存在。

---

### 使用方法
1. 保存脚本为 `check_user.sh`。
2. 赋予执行权限:
   ```bash
   chmod +x check_user.sh
   ```
3. 运行脚本:
   ```bash
   ./check_user.sh
   ```

### 示例输出
- 检查存在的用户(如 `root`):
  ```
  请输入用户名: root
  用户 root 存在于系统中。
  ```
- 检查不存在的用户:
  ```
  请输入用户名: fakeuser
  用户 fakeuser 不存在于系统中。
  ```
- 输入为空:
  ```
  请输入用户名: 
  错误:用户名不能为空!
  ```

---

### 扩展功能(可选)
如果你需要更复杂的功能,可以告诉我,比如:
- 循环输入直到用户退出。
- 检查用户是否属于某个特定组。
- 显示用户的详细信息(如 UID、GID 等)。

四: 几个基础脚本分析

检查ip或域名是否可以访问脚本

下面是一个 Bash 脚本,用于检查指定的 IP 地址或域名是否可以访问。脚本将使用 `ping` 命令测试网络连通性,并提供简单的判断结果。

```bash
#!/bin/bash
##########################################
####################
# File Name: check_connectivity.sh
# Version: V1.0
# Desc: 检查指定的 IP 地址或域名是否可以访问
##########################################

# 提示用户输入 IP 或域名
echo -n "请输入 IP 地址或域名: "
read target

# 判断输入是否为空
if [ -z "$target" ]; then
    echo "错误:输入不能为空!"
    exit 1
fi

# 使用 ping 命令测试连通性(发送 4 个数据包)
echo "正在测试 $target 的连通性..."
if ping -c 4 "$target" >/dev/null 2>&1; then
    echo "$target 可以访问。"
else
    echo "$target 无法访问。"
fi
```

---

### 脚本说明
1. **`read` 命令**:
   - 用于接收用户输入的 IP 地址或域名,存储在 `target` 变量中。

2. **输入校验**:
   - 使用 `[ -z "$target" ]` 检查输入是否为空,若为空则退出脚本。

3. **`ping` 命令**:
   - `-c 4`: 指定发送 4 个数据包。
   - `>/dev/null 2>&1`: 将标准输出和错误输出重定向到空设备,避免显示详细的 ping 信息。
   - 如果 `ping` 返回成功(即目标可达),条件为真。

4. **输出结果**:
   - 根据 `ping` 的返回值,判断目标是否可访问。

---

### 使用方法
1. 保存脚本为 `check_connectivity.sh`。
2. 赋予执行权限:
   ```bash
   chmod +x check_connectivity.sh
   ```
3. 运行脚本:
   ```bash
   ./check_connectivity.sh
   ```

### 示例输出
- 检查可访问的目标(如 `google.com`):
  ```
  请输入 IP 地址或域名: google.com
  正在测试 google.com 的连通性...
  google.com 可以访问。
  ```
- 检查不可访问的目标(如无效域名):
  ```
  请输入 IP 地址或域名: invalid.domain
  正在测试 invalid.domain 的连通性...
  invalid.domain 无法访问。
  ```
- 输入为空:
  ```
  请输入 IP 地址或域名: 
  错误:输入不能为空!
  ```

---

### 扩展功能
如果需要更强大的功能,可以考虑以下改进:

1. **使用 `nc` 检查特定端口**:
   如果想测试某个端口是否开放,可以用 `nc`(netcat)替代 `ping`:
   ```bash
   echo -n "请输入 IP 地址或域名: "
   read target
   echo -n "请输入端口号: "
   read port

   if [ -z "$target" ] || [ -z "$port" ]; then
       echo "错误:输入不能为空!"
       exit 1
   fi

   if nc -z -w 5 "$target" "$port" >/dev/null 2>&1; then
       echo "$target:$port 可以访问。"
   else
       echo "$target:$port 无法访问。"
   fi
   ```
   - `-z`: 扫描模式,不发送数据。
   - `-w 5`: 设置超时为 5 秒。

2. **支持批量检查**:
   可以从文件读取多个 IP/域名进行测试。

3. **更详细的输出**:
   显示延迟时间、丢包率等(需要保留 `ping` 的输出并解析)。

---

### 注意事项
- **权限**: 普通用户可以运行 `ping`,但某些网络环境下可能被防火墙拦截。
- **依赖**: 脚本依赖 `ping` 命令,确保系统中已安装(通常默认存在)。
- **超时**: `ping -c 4` 默认等待时间较短,若网络较慢,可增加 `-c` 值或添加超时选项(如 `-W 5`)。

#大于9后,会表示为$1 + 0 第1个参数+0使用 ${}

下面是一个 Bash 脚本,用于创建一个简单的回收站功能,替代 `rm` 命令。被“删除”的文件不会直接被移除,而是移动到一个指定的回收站目录中,类似于操作系统的回收站机制。

```bash
#!/bin/bash
##########################################
####################
# File Name: safe_rm.sh
# Version: V1.0
# Author: oldboy lidao996
# Organization: www.oldboyedu.com
# Desc: 替代 rm 命令,将文件移动到回收站而不是直接删除
##########################################

# 定义回收站目录
TRASH_DIR="$HOME/.trash"
# 创建回收站目录(如果不存在)
[ ! -d "$TRASH_DIR" ] && mkdir -p "$TRASH_DIR"

# 检查是否提供了参数
if [ $# -eq 0 ]; then
    echo "用法: $0 文件1 [文件2 ...]"
    echo "将文件移动到回收站: $TRASH_DIR"
    exit 1
fi

# 遍历所有输入的参数(文件或目录)
for file in "$@"; do
    # 检查文件是否存在
    if [ ! -e "$file" ]; then
        echo "错误: '$file' 不存在!"
        continue
    fi

    # 获取文件名和绝对路径
    file_name=$(basename "$file")
    file_path=$(realpath "$file")

    # 为避免同名文件覆盖,添加时间戳
    timestamp=$(date +%Y%m%d_%H%M%S)
    trash_file="$TRASH_DIR/${file_name}_$timestamp"

    # 移动文件到回收站
    if mv "$file_path" "$trash_file"; then
        echo "已移动 '$file' 到回收站: $trash_file"
    else
        echo "错误: 无法移动 '$file' 到回收站!"
    fi
done
```

---

### 脚本说明
1. **回收站目录**:
   - 定义在用户家目录下的 `.trash` 文件夹(`$HOME/.trash`)。
   - 使用 `[ ! -d "$TRASH_DIR" ] && mkdir -p "$TRASH_DIR"` 确保目录存在。

2. **参数检查**:
   - 使用 `$#` 检查是否提供了文件参数,若无参数则显示用法并退出。

3. **文件处理**:
   - 通过 `for` 循环遍历所有输入的文件(`$@`)。
   - 使用 `[ ! -e "$file" ]` 检查文件是否存在。
   - `basename` 获取文件名,`realpath` 获取文件绝对路径。
   - 添加时间戳(如 `20250225_143022`)避免同名文件覆盖。

4. **`mv` 命令**:
   - 将文件移动到回收站目录,而不是删除。
   - 提供成功或失败的反馈。

---

### 使用方法
1. 保存脚本为 `safe_rm.sh`。
2. 赋予执行权限:
   ```bash
   chmod +x safe_rm.sh
   ```
3. 运行脚本(测试删除文件):
   ```bash
   ./safe_rm.sh file1.txt file2.txt
   ```

### 示例输出
```
$ ./safe_rm.sh test.txt
已移动 'test.txt' 到回收站: /home/user/.trash/test.txt_20250225_143022

$ ./safe_rm.sh nonexistent.txt
错误: 'nonexistent.txt' 不存在!
```

---

### 如何替代 `rm` 命令
要让 `safe_rm.sh` 替代系统默认的 `rm` 命令,可以通过以下方式设置别名:

1. 编辑 `~/.bashrc` 或 `~/.bash_profile`:
   ```bash
   nano ~/.bashrc
   ```
2. 添加别名:
   ```bash
   alias rm='/path/to/safe_rm.sh'
   ```
3. 保存并刷新配置:
   ```bash
   source ~/.bashrc
   ```
4. 之后,输入 `rm file` 将调用 `safe_rm.sh`,而非直接删除文件。

**注意**:如果需要使用原生的 `rm` 命令,可以用完整路径 `/bin/rm` 或加反斜杠 `\rm`。

---

### 扩展功能(可选)
1. **恢复文件**:
   添加选项(如 `-r`)从回收站恢复文件:
   ```bash
   if [ "$1" = "-r" ]; then
       shift
       mv "$TRASH_DIR/$1" ./
       echo "已恢复 '$1' 到当前目录。"
       exit 0
   fi
   ```

2. **清空回收站**:
   添加选项(如 `--empty`)清空回收站:
   ```bash
   if [ "$1" = "--empty" ]; then
       rm -rf "$TRASH_DIR"/*
       echo "回收站已清空。"
       exit 0
   fi
   ```

3. **日志记录**:
   记录每次删除的文件和时间到日志文件。

最后

alias rm='sh /server/scripts/devopsshell/06.recyle_rm.sh'


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值