Bash技巧:详解用$获取变量值是否要加双引号或者大括号

本篇文章介绍在 Linux bash shell 中,用 $ 获取变量值时,是否要加双引号、是否要加大括号。

用 $ 获取变量值是否要加双引号

在 bash shell 脚本中,用 $ 来获取变量值时,有一些不加双引号,例如 $arg。有一些会加双引号,例如 "$arg"
下面具体说明这两种形式之间的区别,什么情况下要加双引号,什么情况可以不加双引号。

在 bash 中,各个参数之间默认用隔开。
当参数值本身就带有空格时,如果不加双引号把参数值括起来,那么这个参数值可能会被扩展为多个参数值,而丢失原本的完整值。
具体举例说明如下:

$ function test_args() { echo \$\#: $#; echo first: $1; echo second: $2; }
$ args="This is a Test"
$ test_args $args
$#: 4
first: This
second: is
$ test_args "$args"
$#: 1
first: This is a Test
second:

这里定义了一个 test_args 函数,打印传入的 $1$2 参数值。
所给的 args 变量指定的字符串含有空格。

可以看到,当执行 test_args $args 时,args 变量的值被空格隔开成四个参数。
而执行 test_args "$args" 时,args 变量的值保持不变,被当成一个参数。
使用双引号把字符串括起来,可以避免空格导致单词拆分。

即,当我们需要保持变量本身值的完整,不想被空格扩展为多个参数,那么就需要用双引号括起来

在给脚本或函数传递参数时,我们可能不确定获取到的参数值是否带有空格。
为了避免带有空格导致不预期的单词拆分,造成参数个数发生变化,建议传参时每个参数都使用双引号括起来。

用 $ 获取变量值是否要加大括号

在 bash shell 脚本中,用 $ 来获取变量值时,有一些不加大括号,例如 $var。有一些会加大括号,例如 ${var}
下面具体说明这两种形式之间的区别,什么情况下要加大括号,什么情况可以不加大括号。

查看 man bash 里面对 ${parameter} 表达式的含义说明如下:

${parameter}
The value of parameter is substituted.
The braces are required when parameter is a positional parameter with more than one digit, or when parameter is followed by a character which is not to be interpreted as part of its name.
The parameter is a shell parameter or an array reference (Arrays).

即,大括号 {} 的作用是限定大括号里面的字符串是一个整体,不会跟相邻的字符组合成其他含义。

例如,有一个 var 变量值是 "Say",现在想打印这个变量值,并跟着打印 "Hello" 字符串,也就是打印出来 "SayHello" 字符串。
那么获取 var 变量值的语句和 "Hello" 字符串中间就不能有空格,否则 echo 命令会把这个空格一起打印出来。
但是写为 $varHello 达不到想要的效果。
具体举例如下:

$ var="Say"
$ echo $var Hello
Say Hello
$ echo $varHello

$ echo ${var}Hello
SayHello
$ echo "$var"Hello
SayHello

可以看到,$var Hello 这种写法打印出来的 "Say" 和 "Hello" 中间有空格,不是想要的结果。
$varHello 打印为空,这其实是获取 varHello 变量的值,这个变量没有定义过,默认值是空。
${var}Hello 打印出了想要的结果,用 {} 把 var 括起来,明确指定要获取的变量名是 var,避免混淆。
"$var"Hello 用双引号把 $var 括起来,也可以跟后面的 "Hello" 字符串区分开。

即,当用 $ 获取变量值时,如果变量名后面跟着空白字符,隔开了其他内容,可以不用大括号来把变量名括起来。

如果变量名后面直接跟着不属于变量名自身的其他字符,就需要用大括号把变量名括起来,以便明确该变量的名称

Image placeholder
jason2014
未设置
  76人点赞

没有讨论,发表一下自己的看法吧

推荐文章
Bash技巧:使用参数扩展获取变量的子字符串和字符串长度

在bash中,通常使用${parameter}表达式来获取parameter变量的值,这是一种参数扩展(parameterexpansion)。Bash还提供了其他形式的参数扩展,可以对变量值做一些处

mysql 进行update时,要更新的字段中有单引号或者双引号导致不能批量生成sql的问题

前言将数据从一张表迁移到另外一张表的过程中,通过mysql的concat方法批量生成sql时遇到了一个问题,即进行UPDATE更新操作时如果原表中的字段中包含单引号'或者双引号",那么就会生成不正确的

Ubuntu常用技巧:npm下载很慢的超简单解决方法

在使用npm下载时,速度特别特别慢,等了半小时还是纹丝不动:尝试了一些方法,效果不是很明显,最终发现一种简单有效的方法:1.终端输入命令,显示当前的镜像地址:npmgetregistry2.再输入命令

算法题:判断括号字符串是否有效

题目来源于力扣 理论基础 堆栈&队列 判断括号字符串是否有效 题目描述 给定一个只包括'(',')','{','}','[',']'的字符串,判断字符串是否有效。 有效字符串需满足:左括号必

算法题:判断括号字符串是否有效

题目来源于力扣 理论基础 堆栈&队列 判断括号字符串是否有效 题目描述 给定一个只包括'(',')','{','}','[',']'的字符串,判断字符串是否有效。 有效字符串需满足:左括号必

jquery如何判断值是否是url地址?

jquery如何判断值是否是url地址?思路:1、创建一个输入框,使用jquery给它注册change事件;2、创建一个函数checkUrl,传入一个url参数;3、函数内编写一条检测url正确性的正

jquery怎么判断值是否在数组中?

要判断数组中是否包含某个元素,从原理来来说,就是遍历整个数组,然后判断是否相等Jquery方法可以使用Jquery提供的方法:使用$.inArray()来判断。inArray()函数用于在数组中查找指

社交媒体登录认证提供者大全 —— Socialite Providers,支持微博、微信、QQ等

社交媒体登录认证提供者大全——SocialiteProviders,支持微博、微信、QQ等 1、简介 SocialiteProviders是一个扩展自LaravelSocialite的OAuth1&

笨办法学 Linux Bash:Shell、`.profile`、`.bashrc`、`.bash_history`

Bash:Shell、.profile、.bashrc、.bash_history。 当使用CLI(命令行界面)来使用Linux时,你正在与一个名为shell的程序进行交互。所有你输入的都传递给she

第 10 节:复合类型-5. 指针 -- 指针与指针变量 7. 结构体指针变量

7.结构体指针变量我们前面定义了指针指向了数组,解决了数组引用传递的问题。那么指针是否可以指向结构体,也能够解决结构体引用传递的问题呢?完全可以。\ 下面我们先来看一下,结构体指针变量的定义:\\ 也

jquery如何判断对象是否获取焦点?

jquery如何判断对象是否获取焦点?jquery判断对象获取焦点可以使用$(selector).is(":focus")。当对象具有焦点时返回为true,否则返回为false。语法:$(select

03.4. Go 的 http 包详解

前面小节介绍了Go怎么样实现了Web工作模式的一个流程,这一小节,我们将详细地解剖一下http包,看它到底是怎样实现整个过程的。 Go的http有两个核心功能:Conn、ServeMux Conn的g

详解 PHP 中的三大经典模式

单例模式 单例模式的含义:作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统全局地提供这个实例。它不会创建实例副本,而是会向单例类内部存储的实例返回一个引用。单例模式的三

详解 PHP 中的三大经典模式

单例模式 单例模式的含义:作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统全局地提供这个实例。它不会创建实例副本,而是会向单例类内部存储的实例返回一个引用。单例模式的三

详解 PHP 反射的基本使用

PHP反射 今天我要给大家讲解的是PHP当中使用非常普遍的高级操作:反射。反射在当今几乎所有的PHP框架或者工具中都占用非常重要的角色,就比如Laravel的容器,容器对于Laravel架构来说极其重

Redis为什么是单线程、及高并发快的3大原因详解

Redis的高并发和快速原因 1.redis是基于内存的,内存的读写速度非常快; 2.redis是单线程的,省去了很多上下文切换线程的时间; 3.redis使用多路复用技术,可以处理并发的连接。非阻塞

Swoft2 配置详解

Swoft2配置详解更多资料请关注swoft系列教程、小白系列教程定期连载基本功能介绍 配置项是只读的,不能动态修改.所以不要尝试着动态修改配置 Swoft2的配置分为两类,环境配置和应用配置。 en

详解 varint 编码原理

什么是Varint编码Varint是一种使用一个或多个字节序列化整数的方法,会把整数编码为变长字节。对于32位整型数据经过Varint编码后需要1~5个字节,小的数字使用1个byte,大的数字使用5个

万字详解Oracle架构、原理、进程,学会世间再无复杂架构

学习是一个循序渐进的过程,从面到点、从宏观到微观,逐步渗透,各个击破,对于Oracle, 怎么样从宏观上来理解呢?先来看一个图,这个图取自于教材,这个图对于从整体上理解ORACLE 的体系结构组件,非

详解 | 阿里怎么做双11全链路压测?

导读:全链路压测是阿里的首创,本文将从工作内容、操作过程、运行总结等多个方向来介绍下阿里内部典型电商活动(如双11准备),以给大家展示一个完整的压测流程,帮助更多的企业和用户更好的完成性能测试。前言关

详解数据服务共享发布

引言:随着云计算、大数据、物联网等技术兴起,数据朝着多样性、高体量、高速度方向发展,如何将海量数据安全、稳定、高效地数据共享出去成为各企业关注的重点。本次微课堂通过普元在数据服务共享平台研发过程中的实

数据库大牛李海翔详解全局读一致性技术

作者简介:李海翔,网名“那海蓝蓝”,腾讯金融云数据库技术专家。中国人民大学信息学院工程硕士企业导师。著有《数据库事务处理的艺术:事务管理和并发访问控制》、《数据库查询优化器的艺术:原理解析与SQL性能

共享内存在不同系统的应用与优劣详解

共享内存是一种使计算机程序能够同时共享内存资源以实现更高性能和更少冗余数据副本的技术。共享系统内存可以在单处理器系统、并行多处理器或集群微处理器上运行。对于分布式系统会有一些差异,但共享内存也可以其上

Oracle数据库不同损坏级别的恢复详解

墨墨导读:在DBA的日常工作中不可避免存在着数据库的损坏,本文将主要介绍Oracle数据库遇到不同损坏级别下的应该采用的恢复方法,供读者在遇到此类情景时,能的找到适合自己的恢复方法,提高工作效率。数据