Shell知识点(二)引号,转义,变量

1.转义

某些字符在 Bash 里面有特殊含义(比如$&*)。

$ echo $date

$

输出$date不会有任何结果,因为$是一个特殊字符

如果想要原样输出这些特殊字符,就必须在他们前面加上反斜杠,使其变成普通字符

$ echo \$date
$date

 如果想要在命令行使用这些不可打印的字符,可以把它们放在引号里面,然后使用echo命令的-e参数。

$ echo a\tb
atb

$ echo -e "a\tb"
a        b

 换行符是一个特殊字符,表示命令的结束,Bash 收到这个字符以后,就会对输入的命令进行解释执行。换行符前面加上反斜杠转义,就使得换行符变成一个普通字符,Bash 会将其当作长度为0的空字符处理,从而可以将一行命令写成多行。

2.单引号

Bash 允许字符串放在单引号或双引号之中,加以引用。

单引号用于保留字符的字面含义,各种特殊字符在单引号里面,都会变为普通字符,比如星号(*)、美元符号($)、反斜杠(\)等。

$ echo '*'
*

$ echo '$USER'
$USER

$ echo '$((2+2))'
$((2+2))

$ echo '$(echo foo)'
$(echo foo)

 由于反斜杠在单引号里面变成了普通字符,所以如果单引号之中,还要使用单引号,不能使用转义,需要在外层的单引号前面加上一个美元符号($),然后再对里层的单引号转义。

$ echo it's

# 不正确
$ echo 'it\'s'

# 正确
$ echo $'it\'s'

不过,更合理的方法是改在双引号之中使用单引号。

$ echo "it's"
it's

3.双引号 

通配符*是一个特殊字符,放在双引号之中就变成了一个普通字符,会原样输出,这一点是特别留意,双引号里面不会进行文件名扩展

但是 三个特殊字符除外 美元符号($)、反引号(`)和反斜杠(\)。这三个字符在双引号之中,依然有特殊含义,会被 Bash 自动扩展。

$ echo "$SHELL"
/bin/bash

$ echo "`date`"
Mon Jan 27 13:33:18 CST 2020

 上面例子中,美元符号($)和反引号(`)在双引号中,都保持特殊含义。美元符号用来引用变量,反引号则是执行子命令。

换行符在双引号之中,会失去特殊含义,Bash 不再将其解释为命令的结束,只是作为普通的换行符。所以可以利用双引号,在命令行输入多行文本。

4.Here文档

here文档是一种输入多行字符串得方法

<< token
text
token

它的格式分成开始标记(<< token)和结束标记(token)。开始标记是两个小于号 + Here 文档的名称,名称可以随意取,后面必须是一个换行符;结束标记是单独一行顶格写的 Here 文档名称,如果不是顶格,结束标记不起作用。两者之间就是多行字符串的内容。

下面是一个通过 Here 文档输出 HTML 代码的例子。

$ cat << _EOF_
<html>
<head>
    <title>
    The title of your page
    </title>
</head>

<body>
    Your page content goes here.
</body>
</html>
_EOF_

Here 文档内部会发生变量替换,同时支持反斜杠转义,但是不支持通配符扩展,双引号和单引号也失去语法作用,变成了普通字符。

5.变量 

 分为环境变量和自定义变量两类

环境变量是Bash环境自带得变量,进入Shell时已经定义好了可以直接使用,通常时系统定义好得,也可以从父Shell传入子Shell

env命令可以显示所有环境变量

常用环境变量

  • BASHPID:Bash 进程的进程 ID。
  • BASHOPTS:当前 Shell 的参数,可以用shopt命令修改。
  • DISPLAY:图形环境的显示器名字,通常是:0,表示 X Server 的第一个显示器。
  • EDITOR:默认的文本编辑器。
  • HOME:用户的主目录。
  • HOST:当前主机的名称。
  • IFS:词与词之间的分隔符,默认为空格。
  • LANG:字符集以及语言编码,比如zh_CN.UTF-8
  • PATH:由冒号分开的目录列表,当输入可执行程序名后,会搜索这个目录列表。
  • PS1:Shell 提示符。
  • PS2: 输入多行命令时,次要的 Shell 提示符。
  • PWD:当前工作目录。
  • RANDOM:返回一个0到32767之间的随机数。
  • SHELL:Shell 的名字。
  • SHELLOPTS:启动当前 Shell 的set命令的参数,参见《set 命令》一章。
  • TERM:终端类型名,即终端仿真器所用的协议。
  • UID:当前用户的 ID 编号。
  • USER:当前用户的用户名。

Bash变量是区分大小写得,HOME 和 Home是两个不同得变量

1.自定义变量

        set命令可以显示所有变量 以及所有Bash函数

2.创建变量

        规则:

        1.字母,数字瞎花钱组成

        2.第一个字符必须是一个字母或者下划线 不能是数字

       3.不允许出现空格和标点符号

3.声明变量

variable=value

如果包含空格必须放在双引号中

变量可以重复赋值 第二次赋值会覆盖第一次赋值

如果同一行定义多个变量,必须使用分号分隔

4.读取变量

读取变量得时候 直接在变量名前加上$就可以了

由于$在Bash中有特殊含义,把他当作美元符号使用得时候一定特别小心

需要使用(\)进行转义

读取变量得时候,变量名也可以使用{}包围,比如$a也可以写成${a},这种写法可以用于变量名与其它字符串连用得情况。

如果变量的值本身也是变量,可以使用${!varname}的语法,读取最终的值。

5.删除变量 unset命令用来删除一个变量

这个命令不是很有用。因为不存在的 Bash 变量一律等于空字符串,所以即使unset命令删除了变量,还是可以读取这个变量,值为空字符串。

所以,删除一个变量,也可以将这个变量设成空字符串。

5.输出变量 export命令

        用户创建得变量仅可用于当前Shell 子Shell默认读取不到父Shell定义得变量,为了把变量传递给子Shell,需要使用export命令,这样输出得变量,对于子Shell来说就是环境变量

子 Shell 修改了继承的变量$foo,对父 Shell 没有影响。

6.特殊变量

Bash 提供一些特殊变量。这些变量的值由 Shell 提供,用户不能进行赋值。

(1)$?

$?为上一个命令的退出码,用来判断上一个命令是否执行成功。返回值是0,表示上一个命令执行成功;如果不是零,表示上一个命令执行失败。

$ ls doesnotexist
ls: doesnotexist: No such file or directory

$ echo $?
1

上面例子中,ls命令查看一个不存在的文件,导致报错。$?为1,表示上一个命令执行失败。 

(2)$$

$$为当前 Shell 的进程 ID。

这个特殊变量可以用来命名临时文件。

(3)$_

$_为上一个命令的最后一个参数。

(4)$!

$!为最近一个后台执行的异步命令的进程 ID。

$ firefox &
[1] 11064

$ echo $!
11064

 上面例子中,firefox是后台运行的命令,$!返回该命令的进程 ID。

(5)$0

$0为当前 Shell 的名称(在命令行直接执行时)或者脚本名(在脚本中执行时)。

(6)$-

$-为当前 Shell 的启动参数。

(7)$@$#

$#表示脚本的参数数量,$@表示脚本的参数值,参见脚本一章。

7.变量得默认值

Bash 提供四个特殊语法,跟变量的默认值有关,目的是保证变量不为空。

${varname:-word}

上面语法的含义是,如果变量varname存在且不为空,则返回它的值,否则返回word。它的目的是返回一个默认值,比如${count:-0}表示变量count不存在时返回0

${varname:=word}

上面语法的含义是,如果变量varname存在且不为空,则返回它的值,否则将它设为word,并且返回word。它的目的是设置变量的默认值,比如${count:=0}表示变量count不存在时返回0,且将count设为0

${varname:+word}

上面语法的含义是,如果变量名存在且不为空,则返回word,否则返回空值。它的目的是测试变量是否存在,比如${count:+1}表示变量count存在时返回1(表示true),否则返回空值。

${varname:?message}

上面语法的含义是,如果变量varname存在且不为空,则返回它的值,否则打印出varname: message,并中断脚本的执行。如果省略了message,则输出默认的信息“parameter null or not set.”。它的目的是防止变量未定义,比如${count:?"undefined!"}表示变量count未定义时就中断执行,抛出错误,返回给定的报错信息undefined!

上面四种语法如果用在脚本中,变量名的部分可以用数字19,表示脚本的参数。

filename=${1:?"filename missing."}

上面代码出现在脚本中,1表示脚本的第一个参数。如果该参数不存在,就退出脚本并报错。

8.declare命令

declare命令可以声明一些特殊类型的变量,为变量设置一些限制,比如声明只读类型的变量和整数类型的变量。

它的语法形式如下。

declare OPTION VARIABLE=value

declare命令的主要参数(OPTION)如下。

  • -a:声明数组变量。
  • -f:输出所有函数定义。
  • -F:输出所有函数名。
  • -i:声明整数变量。
  • -l:声明变量为小写字母。
  • -p:查看变量信息。
  • -r:声明只读变量。
  • -u:声明变量为大写字母。
  • -x:该变量输出为环境变量。

declare命令如果用在函数中,声明的变量只在函数内部有效,等同于local命令。

不带任何参数时,declare命令输出当前环境的所有变量,包括函数在内,等同于不带有任何参数的set命令。

$ declare

(1)-i参数

-i参数声明整数变量以后,可以直接进行数学运算。

$ declare -i val1=12 val2=5
$ declare -i result
$ result=val1*val2
$ echo $result
60

上面例子中,如果变量result不声明为整数,val1*val2会被当作字面量,不会进行整数运算。另外,val1val2其实不需要声明为整数,因为只要result声明为整数,它的赋值就会自动解释为整数运算。

注意,一个变量声明为整数以后,依然可以被改写为字符串。

$ declare -i var=12
$ var=foo
$ echo $var
0

上面例子中,变量var声明为整数,覆盖以后,Bash 不会报错,但会赋以不确定的值,上面的例子中可能输出0,也可能输出的是3。

(2)-x参数

-x参数等同于export命令,可以输出一个变量为子 Shell 的环境变量。

$ declare -x foo
# 等同于
$ export foo

(3)-r参数

-r参数可以声明只读变量,无法改变变量值,也不能unset变量。

$ declare -r bar=1

$ bar=2
bash: bar:只读变量
$ echo $?
1

$ unset bar
bash: bar:只读变量
$ echo $?
1

上面例子中,后两个赋值语句都会报错,命令执行失败。

(4)-u参数

-u参数声明变量为大写字母,可以自动把变量值转成大写字母。

$ declare -u foo
$ foo=upper
$ echo $foo
UPPER

(5)-l参数

-l参数声明变量为小写字母,可以自动把变量值转成小写字母。

$ declare -l bar
$ bar=LOWER
$ echo $bar
lower

(6)-p参数

-p参数输出变量信息。

$ foo=hello
$ declare -p foo
declare -- foo="hello"
$ declare -p bar
bar:未找到

上面例子中,declare -p可以输出已定义变量的值,对于未定义的变量,会提示找不到。

如果不提供变量名,declare -p输出所有变量的信息。

$ declare -p

(7)-f参数

-f参数输出当前环境的所有函数,包括它的定义。

$ declare -f

(8)-F参数

-F参数输出当前环境的所有函数名,不包含函数定义。

$ declare -F

 9.readonly命令

readonly命令等同于declare -r,用来声明只读变量,不能改变变量值,也不能unset变量。

$ readonly foo=1
$ foo=2
bash: foo:只读变量
$ echo $?
1

上面例子中,更改只读变量foo会报错,命令执行失败。

readonly命令有三个参数。

  • -f:声明的变量为函数名。
  • -p:打印出所有的只读变量。
  • -a:声明的变量为数组。

10.let命令

let命令声明变量时,可以直接执行算术表达式。

$ let foo=1+2
$ echo $foo
3

上面例子中,let命令可以直接计算1 + 2

let命令的参数表达式如果包含空格,就需要使用引号。

$ let "foo = 1 + 2"

let可以同时对多个变量赋值,赋值表达式之间使用空格分隔。

$ let "v1 = 1" "v2 = v1++"
$ echo $v1,$v2
2,1

上面例子中,let声明了两个变量v1v2,其中v2等于v1++,表示先返回v1的值,然后v1自增。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值