前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Shell编程中关于参数是否有双引号包裹以及脚本查找最后一个参数易错点

Shell编程中关于参数是否有双引号包裹以及脚本查找最后一个参数易错点

原创
作者头像
哎呀_编号89757
发布2024-08-09 10:16:16
750
发布2024-08-09 10:16:16
举报
文章被收录于专栏:Shell编程读书笔记

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

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

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

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

代码语言:shell
复制
[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

结果:

代码语言:shell
复制
[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里直接写并不一致。

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

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

代码语言:shell
复制
[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

结果:

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

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

原文
原文

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

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

代码语言:shell
复制
[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/"

测试:

代码语言:shell
复制
#!/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

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

代码语言:shell
复制
[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"

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

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

可知,书中的结论其实并不适配所有服务器,或者说书中的答案其实是错的。

不过对于获取命令行参数的最后一个参数可以通过如下的方式进行书写,即将 $# 参数的个数用一个变量来替换,这样就可以使用${!param}格式来书写了,并且出现了跟书中同样的结果:

代码语言:shell
复制
[root@iZuf6gxtsgxni1r88kx9rtZ linux_cmd]# cat goodlastparameter.sh 
#!/bin/bash
param_cnt=$#
echo The last parameter is ${!param_cnt}
### 结果:

[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脚本编程大全》已经出到第四版了,但是依然有代码问题。所以,还是希望大家从这篇文章中能得到一些知识点。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 关于 -n $1 与 -n "$1"的区别
  • 关于命令行参数最后一个参数的获取
  • 结论
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档