[shell 脚本系列-2] 基本语法,基本命令

标准输入,输出,错误(0,1,2)

重定向-基本语法:

./test_case >log.txt // 将标准输出重定向到 log.txt 中
./test_case >log.txt 2>&1 // 将标准输出和错误重定向到 log.txt 中
grep "key_word" < log.txt // 通过输入重定向将文件内容传递给 grep

变量

获取变量信息: $变量名称

a=123
echo $a

单引号内的字符会保持本身字符的意思,而不会被 bash 进行解释

逻辑判断

if 条件;then
    // do sth
else
    // do sth else
fi
  • if:表示开始条件判断。
    条件:这是一个逻辑表达式或命令,其返回状态决定条件是否成立。一般通过命令的返回码进行判断,返回值为 0 表示成功,非 0 表示失败。
  • then:if 之后必须跟 then,表示如果条件为真时将执行接下来的代码块。
  • else:当条件为假时,执行 else 后的代码块(这个部分是可选的)。
  • fi:表示 if 语句的结束

举个例子:

#!/bin/bash

num=10

if [ $num -gt 5 ]; then
    echo "num is greater than 5"
elif [ $num -lt 3 ]
    echo "num is less than 3"
else
	echo "4"
fi
  • [ $num -gt 5 ]:这里 [ ] 是一个用于测试条件的命令,-gt 表示 “大于”。
  • 如果 $num 大于 5,则执行 then 部分,否则执行 else 部分

常见的条件运算符:
数字比较:

  • -eq:等于
  • -ne:不等于
  • -gt:大于
  • -ge:大于等于
  • -lt:小于
  • -le:小于等于

字符串比较:
=:字符串相等
!=:字符串不等
-z:字符串为空
-n:字符串非空
示例:

if [ "$str" = "hello" ]; then echo "字符串相等"; fi

文件判断:
文件判断:

-e:文件存在
-f:是一个普通文件
-d:是一个目录
-r:文件可读
-w:文件可写
-x:文件可执行
示例:

if [ -e "file.txt" ]; then echo "文件存在"; fi

Part 2 项目中常用命令:

作为一个 Bash 新手,了解像 dirnamerealpath$0、以及如何使用环境变量如 TEST_RESOURCE_DIR 这些概念,是理解和编写有效 Bash 脚本的重要一步。我们逐一详细讲解这些工具和变量的用途。

1. $0:当前脚本的名字

$0 是一个特殊变量,在 Bash 脚本中用来表示当前脚本的名字。如果你运行一个脚本,$0 将包含这个脚本的文件名,可能是相对路径或绝对路径,取决于你如何运行它。

举例:

假设你有一个名为 myscript.sh 的脚本,内容如下:

#!/bin/bash
echo "The name of this script is: $0"

如果你在终端运行这个脚本:

$ ./myscript.sh

输出将是:

The name of this script is: ./myscript.sh

如果你使用绝对路径运行它,例如 /home/user/myscript.sh

$ /home/user/myscript.sh

输出将是:

The name of this script is: /home/user/myscript.sh

$0 通常用来获取当前脚本的路径,配合 dirnamerealpath 来定位脚本文件所在的目录。


2. dirname:获取文件的目录路径

dirname 是一个命令,用于获取文件的目录部分。它删除路径中的文件名,并返回目录路径。

举例:
dirname /home/user/scripts/myscript.sh

输出将是:

/home/user/scripts
在脚本中的用法:

如果你想知道当前脚本所在的目录,可以用 $0dirname 组合来获取。例如:

#!/bin/bash
script_dir=$(dirname "$0")
echo "The script is located in: $script_dir"

假设脚本的路径是 /home/user/scripts/myscript.sh,输出将是:

The script is located in: /home/user/scripts

这样,你可以在脚本中引用脚本所在的目录,方便后续操作文件。


3. realpath:获取文件的绝对路径

realpath 命令用于返回一个文件的绝对路径,解析任何符号链接或相对路径。这在你不确定路径是否是相对路径时非常有用。

举例:
realpath ./myscript.sh

假设当前目录是 /home/user/scripts/,输出将是:

/home/user/scripts/myscript.sh
在脚本中的用法:

结合 realpath$0,你可以始终获取脚本的绝对路径:

#!/bin/bash
script_path=$(realpath "$0")
echo "The full path to this script is: $script_path"

4. 组合使用 dirnamerealpath 来获取脚本目录

通常我们想要获取脚本所在的目录的绝对路径,可以这样组合使用 dirnamerealpath

#!/bin/bash
script_dir=$(dirname "$(realpath "$0")")
echo "The script is located in: $script_dir"
  • realpath "$0":先获取脚本的绝对路径。
  • dirname:再从路径中提取目录部分。
为什么要这么做?

这样无论你从哪个位置运行脚本,脚本都可以确定自己所在的目录,从而可以正确引用其他在同一目录中的文件。


5. TEST_RESOURCE_DIR:环境变量的使用

在 Bash 中,环境变量是存储全局或局部信息的方式。TEST_RESOURCE_DIR 是你可能在测试脚本中见到的一个自定义环境变量,它通常用来存储资源文件或测试数据所在的目录路径。

定义环境变量:

你可以在脚本中定义和使用环境变量,例如:

#!/bin/bash

TEST_RESOURCE_DIR="/home/user/test_resources"
echo "Test resources are located in: $TEST_RESOURCE_DIR"
使用已经定义的环境变量:

如果你已经在系统中定义了 TEST_RESOURCE_DIR,可以在脚本中直接使用它:

#!/bin/bash
echo "Test resources directory: $TEST_RESOURCE_DIR"

假设你在运行脚本之前设置了这个变量:

export TEST_RESOURCE_DIR="/home/user/resources"

然后运行脚本,输出将是:

Test resources directory: /home/user/resources

6. 综合示例:结合 dirname 和环境变量

假设你有一个测试脚本,想要引用存储在与脚本相同目录下的资源文件,并且 TEST_RESOURCE_DIR 是这个目录下的 resources 文件夹。

#!/bin/bash

# 获取当前脚本所在的目录
script_dir=$(dirname "$(realpath "$0")")

# 定义资源文件夹
TEST_RESOURCE_DIR="$script_dir/resources"

# 输出资源文件路径
echo "The test resources are located in: $TEST_RESOURCE_DIR"

这样,你就能根据脚本的位置自动设置 TEST_RESOURCE_DIR 的路径,而不必手动指定。


总结

  1. $0:表示当前脚本的名字,可以是相对路径或绝对路径。
  2. dirname:获取文件路径中的目录部分,用于确定文件所在的目录。
  3. realpath:获取文件或目录的绝对路径,确保路径是标准化的。
  4. 环境变量(如 TEST_RESOURCE_DIR:用于在脚本中存储和传递重要的目录或文件路径信息。
  5. 组合使用:通过结合 dirnamerealpath,你可以准确地获取脚本所在的目录,结合环境变量,让脚本更灵活和可移植。

$TEST_DIR:-$SCRIPT_PATH 是一种在 Bash 中使用参数扩展的语法,允许你设置一个默认值,当变量未定义或为空时使用默认值。

语法详解:

${VARIABLE:-DEFAULT_VALUE}
  • ${VARIABLE:-DEFAULT_VALUE}:这是 Bash 中的参数扩展,如果 VARIABLE 没有定义或为空,则返回 DEFAULT_VALUE
  • ${TEST_DIR:-$SCRIPT_PATH}:这意味着:
    • 如果变量 TEST_DIR 已经定义并且不为空,则使用 TEST_DIR 的值。
    • 如果 TEST_DIR 未定义或为空,则使用 SCRIPT_PATH 作为默认值。

使用场景

这种语法很有用,特别是在编写脚本时,如果用户没有设置某些环境变量或参数,脚本可以为其提供一个合理的默认值。例如,如果用户没有定义 TEST_DIR,脚本将会自动使用 SCRIPT_PATH 作为替代。

示例

#!/bin/bash

# 假设这是获取脚本路径的代码
SCRIPT_PATH=$(dirname "$(realpath "$0")")

# 使用参数扩展,设置 TEST_DIR 的默认值为 SCRIPT_PATH
TEST_DIR=${TEST_DIR:-$SCRIPT_PATH}

echo "Test directory: $TEST_DIR"
运行结果:
  1. TEST_DIR 未定义时:

    • TEST_DIR 会使用 SCRIPT_PATH 的值。
    • 输出类似于:
      Test directory: /home/user/scripts
      
  2. TEST_DIR 已定义时:

    • 如果你事先定义了 TEST_DIR,如:
      export TEST_DIR="/custom/test/dir"
      
    • 那么脚本会使用这个值,而不是 SCRIPT_PATH
      Test directory: /custom/test/dir
      

总结

  • :- 是 Bash 中的参数扩展,用于设置默认值。
  • ${TEST_DIR:-$SCRIPT_PATH} 的意思是:如果 TEST_DIR 未定义或为空,则使用 SCRIPT_PATH 作为默认值。
  • 这是处理可选参数或环境变量的一种常见而有效的方式。

在 Bash 中,CASE_NAME=$(basename "$0") 这行代码的作用是获取当前脚本的文件名,并将其赋值给变量 CASE_NAME

语法详解

  1. basename 命令

    • basename 是一个 Unix/Linux 命令,用于去除路径中的目录部分,只返回文件名
    • 例如,给定 /home/user/scripts/myscript.shbasename 将只返回 myscript.sh
  2. $0

    • 在 Bash 中,$0 是一个特殊变量,表示当前脚本的名字。它可以是相对路径绝对路径,取决于你如何运行脚本。
  3. $(...)

    • 这是命令替换的语法,表示执行括号中的命令并将结果返回。相当于把 basename "$0" 的输出赋值给变量 CASE_NAME

示例说明

假设你的脚本是 /home/user/scripts/test_script.sh,内容如下:

#!/bin/bash

CASE_NAME=$(basename "$0")
echo "The case name is: $CASE_NAME"
运行结果

如果你在终端中运行该脚本:

$ /home/user/scripts/test_script.sh

输出将是:

The case name is: test_script.sh
  • basename "$0" 提取了 test_script.sh,并将其赋值给 CASE_NAME
  • 然后 echo 输出结果。

CASE_NAME="${CASE_NAME%.*}" 是一个字符串操作,用于去除文件名中的扩展名,只保留主文件名部分。

语法详解

  1. ${VAR%PATTERN}

    • 这是 Bash 中的一种字符串操作,称为参数扩展
    • ${VAR%PATTERN}:用于从字符串的末尾删除符合模式 PATTERN 的部分。
    • % 表示从右侧开始匹配一次。
    • %% 会删除匹配模式的最大部分(全匹配)。
  2. %.*

    • .* 是一个通配符模式,表示从最后一个. 到字符串结尾的所有字符(即扩展名)。
    • 例如,对于文件名 script.sh%.* 会匹配 .sh,从而删除它。

示例

假设 CASE_NAME="test_script.sh",我们执行:

CASE_NAME="${CASE_NAME%.*}"

这行代码会删除 test_script.sh 中的扩展名 .sh,留下 test_script

举例说明

结合前面的例子,假设脚本的路径是 /home/user/scripts/test_script.sh,代码如下:

#!/bin/bash

# 获取脚本的文件名
CASE_NAME=$(basename "$0")

# 去掉扩展名
CASE_NAME="${CASE_NAME%.*}"

echo "The case name is: $CASE_NAME"
运行结果

如果你运行这个脚本:

$ /home/user/scripts/test_script.sh

输出将是:

The case name is: test_script
  • basename "$0" 返回 test_script.sh
  • ${CASE_NAME%.*} 去除了 .sh,只剩下 test_script

使用场景

这种用法非常常见,当你只需要处理文件名的主部分而不需要扩展名时。例如:

  1. 创建日志文件:如果你想根据脚本名生成日志文件,但不想包含扩展名。

    LOGFILE="/var/log/${CASE_NAME}.log"
    
  2. 根据文件名执行不同操作:你可以根据文件名的主部分执行特定任务,而忽略扩展名。

总结

  • ${VAR%.*} 是一种 Bash 字符串操作,用于删除变量中从最后一个 . 到字符串末尾的部分。
  • 常用于从文件名中去除扩展名,方便后续处理。

这行代码的作用是找到指定目录 tmp/nxperf最新的 .zip 文件,并将其存储在变量 latest_file 中。让我们逐步解释这段代码的工作原理:

latest_file=$(ls -t $directory/*.zip | head -n 1)

逐步解析

  1. directory=tmp/nxperf

    • 这是定义变量 directory 并赋值为 tmp/nxperf。这个变量表示你要查找 .zip 文件的目录。
  2. ls -t $directory/*.zip

    • ls 是用于列出目录内容的命令。
    • -t 选项表示按时间排序,最近修改的文件会排在最前面。
    • $directory/*.zip 指定要查找 tmp/nxperf 目录下以 .zip 结尾的文件。$directory 使用变量替换,这相当于 tmp/nxperf/*.zip

    例子:如果 tmp/nxperf 目录下有以下文件:

    file1.zip  (最早)
    file2.zip  (稍早)
    file3.zip  (最近)
    

    ls -t $directory/*.zip 输出顺序将是:

    file3.zip
    file2.zip
    file1.zip
    
  3. | (管道符号)

    • 管道 |ls -t 命令的输出传递给下一个命令(head)。也就是说,将文件列表传递给 head 命令进行进一步处理。
  4. head -n 1

    • head 是一个命令,用于显示输出的前 N 行,默认是前 10 行。
    • -n 1 表示只显示第一行,也就是最近修改的那个 .zip 文件。
  5. $(...)

    • 这是命令替换语法,将 ls -t $directory/*.zip | head -n 1 命令的结果赋值给 latest_file 变量。

总结:

这段代码的作用是:

  1. 找到 tmp/nxperf 目录下所有 .zip 文件。
  2. 按照修改时间倒序排列,最近的文件排在最前面。
  3. 通过 head -n 1 只取第一个文件(即最新的 .zip 文件)。
  4. 将该文件的路径存储到变量 latest_file 中。
示例:

假设 tmp/nxperf 目录下有以下文件:

file1.zip  (2024-01-01 10:00)
file2.zip  (2024-01-02 11:00)
file3.zip  (2024-01-03 12:00)

运行这段代码后:

directory=tmp/nxperf
latest_file=$(ls -t $directory/*.zip | head -n 1)
echo $latest_file

输出将是:

tmp/nxperf/file3.zip

因为 file3.zip 是最新的文件。

举个例子:

#!/bin/bash

SCRIPT_PATH=$(dirname "$(realpath "$0")")
TEST_PATH=${TEST_RESOURCE_DIR:-$SCRIPT_PATH}
PRAC_HOME=/tmp/prac
DEFAULT_TARGET_PATH=$TEST_PATH/prac_archive
TARGET_PATH=${OUTPUT_ENVIRONMENT_PATH:-$DEFAULT_TARGET_PATH} # OUTPUT_ENVIRONMENT_PATH needs to be set otherwise use DEFAULT_TARGET_PATH to replace it
echo "Result target path: $TARGET_PATH"
mkdir -p $PRAC_HOME
CASE_NAME=$(basename "$0")
CASE_NAME="${CASE_NAME%.*}"
echo "start run $CASE_NAME"

prac_bin -e all # run the bin with args

echo "run $CASE_NAME successfully"
current_magic=$(date +"%Y-%m-%d-%H-%M-%S")
latest_file=$(ls -t $PRAC_HOME/*.zip | head -n 1)
if [ -n "$latest_file" ]; then
    mv "$latest_file" "$TARGET_PATH/$current_magic-$CASE_NAME.zip"
    echo "Renamed $latest_file to $TARGET_PATH/$current_magic-$CASE_NAME.zip"
else
    echo "No files found in the directory."
fi

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值