Linux基本用法(四)Bash编程

#! 默认后面为绝对路径名

可修改Bash变量

BASH
CDPATHbash完整路径
EDITORcd命令逐个查找的路径,未设置则查找当前目录
ENV应用程序默认编辑器
HISTFILE存放历史记录的文件的路径名
HOME用户的主目录名字
IFSBash分割命令行参数的符号
MAIL用户的系统邮箱文件的名字
MAILCHECKshell检查用户系统邮箱的周期(单位s),有新邮件时通知用户
PATH检索路径变量,用于查找外部命令和程序
PPID父进程ID
PS1命令行主shell提示符,通常为$
PS2二级shell提示符
PWD当前工作目录名字
TERM用户控制终端类型

上述shell环境变量可写

用户定义的变量在shell中作临时的存储空间,值在程序执行的过程中可改变。

set

不带参数时,显示当前所有的shell变量

env

可显示环境变量和它们的值,没那么完整

printenv有类似效果

declare和typeset要详细些

declare

declare [±options][name[=value]]

变量默认为字符串,可定义为一个整型值、函数或数组

-a name为数组

-f name为函数

-i name为整数

-r 给每一个name标记上只读的属性

-x 每一个name都可被子进程访问到

单纯声明时不会改变变量现有的值,即declare val,val原有的值不会改变

整型的变量不能被赋予非整型的值,否则变量的值会变为0.在声明时确定值的类型(declare等),后续不重新声明可直接用'='赋值。

非整型变量可以被赋予任何值,以字符串形式存放

值包含空格时,必须要用''引起来。

$val,表示取val的值,没有初始化为null

${val:-string},val存在不为空时返回其值,否则返回string

${val:=string},val存在不为空时返回其值,否则赋值并返回string

${val:+string},val存在不为空时返回string,否则返回null,用于测试变量存在与否

${val?string},val存在不为空时返回其值,否则显示 shell名字:val:string

在命令行中单独输入$val,会将val的值解析为命令执行。

控制shell提示符

\H:主机域名的全称

\T:时间,hh:mm:ss,12小时格式 \d:日期,格式为weekday month date

\h:计算机主机名的第一部分

\s:用户shell名字

\t:时间,hh:mm:ss,24小时格式

\u:当前用户的用户名 \v:Bash版本号

\w:当前的工作目录

命令替换

wsl中,若用$val取val的值,需要不带引号或只在双引号中使用

:若想将某些命令的输出值赋给变量,采用val=$(command)会十分有效。此过程和管道的输入输出链接有所不同。

export

export [name-list]:从export命令开始,使name-list所有变量的名字和现在的值输出到从这点开始的每个命令中。(不对父进程生效)

类似的有declare -x[name-list],typeset -x[name-list]

bash只读环境变量

环境变量名变量的用途
$0程序的名字
1~9命令參数1~9的值
$*全部命令行參数的值
@ |全部命令行參数的值。假设@被“”包含。即“@”,这相当于当中的每个參数的值被“”包含。相反,假设\$\*被“”包含。即“\$*”。这就相当于全部的參数值作为一个串被“”包含。这就是@同$*在被“”包含的时候的区别。其它时候这二者是等价的
$#记录了命令行參数的总个数
$$当前进程的ID号
$?近期一次命令的退出状态
$!近期一次后台进程的ID号

上述环境变量可以通过echo显示。也可在命令行中配合其他命令使用

“$*”,"$@"的区别在于双引号括起来,*是将所有参数当作一个字符串处理,@是将每一个参数的值都作为一个字符串。

重置变量

unset [name-list]:删除name-list中的值,等于显示赋值为null:name=

只读常量

readonly [name-list]:等价于 declare -r [name-list]以及 typeset -r [name-list]

只读变量的值不可以被unset,即不能被重设。也不能通过declare,typeset等设置,只能退出该进程

read

read [options][variable-list],从标准输入中读入一行,赋值给variable-list中的变量。

options:

-a name 读到数组name中

-e 一整行读入第一个变量,其余为null

-p prompt 从终端读入数据,显示prompt字符串。

如果variable-list有多个,则将输入中的word按序赋给variable-list中的变量。如果词的数量比列出的变量的数量多,则余下的所有词赋值给最后一个变量。如果列出的变量的数量多于输入的词的数量,则多余的变量的值被置为null。

read -p "Enter:" line,此命令会在命令行提示Enter:,然后将命令行的输入存入line变量中。

read成功读取后会返回

shell只能保留最多9个命令行参数(在命令行中按序传入)

shift

shift[N]:将命令行参数左移N位,移位只在1以后的参数中进行,$0保持不变。

需要值得注意的是一开始传入shell脚本的参数数量大于9个时仍是全部被一次性读入到shell脚本中。

set

set [options][argument-list]

options:

-- 不把以'-'开头的词作为参数选项

-C 把noclobber标志设置为on,不允许用户通过重定向覆盖已经存在的文件,如果要覆盖,则需要强制重定向,如>|

-a 赋值的时候自动把变量输出

-o [options] 设置options;当options为空,打印出目前shell的设置,可选的option有

hash 内部哈希表保存命令的位置,可用-h选项设置

history 允许保存历史记录

noclobber 不允许输出重定向覆盖已经存在的文件

-v 详细模式:显示隐含的输入参数

set命令是将命令行参数设置为argument-list,即将后者对应填入$1~$9位置

Bash脚本编码规范
程序头内容

1.包含脚本的文件名

2.作者的名字

3.编写的日期

4.最后一次修改的日期

5.编写这个脚本的目的

6.对解决这个问题的算法的简要描述

注释以#开始

跳转

if expression;then

command

fi

如果要实现二路甚至是多路跳转,可以使用else,elif

if expression;then

command

elif expression;then

command

...(elif数目无限制)

else

command

fi

注:条件expression后接分号,i整个条件结束用fi

&> /dev/null:将输出结果丢弃

对表达式求值

test [expression] / [[expression]]

命令过长时,可以用'\'分隔命令。

for

for var [in argument-list]

do

command-list

done

如果有argument-list,则按序赋给变量var,并依次执行command-list。若没有argument-list,则从命令行获取

while

while expression

do

command-list

done

expression为真一直执行

until

until expression

do

command-list

done

expression值为假时,重复执行command-list中的命令

类似的,循环语句中有break和continue

case

使用符号';;'给command-list划分边界

case expression in
pattern1)   cmd1;;
pattern2)   cmd2;;
...
patternN)   cmdN;;
esac
​

对于default case,可以用*)代替

数值数据处理

运算符描述示例
+加法,数字(操作数)的加法$(( 10 + 3 )),结果为:13
-减法,从第一个到第二个操作数的减法$(( 10 - 3 )),结果为:7
*乘法,操作数的乘法。$(( 10 * 3 )),结果为:30
/除法,第一个操作数除以第二个操作数并返回商。$(( 10 / 3 )),结果为:3
**求幂,第一操作数的第二操作数的幂值。$(( 10 ** 3 )),结果为:1000
%模,测量第一个操作数除以第二个操作数时的余数。$(( 10 % 3 )),结果为:1
+=通过常量递增变量,用于按提供的常量递增第一个操作数的值。x=10;let "x += 3";echo $x;结果为:13
-=通过常量递减变量,用于按提供的常量递减第一个操作数的值。x=10;let "x -= 3";echo $x;结果为:7
*=将变量乘以常数,用于将第一个操作数的值乘以提供的常数。x=10;let "x *= 3";echo $x;结果为:30
/=将变量除以常数,用于计算(变量/常数)的值并将结果存储回变量。x=10;let "x /= 3";echo $x;结果为:3
%=变量除以常数的余数,用于计算(变量%常数)的值并将结果存储回变量。x=10;let "x %= 3";echo $x;结果为:1

其他的运算符还有逻辑非、补(!、~),移位(<<、>>),不等关系(\leq、\geq、<、>、==、!=),逻辑运算(&、^、|,注意优先级不同),逻辑与或(&&、||),赋值(&=、^=、|=、<<=、>>=)

let expression:计算算术表达式expression的值,expression若是命令,则会被执行,expression可以有多个,中间用' '分隔

expr

expr args:计算表达式的参数args的值,并返回值到标准输出

expr index str1 str2: 在str1中寻找str2内的字符,并返回第一个匹配的位置索引,匹配不到返回0

expr length str:计算并将str长度送到标准输出

expr substr str num1 num2:提取str从num1开始,长为num2的子串

expr "abcd" : "\(.bc\)"

匹配正则字符串,用“\(\)”括起来的返回匹配到的字符串

expr "abcd" : ".bc"

此时返回匹配到的字符串的长度

使用expr命令时,参数与选项之间要留有空格

:不要用''将expr语句括起来,在wsl中若想将expr的返回值赋值给变量,用var=$(expr command),也可以用var=`expr command`

数组

数组大小没有限制,不必连续赋值。只要声明了数组变量,就可以给数组任何一个元素赋值。

引用数组array内容:${array[i]},i为下标。若将@或者*当作下标,则引用数组中所有元素。区别在于$array[*]将数组中所有元素扩展为一个词,$array[@]将数组中每个元素分别扩展为一个词。

数组初始化方法:

array=(val1 val2 ... valN),不同值之间用' '隔开。

初始化后可以根据需要给任意下标数据赋值

local可以声明局部数组,但只能在函数中使用。

显示数组元素大小:${#array[i]},没有下标i时显示第一个数组元素的大小。

*作为下标时显示数组元素个数,只会统计被赋值的元素,如若只有1,19,36下标对应的元素被赋值,则结果为3。

数组下标从0开始

here文件

将脚本中命令的标准输入重定向到脚本中的数据(重定向到本文件中)

command << [-] input_marker

...input data...

input_marker(结束标记必须单独另起一行)

input_marker为自定义字

-连字符是取消here文件中(即input data区域)行首和结束标记前面的tab(不包括空格)

如果输出和错误也要重定向,则重定向要在here文件结束标记前,可以在<<之前,也可以在input_marker(非结束标记)与input data之间

中断(信号)处理

Arm Linux 信号

信号执行动作信号发出的原因
SIGHUP1A终端的挂端或控制进程终止
SIGINT2A来自键盘的中断信号(ctrl+c组合键)
SIGQUIT3C终端退出(ctrl+\组合键)(ctrl+I)
SIGILL4C非法指令
SIGTRAP5C断点或陷阱指令(debuger使用)
SIGABRT6C来自abort(3)发出的退出指令
SIGBUS7C总线错误
SIGFPE8C浮点运算错误
SIGKILL9AEFKill信号
SIGUSR110A用户自定义信号1
SIGSEGV11C段非法错误(无效的内存引用)
SIGUSR212A用户自定义信号2
SIGPIPE13A管道损坏:写一个没有读端口的管道
SIGALARM14A由alarm(2)发出的信号
SIGTERM15A终止信号(软件中断)
SIGSTKFLT16栈溢出
SIGCHLD17B子进程结束信号
SIGCONT18B进程继续(曾被停止的进程)
SIGSTOP19DEF停止进程的执行,只是暂停
SIGTSTP20D停止进程的运行(Ctrl+z组合键)(挂起进程)
SIGTTIN21D后台进程需要从终端读取数据
SIGTTOU22D后台进程需要向终端写数据
SIGURG23BI/O有紧急数据到达当前进程
SIGXCPU24A查过CPU资源限制
SIGXFSZ25A文件大小超出上限
SIGVTALRM26A虚拟时钟超时
SIGPROF27AProfile时钟信号描述
SIGWINCH28B窗口大小改变
SIGIO29BI/O相关
SIGPWR30B关机
SIGSYS31非法的系统调用

trap 'command-list' signal-list:处理截获的信号,command-list两端必须有单引号。

使用trap但没有参数时,执行默认动作(命令是多余的)。

command-list为空(只剩下单引号),则signal-list被忽略

stty

修改终端命令行相关设置

stty -echo命令:禁止回显(即命令行上不会显示输入)

stty echo:打开回显

'-'表示恢复原来的功能,下同

stty iuclc:开启禁止输出大写

stty olcuc:开启禁止输出小写

stty size:打出终端的行数和列数

stty eof "string":改变文件结束符,默认为ctrl+D

stty igncr:忽略回车符

exec

独特用途

执行一个命令或程序取代当前的进程

打开和关闭文件描述符

exec command:将command代码覆盖到运行exec命令的进程上不生成新的进程,结束后控制权交还给调用进程的父进程

exp:shell中执行exec,则返回到mingetty进程,需要login

exec [选项] <命令> [参数]

  • 选项exec命令可以接受一些选项,用于控制其行为。以下是一些常用的选项:

    • -c:在执行命令之前,先清除环境变量。

    • -l:在执行命令之前,先将当前环境变量传递给新的进程。

    • -s:在执行命令之前,将当前进程的信号掩码传递给新的进程。

    • -t:在执行命令之前,分配一个伪终端(pseudo-terminal)给新的进程。

  • <命令>:要执行的命令。可以是任何可执行的命令,包括内部命令和外部命令。

  • 参数:传递给命令的参数。你可以指定零个或多个参数,具体取决于命令的要求。

请注意,exec命令执行后会替换当前进程,因此执行exec命令后的代码不会被执行。如果你希望在执行完一个命令后继续执行其他代码,你可以使用分号(;)将多个命令组合在一起。

以下是一个示例,展示了如何使用exec命令执行一个外部命令:

bash shell最多允许10个文件描述符,(0 1 2)保留给标准输入、输出、错误

exec中的重定向操作和之前相同,还可以打开here文档进行重定向。

exec <&-关闭标准输入

exec >& -关闭标准输出

exec n<& - ,关闭重定向为标准输入的文件描述符n

exec n>& -,关闭重定向为标准输出的文件描述符n

exec < /dev/tty:将stdin重新连接到终端。/dev/tty是代表shell运行时终端的伪终端

exec > /dev/tty:将stout重新连接到终端.exec执行输出重定向后必须要使用该命令才能使显示屏重新和终端相连。

exec的特性配合重定向操作适合在脚本中对文件进行操作,不需要额外的command

函数

使用函数的原因:函数的定义在内存中,调用比脚本(硬盘)快。

在脚本中定义了函数后,使用前需要用.或source命令

函数前使用export,可使函数为子进程所使用。

定义:

func()
{
    command-list
}

函数可在命令行中按上述方式交互式地定义

函数中的参数通过脚本中的变量获取

调试

Bash shell中,-x选项用于启用shell的跟踪模式。当使用bash -x命令时,Bash会在执行每个命令之前打印该命令的跟踪信息,跟踪信息包括执行的命令、参数和结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值