二、变量

1、Shell变量

变量是暂时存储数据的地方,所存储的数据存在于内存空间中,通过调用内存空间中变量的名字取出与变量对应的数据

  • 变量是 shell 传递数据的一种方法,可以理解为存储数据的容器。
  • 每一个变量的值都是字符串,无论你给变量赋值时有没有使用引号,值都会以字符串的形式存储。

Shell 变量的命名规范:

  • 变量名由数字、字母、下划线 _ 组成。区分大小写,必须以字母或者下划线开头(不能以数字开头);
  • 不能使用 Shell 里的关键字(通过 help 命令可以查看保留关键字)。

变量类型:

在 Bash 中,Bash 变量没有类型,变量值以字符串形式存储,但在算术上下文中会被自动解释为数字。即 Shell 会尝试将字符串解析为数字。

 如:

1. 赋值时是否加引号,不影响“字符串”本质

a=123        // 没加引号
b="123"      // 加了双引号
c='123'      // 加了单引号
echo "$a $b $c"  // 输出:123 123 123

三者在内存中都是字符串 "123",没有区别。

2. 字符串可以用于算术运算(Shell 会自动转换)

x=10
y=20
sum=$((x + y))   // Shell 将 "10" 和 "20" 当作数字处理
echo $sum        // 输出:30

((...)) 或 $((...)) 是算术扩展,此时 Shell 会忽略字符串属性,按数字解析。

3. 如果字符串不是纯数字,会发生什么?

a="10"
b="20abc"
c="hello"
echo $((a + b))   // 输出:30(b 被截断为 20)
echo $((a + c))  // 输出:10(c 被当作 0)

Shell 在算术上下文中会尽力解析数字,失败则视为 0,不会报错!

2、定义变量

 Shell 支持以下三种定义变量的方式:

variable=value
variable='value'
variable="value"
  • variable 是变量名,value 是赋给变量的值。
  • 等号为变量赋值,等号两边不能有空格

使用引号的情况:

  •  value 不包含任何空白符(例如空格、Tab 缩进等)时,可以不使用引号;如果 value 包含了空格,那么就必须使用引号包围起来
  • 单引号' '包围变量的值时,单引号里面是什么就输出什么(原样输出),即使内容中有变量和命令(命令需要反引起来)也会把它们原样输出。
  • 双引号" "包围变量的值时,输出时会先解析里面的变量和命令,而不是把双引号中的变量名和命令原样输出。
#!/bin/bash

echo "hello world !"

#-----
url="http://c.biancheng.net"
website1='C语言中文网:${url}'
website2="C语言中文网:${url}"
echo $website1
echo $website2

#运行结果
[root@localhost ~]# ./1.sh
hello world !
C语言中文网:${url}
C语言中文网:http://c.biancheng.net

二、使用变量,获取变量值

使用一个定义过的变量,只要在变量名前面加美元符号 即可,如:

[root@localhost ~]# a=12;b=12
[root@localhost ~]# echo $a
12
[root@localhost ~]# b='dasd'
[root@localhost ~]# echo $bc                         #解释器就会把 $bc 当成一个变量(其值为空)
 
[root@localhost ~]# echo ${b}c                       #解释器把 $b 看成变量
dasdc

变量名外面的花括号{ }是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界,使用 ${} 明确边界。

三、命令替换

一个命令的输出结果,作为另一个命令的参数或赋值给变量

换句话说,Shell 会先执行括号内的命令,然后用它的标准输出(stdout)替换整个表达式。

工作原理,Shell 执行以下步骤:

(1)词法分析,识别命令替换结构

  • 遇到 $(,识别出这是一个命令替换表达式。它会寻找与之匹配的 )(支持嵌套,如 $(echo $(whoami)))。
  • 提取出内部命令:command
  • 此时 不会立即执行 command,只是识别语法结构。

(2)在子 Shell 中执行内部命令

Shell 创建一个子进程(subshell)来运行 command

  • 子 Shell 继承父 Shell 的环境(如 PATH、当前目录等),但对变量的修改不会影响父 Shell。
  • 命令的标准输出(stdout)被捕获;
  • 标准错误(stderr)默认仍输出到终端(除非重定向)。

(3)捕获并处理输出

  • Shell 收集子 Shell 的 stdout 内容(不包括 stderr)。
  • 自动删除输出末尾的所有换行符(trailing newlines)。
    • 例如:$(echo "hello\n\n") → 实际替换为 "hello"(两个 \n 都被删)。
  • 其他空白字符(如空格、制表符、中间换行)保留不变。

(4)用输出结果替换原 $(command) 表达式

将捕获到的字符串(如 "16:45")原样替换 $(command) 的位置。

(5)替换完成后,Shell 继续对整行解析:

  • 变量展开(如果还有其他 $var
  • 单词分割(word splitting)
  • 路径名扩展(globbing,如 *?
  • 引用处理(引号规则)

命令替换的结果默认会参与单词分割和通配符扩展,除非用双引号包裹!

命令替换的两种方式:

variable=`command`         //反引号` ` 把命令包围起来;

variable=$(command)          //$() 把命令包围起来,推荐使用这种方式。

如:

files=$(echo "a b c")
echo $files     // → a b c(三个参数,因空格被分割)
echo "$files"  // → a b c(一个参数,保留空格)

四、变量删除

unset 命令可以删除变量。

语法:  

 unset  变量名

注 unset 命令不能删除只读变量。

只读变量用readonly定义,只读变量的值不能被改变。

#!/bin/bash
myUrl="http://c.biancheng.net/shell/"
readonly myUrl
myUrl="http://c.biancheng.net/shell/"

#运行结果
bash: myUrl: This variable is read only.

 

关键点说明
变量名 不能以数字开头,可用字母、数字、下划线
赋值 var=value(等号两边无空格)
引用 $var 或 ${var}
字符串含空格 必须用 ' ' 或 " " 包裹
拼接 用双引号包裹变量,如 "$a $b"

  

posted @ 2021-11-10 08:41  chao_xiong  阅读(0)  评论(0)    收藏  举报