Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to understand $() and ${} in shell

2025-01-30 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >

Share

Shulou(Shulou.com)06/01 Report--

本篇文章为大家展示了如何理解shell中$()与${},内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

$( )与` `(反引号)

在bash shell中,$( )与` `(反引号)都是用来做命令替换(command substitution)用的。

$ echo the last sunday is $(date -d "last sunday" +%Y-%m-%d)

得到上一星期天的日期

用$( )的理由

1. ` `很容易与' '(单引号)搞混。有时在一些奇怪的字形显示中,两种符号是一模一样的(直竖两点)。

2. 在多层次的复合替换中,` `须要额外的跳脱(\`)处理,而$( )则比较直观。例如:

command1 `command2 `command3` `

原本的意图是在command2 `command3`中先将command3替换出来给command2处理,然后再将结果传给command1 `command2 ...`来处理。

然而,真正的结果在命令行中却是分成了`command2`与` `两段。

正确的输入应该如下:

command1 `command2 \`command3\` `

换成$( )则一目了然:

command1 $(command2 $(command3))

$( )的不足

` `基本上可在全部的unix shell中使用,若写成shell script移植性比较高。而$( )并不是每一种shell都能使用。

${ }用来作变量替换

一般情况下,$var与${var}作用相同。但是用${ }会比较精确的界定变量名称的范围,例如:

$ A=B

$ echo $AB

原本是打算先将$A的结果替换出来,然后再补一个B字母于其后,但在命令行上,真正的结果却是只会替换变量名称为AB的值出来。

使用${ }就没问题了:

$ echo ${A}B

BB

${ }的一些特异功能

定义一个变量:

file=/dir1/dir2/dir3/my.file.txt

可以用${ }分别替换获得不同的值:

${file#*/} 拿掉第一个 / 及其左边的字符串:dir1/dir2/dir3/my.file.txt

${file##*/} 拿掉最后一个 / 及其左边的字符串:my.file.txt

${file#*.} 拿掉第一个 . 及其左边的字符串:file.txt

${file##*.} 拿掉最后一个 . 及其左边的字符串:txt

${file%/*} 拿掉最后一个 / 及其右边的字符串:/dir1/dir2/dir3

${file%%/*} 拿掉第一个 / 及其右边的字符串:(空值)

${file%.*} 拿掉最后一个 . 及其右边的字符串:/dir1/dir2/dir3/my.file

${file%%.*} 拿掉第一个 . 及其右边的字符串:/dir1/dir2/dir3/my

记忆的方法:

# 去掉左边(键盘上 # 在 $ 的左边)

% 去掉右边(在键盘上 % 在 $ 的右边)

单一符号是最小匹配,两个符号是最大匹配。

${file:0:5} 提取最左边的 5 个字节:/dir1

${file:5:5} 提取第 5 个字节右边的连续 5 个字节:/dir2

也可以对变量值里的字符串作替换:

${file/dir/path} 将第一个 dir 替换为 path:/path2/dir2/dir3/my.file.txt

${file//dir/path} 将全部 dir 替换为 path:/path2/path3/path4/my.file.txt

利用${ }还可针对不同的变量状态赋值(未设定、空值、非空值):

${file-my.file.txt} 若 $file 未设定,则使用 my.file.txt 作传回值。(空值及非空值时不作处理)

${file:-my.file.txt} 若 $file 未设定或为空值,则使用 my.file.txt 作传回值。(非空值时不作处理)

${file+my.file.txt} 若 $file 设为空值或非空值,均使用 my.file.txt 作传回值。(未设定时不作处理)

${file:+my.file.txt} 若 $file 为非空值,则使用 my.file.txt 作传回值。(未设定及空值时不作处理)

${file=my.file.txt} 若 $file 未设定,则使用 my.file.txt 作传回值,同时将 $file 赋值为 my.file.txt。 (空值及非空值时不作处理)

${file:=my.file.txt} 若 $file 未设定或为空值,则使用 my.file.txt 作传回值,同时将 $file 赋值为 my.file.txt。 (非空值时不作处理)

${file?my.file.txt} :若 $file 未设定,则将 my.file.txt 输出至 STDERR。(空值及非空值时不作处理)

${file:?my.file.txt} :若 $file 未设定或为空值,则将 my.file.txt 输出至 STDERR。(非空值时不作处理)

以上的理解在于,一定要分清楚 unset 与 null 及 non-null 这三种赋值状态。

一般而言,与 null 有关,若不带 : 的话,null 不受影响,若带 : 则连 null 也受影响。

${#var} 可计算出变量值的长度:

${#file} 可得到 27,/dir1/dir2/dir3/my.file.txt 刚好是 27 个字节。

bash数组(array)处理方法

一般而言,A="a b c def"只是将 $A 替换为一个单一的字符串,但是改为 A=(a b c def),则是将 $A 定义为数组。

bash的数组替换方法可参考如下方法:

${A[@]} 或 ${A[*]} 得到 a b c def(全部数组)

${A[0]} 得到 a (第一个元素),${A[1]} 第二个...

${#A[@]} 或 ${#A[*]} 得到 4 (数组数量)

${#A[0]} 得到 1 (第一个元素 a 的长度),${#A[3]} 得到 3 (第四个元素 def 的长度)

A[3]=xyz 将第四个元素重新定义为 xyz

$(( ))的用途

用来作整数运算。在 bash 中,$(( ))的整数运算符号大致有这些:

+ - * / 加、减、乘、除

% 余数运算

& | ^ ! AND、OR、XOR、NOT运算

举例:

$ a=5; b=7; c=2

$ echo $((a+b*c))

19

$ echo $(((a+b)/c))

6

$ echo $(((a*b)%c))

1

在$(( ))中的变量名称也可以在其前面加 $ 符号:$(($a+$b*$c))也可以得到 19 的结果。

此外,$(( ))还可以作不同进制(如二进制、八进位、十六进制)运算,只是输出结果皆为十进制而已。

echo $((16#2a)) 结果为 42 (16进位转十进制)

举一个实用的例子:

当前的 umask 是 022,新建文件的权限为:

$ umask 022

$ echo "obase=8; $(( 8#666 & (8#777 ^ 8#$(umask)) ))" | bc

644

事实上,单纯用(( ))也可以重定义变量值,或作testing:

a=5; ((a++)) 将 $a 重定义为 6

a=5; ((a-)) a=4

a=5; b=7; ((a

< b)) 会得到 0 (true) 的返回值 常见的用于(( ))的测试符号有以下这些: < 小于 >

greater than

= greater than or equal to

== equals

!= not equal to

That's how to understand $() and ${} in shell. Have you learned any knowledge or skills? If you want to learn more skills or enrich your knowledge reserves, please pay attention to the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Servers

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report