Shell编程入门学习笔记之shell变量

时间:2023-01-03 11:59:16


shell简介

Shell本身是一个用C语言编写的程序,它是用户使用Unix/Linux的桥梁,用户的大部分工作都是通过Shell完成的。

他不是Unix/Linux系统内核的一部分,但是他调用了系统核心的大部分功能来执行程序、建立文件并以并行的方式协调各个程序的运行。因此,对于用户来说,shell是最重要的实用程序。

可以说,shell使用的熟练程度反映了用户对Unix/Linux使用的熟练程度。

Shell的两种执行命令的方式:
  • 交互式:解释执行用户的命令,用户输入一条命令,Shell就解释执行一条。
  • 批处理:用户事先写一个Shell脚本(Script),其中有很多条命令,让Shell一次把这些命令执行完,而不必一条一条地敲命令。

Shell脚本和编程语言很相似,也有变量和流程控制语句,但Shell脚本是解释执行的,不需要编译,Shell程序从脚本中一行一行读取并执行这些命令,相当于一个用户把脚本中的命令一行一行敲到Shell提示符下执行。

几种常见的Shell

Shell是一种脚本语言,就必须有解释器来执行这些脚本。

​Unix/Linux​​​上常见的Shell脚本编译器有​​bash​​​、​​sh​​​、​​csh​​​、​​ksh​​等,习惯上把它们称为一种Shell。我们常说有多少种Shell,其实说的是Shell脚本解释器。

​bash​​:是Linux标准默认的shell,内部命令一共有40种。

​sh​​:是Unix标准默认的shell。(bash完全兼容sh,所以用sh写的脚本可以不加修改的在bahs中执行)。

​ash​​:是Linux中占用系统资源最少的一个shell,只包含24个内部命令,因而使用起来不方便。

​csh​​:是Linux比较大的内核,共有52个内部命令。


第一个Shell脚本
#!/bin/bash
echo "Hello World !"

​#!​​是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种Shell。

运行Shell脚本有两种方法
1、作为可执行程序

将上边的代码保存为​​test.sh​​​,并​​cd​​到相应目录:

chmod +x ./test.sh #给该脚本增加可执行的权限
./test.sh # 执行脚本

注意:通过这种方式运行bash脚本,第一行一定要写对,好让系统查找到正确的解释器。

2、作为解释器参数
/bin/sh test.sh
/bin/php test.php

这种方式运行的脚本,不需要在第一行指定解释器信息,写了也没用。


#!/bin/bash
# Author : JonnyYue
echo "What is your name?"
read PERSON
echo "Hello ,$PERSON"
chmod +x ./test.sh
$./test.sh
输出:
What is your name?
mozhiyan
Hello, mozhiyan
Shell变量
定义变量

定义变量时,变量名不加美元符号。
​​​变量名 = “value”​

注意:变量名和等号之间不能有空格。

变量名的命名规则遵循如下规则:

  • 首个字母必须有字母(a-z、A-Z)
  • 中间不能有空格,可以使用下划线(_)
  • 不能使用标点符号。
  • 不能使用​​bash​​里的关键字
使用变量

使用一个已经定义过的变量,只需要在变量名前面加上美元符号$就可以了。

a="hello"
echo $a
echo ${a}

变量名后面的​​{}​​是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界,比如下面这种情况:

​${name}is a boy​​如果不给name加上花括号,解释器就会把nameis 当作一个变量。

重新定义变量

已定义的变量,可以被重新定义。

your_name="tom"
echo $your_name
your_name="alibaba" #不能加$
echo $your_name
只读变量
#!/bin/bash
myUrl="http://www.google.com"
readonly myUrl
删除变量

​unset variable_name​

变量被删除后不能再次使用。unset 命令不能删除只读变量。

变量类型

有三种类型:

  • 局部变量
  • 仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量
  • 环境变量
  • 所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。
  • shell变量
  • shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行。
特殊变量

变量

含义

​$0​

当前脚本的文件名

​$n​

传递给脚本或函数的参数。n是一个数字,表示第几个参数。

​$#​

传递给脚本或函数的参数个数

​$*​

传递给脚本或函数的所有参数

​$@​

传递给脚本或函数的所有参数

​$?​

上个命令的退出状态,或函数的返回值。

​$$​

当前Shell进程的ID。对于Shell脚本,就是这些脚本所在的进程ID

命令行参数

运行脚本时传递给脚本的参数称为命令行参数。

#!/bin/bash
echo "File Name: $0"
echo "First Parameter : $1"
echo "First Parameter : $2"
echo "Quoted Values: $@"
echo "Quoted Values: $*"
echo "Total Number of Parameters : $#"

运行结果:

$./test.sh Zara Ali
File Name : ./test.sh
First Parameter : Zara
Second Parameter : Ali
Quoted Values: Zara Ali
Quoted Values: Zara Ali
Total Number of Parameters : 2
*和@的区别

​∗​​​和​​@​​​ 都表示传递给函数或脚本的所有参数,不被双引号(" “)包含时,都以"1"“2” … “$n” 的形式输出所有参数。
  但是当它们被双引号(” ")包含时,“∗"会将所有的参数作为一个整体,以"1 2…n"的形式输出所有参数;”@“会将各个参数分开,以"1” “2”…“n” 的形式输出所有参数。
  下面的例子可以清楚的看到 ∗和@ 的区别:

#!/bin/bash
echo "\$*=" $*
echo "\"\$*\"=" "$*"
echo "\$@=" $@
echo "\"\$@\"=" "$@"
echo "print each param from \$*"
for var in $*
do
echo "$var"
done
echo "print each param from \$@"
for var in $@
do
echo "$var"
done
echo "print each param from \"\$*\""
for var in "$*"
do
echo "$var"
done
echo "print each param from \"\$@\""
for var in "$@"
do
echo "$var"

执行 ​​./test.sh "a" "b" "c" "d"​​,看到下面的结果::

$*=  a b c d
"$*"= a b c d
$@= a b c d
"$@"= a b c d
print each param from $*
a
b
c
d
print each param from $@
a
b
c
d
print each param from "$*"
a b c d
print each param from "$@"
a
b
c
d
退出状态

​$?​​ 可以获取上一个命令的退出状态。所谓退出状态,就是上一个命令执行后的返回结果。

退出状态是一个数字,一般情况下,大部分命令执行成功会返回 0,失败返回 1。

Shell 替换

如果表达式中包含特殊字符,Shell将会进行替换。比如转义字符

下面的转义字符都可以用在​​echo​​中:

转义字符

含义

​\\​

反斜杠

​\a​

警报,响铃

​\b​

退格(删除键)

​\f​

换页(FF),将当前位置移到下页开头

​\n​

换行

​\r​

回车

​\t​

水平制表符(tab键)

​\v​

垂直制表符

可以使用​​echo -e​​来禁止转义,默认也是不转义的。

命令替换

命令替换是指Shell可以先执行命令,将输出结果暂时保存,在适当的地方输出。

命令替换的语法:

`command` # 注意是反引号,而不是单引号。
#!/bin/bash
DATE=`date`
echo "Date is $DATE"
USERS=`who | wc -l`
echo "Logged in user are $USERS"
UP=`date ; uptime`
echo "Uptime is $UP"

运行结果:

Date is Thu Jul  2 03:59:57 MST 2009
Logged in user are 1
Uptime is Thu Jul 2 03:59:57 MST 2009
03:59:57 up 20 days, 14:03, 1 user, load avg: 0.13, 0.07, 0.15
变量替换

变量替换可以根据变量的状态(是否为空、是否定义等)来改变它的值。

可以使用的变量替换形式:

形式

说明

​${var}​

变量本来的值

​${var:-word}​

如果变量 var 为空或已被删除(unset),那么返回 word,但不改变 var 的值。

​${var:=word}​

如果变量 var 为空或已被删除(unset),那么返回 word,并将 var 的值设置为 word。

​${var:?message}​

如果变量 var 为空或已被删除(unset),那么将消息 message 送到标准错误输出,可以用来检测变量 var 是否可以被正常赋值。

若此替换出现在Shell脚本中,那么脚本将停止运行。

​${var:+word}​

如果变量 var 被定义,那么返回 word,但不改变 var 的值。

#!/bin/bash

echo ${var:-"Variable is not set"}
echo "1 - Value of var is ${var}"

echo ${var:="Variable is not set"}
echo "2 - Value of var is ${var}"

unset var
echo ${var:+"This is default value"}
echo "3 - Value of var is $var"

var="Prefix"
echo ${var:+"This is default value"}
echo "4 - Value of var is $var"

echo ${var:?"Print this message"}
echo "5 - Value of var is ${var}"

运行结果:

Variable is not set
1 - Value of var is
Variable is not set
2 - Value of var is Variable is not set
3 - Value of var is
This is default value
4 - Value of var is Prefix
Prefix
5 - Value of var is Prefix
参考自: