「Linux」Linux Shell 编程基础入门

本文介绍了 Linux Shell 编程的基础知识,涵盖变量定义与使用、字符串操作、数组处理及各类运算符等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 变量

1.1 变量定义

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

variable=value
variable='value'
variable="value"

variable 是变量名,value 是赋给变量的值。如果 value 不包含任何空白符(例如空格、Tab 缩进等),那么可以不使用引号;如果 value 包含了空白符,那么就必须使用引号包围起来。

注意:赋值号=的周围不能有空格!

1.2 使用变量

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

project="rfg"
echo $project
echo ${project}

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

1.3 引号

以单引号' '包围变量的值时,单引号里面是什么就输出什么,即使内容中有变量和命令(命令需要反引起来)也会把它们原样输出。这种方式比较适合定义显示纯字符串的情况,即不希望解析变量、命令等的场景。

以双引号" "包围变量的值时,输出时会先解析里面的变量和命令,而不是把双引号中的变量名和命令原样输出。这种方式比较适合字符串中附带有变量和命令并且想将其解析后再输出的变量定义。

1.4 将命令的结果赋值给变量

variable=`command`
variable=$(command)

第一种方式把命令用反引号````(位于 Esc 键的下方)包围起来,反引号和单引号非常相似,容易产生混淆,所以不推荐使用这种方式;第二种方式把命令用$()包围起来,区分更加明显,所以推荐使用这种方式。

`

1.5 位置参数

运行 Shell 脚本文件时我们可以给它传递一些参数,这些参数在脚本文件内部可以使用$n的形式来接收,例如,$1 表示第一个参数,$2 表示第二个参数,依次类推。

同样,在调用函数时也可以传递参数。Shell 函数参数的传递和其它编程语言不同,没有所谓的形参和实参,在定义函数时也不用指明参数的名字和数目。换句话说,定义 Shell 函数时不能带参数,但是在调用函数时却可以传递参数,这些传递进来的参数,在函数内部就也使用$n的形式接收,例如,$1 表示第一个参数,$2 表示第二个参数,依次类推。

这种通过$n的形式来接收的参数,在 Shell 中称为位置参数。

注意:如果参数个数太多,达到或者超过了 10 个,那么就得用${n}的形式来接收了,例如 10 、 {10}、 10{23}。{ }的作用是为了帮助解释器识别参数的边界,这跟使用变量时加{ }是一样的效果。

1.6 特殊变量及其含义

变量含义
$0当前脚本的文件名。
$n(n≥1)传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是 $1,第二个参数是 $2。
$#传递给脚本或函数的参数个数。
$*传递给脚本或函数的所有参数。将所有的参数从整体上看做一份数据。
$@传递给脚本或函数的所有参数。将每个参数都看作一份数据,彼此之间是独立的。
$?上个命令的退出状态,或函数的返回值。
$$当前 Shell 进程 ID。对于 Shell 脚本,就是这些脚本所在的进程 ID。

2. 字符串

2.1 字符串截取

格式说明
${string: start :length}从 string 字符串的左边第 start 个字符开始,向右截取 length 个字符。
${string: start}从 string 字符串的左边第 start 个字符开始截取,直到最后。
${string: 0-start :length}从 string 字符串的右边第 start 个字符开始,向右截取 length 个字符。
${string: 0-start}从 string 字符串的右边第 start 个字符开始截取,直到最后。
${string#*chars}从 string 字符串第一次出现 *chars 的位置开始,截取 *chars 右边的所有字符。
${string##*chars}从 string 字符串最后一次出现 *chars 的位置开始,截取 *chars 右边的所有字符。
${string%*chars}从 string 字符串第一次出现 *chars 的位置开始,截取 *chars 左边的所有字符。
${string%%*chars}从 string 字符串最后一次出现 *chars 的位置开始,截取 *chars 左边的所有字符。

3. 数组

# 定义
array_name=(ele1  ele2  ele3 ... elen)
ages=([3]=24 [5]=19 [10]=12)  # 数组长度还是3

# 获取数组元素
${array_name[index]}
# 获取所有元素
${nums[*]}
${nums[@]}

4. 运算符

原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。

expr 是一款表达式计算工具,使用它能完成表达式的求值操作。

#!/bin/bash

val=`expr 2 + 2`
echo "两数之和为 : $val"

两点注意:

  • 表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2,这与我们熟悉的大多数编程语言不一样。
  • 完整的表达式要被````包含,注意这个字符不是常用的单引号,在 Esc 键下边。

4.1 算术运算符

运算符说明举例
+加法expr $a + $b 结果为 30。
-减法expr $a - $b 结果为 -10。
*乘法expr $a \* $b 结果为 200。
/除法expr $b / $a 结果为 2。
%取余expr $b % $a 结果为 0。
=赋值a=$b 将把变量 b 的值赋给 a。
==相等。用于比较两个数字,相同则返回 true。[ $a == $b ] 返回 false。
!=不相等。用于比较两个数字,不相同则返回 true。[ $a != $b ] 返回 true。

**注意:**条件表达式要放在方括号之间,并且要有空格,例如: [ a = = a== a==b] 是错误的,必须写成 [ $a == $b ]

4.2 关系运算符

关系运算符只支持数字,不支持字符串,除非字符串的值是数字。

下表列出了常用的关系运算符,假定变量 a 为 10,变量 b 为 20:

运算符说明举例
-eq检测两个数是否相等,相等返回 true。[ $a -eq $b ] 返回 false。
-ne检测两个数是否不相等,不相等返回 true。[ $a -ne $b ] 返回 true。
-gt检测左边的数是否大于右边的,如果是,则返回 true。[ $a -gt $b ] 返回 false。
-lt检测左边的数是否小于右边的,如果是,则返回 true。[ $a -lt $b ] 返回 true。
-ge检测左边的数是否大于等于右边的,如果是,则返回 true。[ $a -ge $b ] 返回 false。
-le检测左边的数是否小于等于右边的,如果是,则返回 true。[ $a -le $b ] 返回 true。

4.3 布尔运算符

下表列出了常用的布尔运算符,假定变量 a 为 10,变量 b 为 20:

运算符说明举例
!非运算,表达式为 true 则返回 false,否则返回 true。[ ! false ] 返回 true。
-o或运算,有一个表达式为 true 则返回 true。[ $a -lt 20 -o $b -gt 100 ] 返回 true。
-a与运算,两个表达式都为 true 才返回 true。[ $a -lt 20 -a $b -gt 100 ] 返回 false。

4.4 逻辑运算符

以下介绍 Shell 的逻辑运算符,假定变量 a 为 10,变量 b 为 20:

运算符说明举例
&&逻辑的 AND[[ $a -lt 100 && $b -gt 100 ]] 返回 false
||逻辑的 OR[[ $a -lt 100 || $b -gt 100 ]] 返回 true

4.5 字符串运算符

下表列出了常用的字符串运算符,假定变量 a 为 “abc”,变量 b 为 “efg”:

运算符说明举例
=检测两个字符串是否相等,相等返回 true。[ $a = $b ] 返回 false。
!=检测两个字符串是否相等,不相等返回 true。[ $a != $b ] 返回 true。
-z检测字符串长度是否为0,为0返回 true。[ -z $a ] 返回 false。
-n检测字符串长度是否不为 0,不为 0 返回 true。[ -n “$a” ] 返回 true。
$检测字符串是否为空,不为空返回 true。[ $a ] 返回 true。

4.6 文件测试运算符

文件测试运算符用于检测 Unix 文件的各种属性。

属性检测描述如下:

操作符说明举例
-b file检测文件是否是块设备文件,如果是,则返回 true。[ -b $file ] 返回 false。
-c file检测文件是否是字符设备文件,如果是,则返回 true。[ -c $file ] 返回 false。
-d file检测文件是否是目录,如果是,则返回 true。[ -d $file ] 返回 false。
-f file检测文件是否是普通文件(非目录非备文件),如果是,则返回 true。[ -f $file ] 返回 true。
-g file检测文件是否设置了 SGID 位,如果是,则返回 true。[ -g $file ] 返回 false。
-k file检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。[ -k $file ] 返回 false。
-p file检测文件是否是有名管道,如果是,则返回 true。[ -p $file ] 返回 false。
-u file检测文件是否设置了 SUID 位,如果是,则返回 true。[ -u $file ] 返回 false。
-r file检测文件是否可读,如果是,则返回 true。[ -r $file ] 返回 true。
-w file检测文件是否可写,如果是,则返回 true。[ -w $file ] 返回 true。
-x file检测文件是否可执行,如果是,则返回 true。[ -x $file ] 返回 true。
-s file检测文件是否为空(文件大小是否大于0),不为空返回 true。[ -s $file ] 返回 true。
-e file检测文件(包括目录)是否存在,如果是,则返回 true。[ -e $file ] 返回 true。

其他检查符:

  • -S: 判断某文件是否 socket。
  • -L: 检测文件是否存在并且是一个符号链接。

5. echo命令

Shell 的 echo 指令与 PHP 的 echo 指令类似,都是用于字符串的输出。

5.1 命令格式

echo string

您可以使用echo实现更复杂的输出格式控制。

5.2 基本用法

  1. 显示普通字符串:
echo "It is a test"

这里的双引号完全可以省略,以下命令与上面实例效果一致:

echo It is a test
  1. 显示转义字符
echo "\"It is a test\""

结果将是:

"It is a test"

同样,双引号也可以省略

  1. 显示变量

read 命令从标准输入中读取一行,并把输入行的每个字段的值指定给 shell 变量

#!/bin/sh
read name 
echo "$name It is a test"

以上代码保存为 test.sh,name 接收标准输入的变量,结果将是:

[root@www ~]# sh test.sh
OK                     #标准输入
OK It is a test        #输出
  1. 显示换行
echo -e "OK! \n" # -e 开启转义
echo "It is a test"

输出结果:

OK!

It is a test
  1. 显示不换行
#!/bin/sh
echo -e "OK! \c" # -e 开启转义 \c 不换行
echo "It is a test"

输出结果:

OK! It is a test
  1. 显示结果定向至文件
echo "It is a test" > myfile
  1. 原样输出字符串,不进行转义或取变量(用单引号)
echo '$name\"'

输出结果:

$name\"
  1. 显示命令执行结果
echo `date`

注意: 这里使用的是反引号 `, 而不是单引号 '

结果将显示当前日期

Thu Jul 24 10:08:46 CST 2014

6. awk命令

AWK 是一种处理文本文件的语言,是一个强大的文本分析工具。

之所以叫 AWK 是因为其取了三位创始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的 Family Name 的首字符。

6.1 语法

awk [选项参数] 'script' var=value file(s)
或
awk [选项参数] -f scriptfile var=value file(s)

注:NF表示第几个字段,每个字段默认用空格分开。NF-3的意思是倒数第三个字段。NR 是总共读取了多少行

6.2 选项参数说明

  • -F fs or --field-separator fs
    指定输入文件折分隔符,fs是一个字符串或者是一个正则表达式,如-F:。
  • -v var=value or --asign var=value
    赋值一个用户定义变量。
  • -f scripfile or --file scriptfile
    从脚本文件中读取awk命令。
  • -mf nnn and -mr nnn
    对nnn值设置内在限制,-mf选项限制分配给nnn的最大块数目;-mr选项限制记录的最大数目。这两个功能是Bell实验室版awk的扩展功能,在标准awk中不适用。
  • -W compact or --compat, -W traditional or --traditional
    在兼容模式下运行awk。所以gawk的行为和标准的awk完全一样,所有的awk扩展都被忽略。
  • -W copyleft or --copyleft, -W copyright or --copyright
    打印简短的版权信息。
  • -W help or --help, -W usage or --usage
    打印全部awk选项和每个选项的简短说明。
  • -W lint or --lint
    打印不能向传统unix平台移植的结构的警告。
  • -W lint-old or --lint-old
    打印关于不能向传统unix平台移植的结构的警告。
  • -W posix
    打开兼容模式。但有以下限制,不识别:/x、函数关键字、func、换码序列以及当fs是一个空格时,将新行作为一个域分隔符;操作符=不能代替=;fflush无效。
  • -W re-interval or --re-inerval
    允许间隔正则表达式的使用,参考(grep中的Posix字符类),如括号表达式[[:alpha:]]。
  • -W source program-text or --source program-text
    使用program-text作为源代码,可与-f命令混用。
  • -W version or --version
    打印bug报告信息的版本。

6.3 基本用法

log.txt文本内容如下:

2 this is a test
3 Are you like awk
This's a test
10 There are orange,apple,mongo

用法一:

awk '{[pattern] action}' {filenames}   # 行匹配语句 awk '' 只能用单引号

实例:

# 每行按空格或TAB分割,输出文本中的1、4项
 $ awk '{print $1,$4}' log.txt
 ---------------------------------------------
 2 a
 3 like
 This's
 10 orange,apple,mongo
 # 格式化输出
 $ awk '{printf "%-8s %-10s\n",$1,$4}' log.txt
 ---------------------------------------------
 2        a
 3        like
 This's
 10       orange,apple,mongo

用法二:

awk -F  #-F相当于内置变量FS, 指定分割字符

实例:

# 使用","分割
 $  awk -F, '{print $1,$2}'   log.txt
 ---------------------------------------------
 2 this is a test
 3 Are you like awk
 This's a test
 10 There are orange apple
 # 或者使用内建变量
 $ awk 'BEGIN{FS=","} {print $1,$2}'     log.txt
 ---------------------------------------------
 2 this is a test
 3 Are you like awk
 This's a test
 10 There are orange apple
 # 使用多个分隔符.先使用空格分割,然后对分割结果再使用","分割
 $ awk -F '[ ,]'  '{print $1,$2,$5}'   log.txt
 ---------------------------------------------
 2 this test
 3 Are awk
 This's a
 10 There apple

用法三:

awk -v  # 设置变量

实例:

 $ awk -va=1 '{print $1,$1+a}' log.txt
 ---------------------------------------------
 2 3
 3 4
 This's 1
 10 11
 $ awk -va=1 -vb=s '{print $1,$1+a,$1b}' log.txt
 ---------------------------------------------
 2 3 2s
 3 4 3s
 This's 1 This'ss
 10 11 10s

用法四:

awk -f {awk脚本} {文件名}

实例:

 $ awk -f cal.awk log.txt
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秀球Gang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值