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

相关推荐
dingdingfish3 天前
GNU Parallel 学习 - 第1章:How to read this book
bash·shell·gnu·parallel
似霰6 天前
Linux Shell 脚本编程——核心基础语法
linux·shell
似霰7 天前
Linux Shell 脚本编程——脚本自动化基础
linux·自动化·shell
偷学技术的梁胖胖yo8 天前
Shell脚本中连接数据库查询数据报错 “No such file or directory“以及函数传参数组
linux·mysql·shell
纵有疾風起17 天前
【Linux 系统开发】基础开发工具详解:软件包管理器、编辑器。编译器开发实战
linux·服务器·开发语言·经验分享·bash·shell
gis分享者19 天前
Shell 脚本中如何使用 here document 实现多行文本输入? (中等)
shell·脚本·document·多行·文本输入·here
柏木乃一19 天前
基础IO(上)
linux·服务器·c语言·c++·shell
angushine19 天前
CPU脚本并远程部署
shell
赵民勇24 天前
Linux/Unix中install命令全面用法解析
linux·shell
gis分享者25 天前
Shell 脚本中如何使用 trap 命令捕捉和处理信号(中等)
shell·脚本·信号·处理·trap·捕捉