shell脚本中的特殊变量与if条件测试

简介: shell脚本中的特殊变量与if条件测试

1.特殊变量


     实际工作中我们不可避免的遇到一些xxxx.sh脚本文件,实际阅读shell脚本代码时经常会遇到很多特殊变量(例如:$0、$n、$#、$@、$*、$?、$$等),我们常常会被这些特殊符号折腾的脑壳痛,本期文章就会对这些奇奇怪怪的特殊符号进行一个总结,以便后续工作中遇到时可以及时复习。废话不多说,直接开干!查阅了网上的一些资料,对这些特殊变量的整理如下所示:


序号 特殊变量 含义
1
$0 当前脚本的文件名称
2 $n 传递给脚本或函数的参数,n是一个数字,表示第几个参数。例如:第1个参数是$1,第2个参数是$2,其余依次类推......
3 $# 传递给脚本或函数的参数个数
4 $* 传递给脚本或函数的所有参数
5 $@ 传递给脚本或函数的所有参数,与$*的区别稍后会进行比较
6
$? 返回执行完上一条命令后,退出时的状态或函数的返回值
7
$$ 当前shell进程的ID


    下面用一些简单的测试代码向大家展示一下,在shell脚本中上述特殊变量的应用。


1.1 $$的用法


可以看到我们将特殊变量$$的值打印出来了,即当前shell进程的ID号为6929。


[cdl@h3c/home/cdl]$echo "hello world" $$
hello world 6929



1.2 $0、$n、$#、$*、$@的用法


     可以编写一个简单的测试脚本demo.sh,运行脚本时给此脚本传递一些参数(简称:命令行参数),如下所示。命令行参数用$n表示,例如:$1表示第一个参数、$2表示第二个参数、$3表示第三个参数,其余依次类推......


[cdl@h3c/home/cdl/Test]$cat demo.sh
#!/bin/bash
:<<comment
echo "这是shell脚本中整段代码注释的方法,不需要逐行用#进行注释"
comment
echo "当前文件名称: $0"
echo "命令行参数中的第1个参数: $1"
echo "命令行参数中的第2个参数: $2"
echo "传递给脚本或函数的所有参数: $@"
echo "传递给脚本或函数的所有参数: $*"
echo "传递给脚本或函数的所有参数总数: $#"
[cdl@h3c/home/cdl/Test]$
[cdl@h3c/home/cdl/Test]$chmod 777 demo.sh
[cdl@h3c/home/cdl/Test]$
[cdl@h3c/home/cdl/Test]$
[cdl@h3c/home/cdl/Test]$./demo.sh Curry Durant
当前文件名称: ./demo.sh
命令行参数中的第1个参数: Curry
命令行参数中的第2个参数: Durant
传递给脚本或函数的所有参数: Curry Durant
传递给脚本或函数的所有参数: Curry Durant
传递给脚本或函数的所有参数总数: 2


1.3 $?的用法


     $?可以获取上一条命令的退出状态,退出状态是一个数字。如果退出状态为非0值,则表示上一条命令执行异常啦。我们可以故意将demo.sh脚本中的最后一行命令修改错误,打印一下$?为127。由此,我们可以知道demo.sh脚本的最后一行命令执行失败啦。


[cdl@h3c/home/cdl/Test]$cat demo.sh
#!/bin/bash
:<<comment
echo "这是shell脚本中整段代码注释的方法,不需要逐行用#进行注释"
comment
echo "当前文件名称: $0"
echo "命令行参数中的第1个参数: $1"
echo "命令行参数中的第2个参数: $2"
echo "传递给脚本或函数的所有参数: $@"
echo "传递给脚本或函数的所有参数: $*"
eho "传递给脚本或函数的所有参数总数: $#"
[cdl@h3c/home/cdl/Test]$./demo.sh Curry Durant
当前文件名称: ./demo.sh
命令行参数中的第1个参数: Curry
命令行参数中的第2个参数: Durant
传递给脚本或函数的所有参数: Curry Durant
传递给脚本或函数的所有参数: Curry Durant
./demo.sh: line 15: eho: command not found
[cdl@h3c/home/cdl/Test]$echo $?
127


1.4 $@与$*的区别


     $*和$@都可以表示传递给脚本或者函数的所有参数,$*和$@不被双引号""包含时,两者都是以$1、$2、$3...$n的形式逐一输出所有参数;但是当$*和$@被双引号""包含时,两者就会有区别:$*会将所有参数作为一个整体输出(具体形如"$1 $2 $3 ... $n"的格式输出所有参数);而$@会将各个参数分开输出(具体形如$1、$2、$3...$n的格式输出所有参数)。


    如果直接用echo直接输出$*和$@是看不出来两者的区别,例如上面的demo.sh脚本;但如果使用for循环依次输出所有参数时,立即就可以看出两者的区别。如下所示:


[cdl@h3c/home/cdl/Test]$cat test.sh 
#!/bin/bash
echo "\$* =" $*
echo "\"\$*\" =" $*
echo "print each param from \$*"
for var in $*
do
    echo "$var"
done
echo "print each param from \"\$*\""
for var in "$*"
do
    echo "$var"
done
echo "====================此处是分割线========================"
echo "\$@ =" $@
echo "\"\$@\" =" $@
echo "print each param from \$@"
for var in $@
do
    echo "$var"
done
echo "print each param from \"\$@\""
for var in "$@"
do
    echo "$var"
done
[cdl@h3c/home/cdl/Test]$chmod 777 test.sh 
[cdl@h3c/home/cdl/Test]$./test.sh A B C D
$* = A B C D
"$*" = A B C D
print each param from $*
A
B
C
D
print each param from "$*"
A B C D
====================此处是分割线========================
$@ = A B C D
"$@" = A B C D
print each param from $@
A
B
C
D
print each param from "$@"
A
B
C
D


2.if条件测试


     总结完shell脚本中的特殊变量,接着再输出一下也是shell脚本中很常见的if条件测试。之所以对这一部分进行总结,原因是自己遇到的编译脚本中遇到实在是太多了。此外,前几天也有别人在问我这个问题,一时竟记不起来。于是,本期文章的第二部分会对如何测试文件表达式、字符串表达式、整数表达式进行梳理总结。


2.1 测试文件表达式


     文件表达式中涉及很多测试选项,在实际脚本文件中应用的也很多。同时,查找网上资料将常用的一些测试选项整理如下。最后,用一个简单的脚本样例进行说明。

37.jpg

38.jpg

测试文件表达式


[cdl@h3c/home/cdl/Test]$cat hello.sh 
#!/bin/bash
FILE=~/.bashrc
if [ -e "$FILE" ]; then
    if [ -f "$FILE" ]; then
        echo "$FILE是一个普通文件"
    fi
    if [ -d "$FILE" ]; then
        echo "$FILE是一个目录"
    fi
    if [ -r "$FILE" ]; then
        echo "$FILE是一个可读文件"
    fi
    if [ -w "$FILE" ]; then
        echo "$FILE是一个可写文件"
    fi
    if [ -x "$FILE" ]; then
        echo "$FILE 是一个可执行文件"
    fi
else
    echo "$FILE是一个不存在的文件"
    exit 1
fi
exit
[cdl@h3c/home/cdl/Test]$chmod 777 hello.sh
[cdl@h3c/home/cdl/Test]$./hello.sh
/home/cdl/.bashrc是一个普通文件
/home/cdl/.bashrc是一个可读文件
/home/cdl/.bashrc是一个可写文件
/home/cdl/.bashrc 是一个可执行文件


2.2 测试字符串表达式

     

有了前面测试文件表达式的经验,使用同样的方法对字符串表达式进行测试。同时,查找网上资料将常用的一些测试选项整理如下。最后,用一个简单的脚本样例进行说明。

39.jpg

测试字符串表达式


[cdl@h3c/home/cdl/Test]$cat debug.sh
#!/bin/bash
ANSWER=maybe
if [ -z "$ANSWER" ]; then
    # >&2:将There is answer错误信息重定向到标准错误(2是标准错误对应的文件描述符)
    echo "There is no answer." >&2
    exit 1
elif [ "$ANSWER" = "no" ]; then
    echo "The answer is no"
elif [ "$ANSWER" = "yes" ]; then
    echo "The answer is yes"
elif [ "$ANSWER" = "maybe" ]; then
    echo "The answer is maybe"
else
    echo "The answer is unknown"
fi    
[cdl@h3c/home/cdl/Test]$chmod 777 debug.sh
[cdl@h3c/home/cdl/Test]$./debug.sh
The answer is maybe


2.3 测试整数表达式

   

使用同样的方法对整数表达式进行测试,测试时注意大于、小于、等于选项的英文表示。同时,查找网上资料将常用的一些测试选项整理如下。最后,用一个简单的脚本样例进行说明

40.jpg

测试整数表达式


[cdl@h3c/home/cdl/Test]$cat int.sh 
#!/bin/bash
INT=-5
if [ -z "$INT" ]; then
    echo "INT is empty" >&2
    exit 1
fi
if [ $INT -eq 0 ]; then
    echo "INT is zero"
else
    if [ $INT -lt 0 ]; then
        echo "INT is negative"
    else
        echo "INT is positive"
    fi
    if [ $((INT % 2)) -eq 0 ]; then
        echo "INT is even"
    else
        echo "INT is odd"
    fi
fi
[cdl@h3c/home/cdl/Test]$chmod 777 int.sh
[cdl@h3c/home/cdl/Test]$./int.sh 
INT is negative
INT is odd
相关文章
|
2月前
|
测试技术 Linux
VPS一键测试脚本,无痕体验+自动导出,服务器测试更轻松
NodeQuality 是一款整合 Yabs、IPQuality、NetQuality 等主流 VPS 测试脚本的全能工具,支持一键测试硬件性能、IP属性、网络质量,并新增分享与导出功能。其“无痕测试”设计不安装依赖、不留残留,兼容性强;测试结果自动排版、截图并生成分享链接,极大提升效率。适合需要全面、快速、干净测试 VPS 的用户,是运维和测评的高效利器。
207 3
|
2月前
|
存储 安全 Unix
七、Linux Shell 与脚本基础
别再一遍遍地敲重复的命令了,把它们写进Shell脚本,就能一键搞定。脚本本质上就是个存着一堆命令的文本文件,但要让它“活”起来,有几个关键点:文件开头最好用#!/usr/bin/env bash来指定解释器,并用chmod +x给它执行权限。执行时也有讲究:./script.sh是在一个新“房间”(子Shell)里跑,不影响你;而source script.sh是在当前“房间”里跑,适合用来加载环境变量和配置文件。
391 9
|
2月前
|
存储 Shell Linux
八、Linux Shell 脚本:变量与字符串
Shell脚本里的变量就像一个个贴着标签的“箱子”。装东西(赋值)时,=两边千万不能有空格。用单引号''装进去的东西会原封不动,用双引号""则会让里面的$变量先“变身”再装箱。默认箱子只能在当前“房间”(Shell进程)用,想让隔壁房间(子进程)也能看到,就得给箱子盖个export的“出口”戳。此外,Shell还自带了$?(上条命令的成绩单)和$1(别人递进来的第一个包裹)等许多特殊箱子,非常有用。
256 2
|
5月前
|
Shell
Shell脚本循环控制:shift、continue、break、exit指令
使用这些命令可以让你的Shell脚本像有生命一样动起来。正确使用它们,你的脚本就能像一场精心编排的舞蹈剧目,既有旋律的起伏,也有节奏的跳跃,最终以一场惊艳的表演结束。每一个动作、每一个转折点,都准确、优雅地完成所需要表达的逻辑。如此,你的脚本不只是冰冷的代码,它透过终端的界面,跳着有节奏的舞蹈,走进观众——使用者的心中。
240 60
|
2月前
|
存储 测试技术 API
数据驱动开发软件测试脚本
今天刚提交了我的新作《带着ChatGPT玩转软件开发》给出版社,在写作期间跟着ChatGPT学到许多新知识。下面分享数据驱动开发软件测试脚本。
87 0
|
2月前
|
数据采集 监控 Shell
无需Python:Shell脚本如何成为你的自动化爬虫引擎?
Shell脚本利用curl/wget发起请求,结合文本处理工具构建轻量级爬虫,支持并行加速、定时任务、增量抓取及分布式部署。通过随机UA、异常重试等优化提升稳定性,适用于日志监控、价格追踪等场景。相比Python,具备启动快、资源占用低的优势,适合嵌入式或老旧服务器环境,复杂任务可结合Python实现混合编程。
|
8月前
|
关系型数据库 MySQL Shell
MySQL 备份 Shell 脚本:支持远程同步与阿里云 OSS 备份
一款自动化 MySQL 备份 Shell 脚本,支持本地存储、远程服务器同步(SSH+rsync)、阿里云 OSS 备份,并自动清理过期备份。适用于数据库管理员和开发者,帮助确保数据安全。
|
4月前
|
Web App开发 缓存 安全
Linux一键清理系统垃圾:释放30GB空间的Shell脚本实战​
这篇博客介绍了一个实用的Linux系统盘清理脚本,主要功能包括: 安全权限检查和旧内核清理,保留当前使用内核 7天以上日志文件清理和系统日志压缩 浏览器缓存(Chrome/Firefox)、APT缓存、临时文件清理 智能清理Snap旧版本和Docker无用数据 提供磁盘空间使用前后对比和大文件查找功能 脚本采用交互式设计确保安全性,适合定期维护开发环境、服务器和个人电脑。文章详细解析了脚本的关键功能代码,并给出了使用建议。完整脚本已开源,用户可根据需求自定义调整清理策略。
467 1
|
4月前
|
Web App开发 JavaScript 测试技术
Playwright 极速入门:1 小时搞定环境搭建与首个测试脚本
本文带你1小时快速入门Playwright,完成环境搭建并编写首个测试脚本。Playwright是微软推出的现代化Web自动化测试工具,支持Chromium、Firefox和WebKit三大浏览器引擎,具备跨平台、多语言(Python/JS/Java/C#)特性。其核心优势包括:智能自动等待机制减少失败率、内置录制工具实时生成脚本、多语言灵活选择,以及真移动端设备模拟能力,显著提升测试效率和可靠性。
|
6月前
|
存储 Unix Shell
确定Shell脚本在操作系统中的具体位置方法。
这对于掌握Linux的文件系统组织结构和路径方面的理解很有帮助,是我们日常工作和学习中都可能使用到的知识。以上讲解详细清晰,应用简便,是每一个想要精通操作系统的计算机爱好者必备的实用技能。
161 17