Shell编程中关于参数的两个易错点

最近在学习《Linux命令行和shell脚本编程大全》(第四版)这本书,对于自己遇到的问题以及通过搜索引擎和书籍中的解决方案进行一个案例的剖析,希望对于像我这样的初学者,有一个帮助。

问题其实都相对简单,但是如果这些点大家不了解,可能还真的会将大家从Shell编程入门直接扼杀到放弃了。

关于 -n $1 与 -n "$1"的区别

在用if条件对于命令行第一个参数进行判别时,我不小心将 "$1" 写成了 $1 ,发现最后的结果结果报错,以下为代码:

bash 复制代码
 [root@iZuf6gxtsgxni1r88kx9rtZ ~]# cat param_one.sh 
 #!/bin/bash
 echo "***************************"
 echo "$1 参数测试..."
 if [ -n $1 ]
 then
     echo "参数不为空,且值为:$1"
 fi
 echo "***************************"
 echo ""$1" 参数测试..."
 if [ -n "$1" ]
 then
     echo "参数不为空,且值为:$1"
 fi

结果:

markdown 复制代码
 [root@iZuf6gxtsgxni1r88kx9rtZ ~]# sh param_one.sh "my dear"
 ***************************
 $1 参数测试...
 param_one.sh: line 4: [: my: binary operator expected
 ***************************
 "$1" 参数测试...
 参数不为空,且值为:my dear

发现第一段脚本提示param_one.sh: line 4: [: my: binary operator expected,可以想见,如果不用""括上,就会导致中括号内的$1无法被解析,这跟直接在echo里直接写并不一致。

总结可知,在[]抑或是{}内,使用变量需要使用""对其进行包裹,而在其他情况下,可以不使用"",也可以引用参数。

以下几种情况还请大家仔细体会:

bash 复制代码
 [root@iZuf6gxtsgxni1r88kx9rtZ ~]# cat param_one.sh 
 #!/bin/bash
 echo "***************************"
 echo "$1 参数测试..."
 if [ -n $1 ]
 then
     echo "参数不为空,且值为:$1"
 fi
 echo "***************************"
 echo ""$1" 参数测试..."
 if [ -n "$1" ]
 then
     echo "参数不为空,且值为:$1"
 fi
 echo "****************************"
 param="hello world"
 if [ -n "$param" ]
 then
     echo "第一行代码,$param"
 fi
 echo "****************************"
 echo 第二行代码:$param

结果:

markdown 复制代码
 [root@iZuf6gxtsgxni1r88kx9rtZ ~]# sh param_one.sh 
 ***************************
 $1 参数测试...
 参数不为空,且值为:
 ***************************
 "$1" 参数测试...
 ****************************
 第一行代码,hello world
 ****************************
 第二行代码:hello world
关于命令行参数最后一个参数的获取

在第四版中有这样的一段话:

但是如果按照这个脚本测试:

在阿里云的ecs上,版本号如下:

ini 复制代码
 [root@iZuf6gxtsgxni1r88kx9rtZ ~]# cat /etc/os-release 
 NAME="Alibaba Cloud Linux"
 VERSION="3 (Soaring Falcon)"
 ID="alinux"
 ID_LIKE="rhel fedora centos"
 VERSION_ID="3"
 PLATFORM_ID="platform:al8"
 PRETTY_NAME="Alibaba Cloud Linux 3 (Soaring Falcon)"
 ANSI_COLOR="0;31"
 HOME_URL="https://www.aliyun.com/"

测试:

csharp 复制代码
 #!/bin/bash
 echo The Number of Parameters is $#
 echo the last parameter is ${!#}
 exit
 ​
 结果如下:
 [root@iZuf6gxtsgxni1r88kx9rtZ ~]# sh badlastparamtest.sh a b c d 
 The Number of Parameters is 4
 the last parameter is

在百度云上,版本号如下:

ini 复制代码
 [jiangms@instance-jgzzg4xl ~]$ cat /etc/os-release 
 NAME="CentOS Linux"
 VERSION="7 (Core)"
 ID="centos"
 ID_LIKE="rhel fedora"
 VERSION_ID="7"
 PRETTY_NAME="CentOS Linux 7 (Core)"
 ANSI_COLOR="0;31"
 CPE_NAME="cpe:/o:centos:centos:7"
 HOME_URL="https://www.centos.org/"
 BUG_REPORT_URL="https://bugs.centos.org/"
 ​
 CENTOS_MANTISBT_PROJECT="CentOS-7"
 CENTOS_MANTISBT_PROJECT_VERSION="7"
 REDHAT_SUPPORT_PRODUCT="centos"
 REDHAT_SUPPORT_PRODUCT_VERSION="7"

测试同样的脚本,结果如下:

csharp 复制代码
 [jiangms@instance-jgzzg4xl ~]$ sh badparameter.sh 
 the number of parameters is 0
 the last parameter is

可知,书中的结论其实并不适配所有服务器。

不过对于获取命令行参数的最后一个参数可以通过如下的方式:

csharp 复制代码
 [root@iZuf6gxtsgxni1r88kx9rtZ ~]# sh goodlastparameter.sh 
 the count of parameters is 0
 the last parameter is goodlastparameter.sh
 ​
 [root@iZuf6gxtsgxni1r88kx9rtZ ~]# sh goodlastparameter.sh a b d "hello world"
 the count of parameters is 4
 the last parameter is hello world

Tip:当用这种种方法时,如果对脚本没有输入参数,则显示的为命令的本身名称。

而为什么在 {...} 内不能使用 $ 而需要 ! 来代替,这可能是需要死记硬背了。

结论

尽信书,不如无书。所以,对于书中的话我们需要验证着看,《Linux命令行和shell脚本编程大全》已经出到第四版了,但是依然有代码问题。所以,还是希望大家从这篇文章中能得到一些知识点。

相关推荐
AnxiangLemon9 天前
Warp Lite :一个专注本地使用的开源终端
终端·shell·warp·warp lite
sbjdhjd12 天前
从污点追踪断点到 PHP-FPM 请求队列:HIDS PHP WebShell 样本复盘
开发语言·网络安全·数据挖掘·渗透测试·开源·php·shell
Shell运维手记15 天前
Shell 结构化命令知识点总结(case、for、while)
运维·microsoft·shell·脚本
云计算练习生15 天前
什么是 Bash?Linux 默认 Shell 的核心功能
linux·操作系统·bash·shell·命令解释器
猫咪很可爱16 天前
MySQL 5.7 备份恢复后函数与存储过程丢失:原因分析与正确备份姿势
数据库·mysql·bug·shell
qetfw17 天前
Linux 文件清理:find、mtime 与安全传参验证
linux·shell·1024程序员节
Lsetea19 天前
curl下载HTTPS文件报23:证书验证成功与本地写入失败分层排查
linux·https·shell·ssl证书·curl
DogDaoDao20 天前
Windows 双 Shell 全面对比:CMD 与 PowerShell 的技术剖析
windows·shell·测试·powershell·cmd·程序员开发
Lsetea21 天前
OpenSSL的checkhost显示不匹配却退出0:名称检查与证书验收
linux·https·shell·ssl证书·openssl
钱栈up24 天前
耳机音效不对,我顺手查了系统更新,结果挖出个崩溃了整天的服务
windows·shell