bash shell是一个与sh兼容的命令行解析器,是用户与系统内核交互的接口。通过bash,可以执行命令(程序),bash本身就内置了很多常用的命令。可以将一些常用的命令写入脚本中,让bash运行,用以实现简化和自动化日常的任务。对于其他比较复杂的任务,如字符串操作、算术、数据访问、更强的函数等功能,尽管bash也提供了对应的语法(也有函数!!),但还是应该选择使用其他脚本(python)或编译语言(c)。因此,这里只记录比较常用的bash语法。
shel按照启动方式的不同,可分为login
、non-login
、interactive
、non-interactive
shell。login shell
表示该shell用来登录;interactive shell
的标准输入输出都连接到终端上,即可与用户交互。
shell在启动时会读取配置文件,不同的shell读取的文件都不同。下面是bash shell在不同启动方式下,与执行的配置文件的关系:
/etc/profile
,然后查找~/.bash_profile
,~/.bash_login
和~/.profile
,读取和执行第一个找到的文件。当shell结束时,会读取和执行~/.bash_logout
和/etc/bash.bash_logout
。~/.bashrc
图形界面登录使用就不是bash了,而是不知道哪款GUI shell了
建议自己的配置一般放入~/.bashrc
中
配置文件中会定义一些和用户使用相关的环境变量和shell变量,如PATH、命令提示符(prompt)、命令别名(alias)、权限掩码、默认编辑器等配置。
一条简单的bash命令,以要执行的命令开始,接着给出空格分隔的参数,最后以控制操作符结束,执行结束后,会返回一个状态码。执行一条命令类似于其他语言中调用一个函数。
不要将状态码和命令的标准输出混淆,状态码可以通过
$?
获得,bash中很多复合命令可以检查到命令放回的状态码而执行响应的动作。
一般状态码为0表示命令正常,其余非正常,但命令状态码的解释权归该命令所有。
其中控制操作符可以是&
,;
,换行
。以&
结束的命令语句,会在后台运行,bash不会等待命令的完成,而是直接执行下一条语句;以;
或换行
结束的命令语句,bash会顺序执行,等待其完成。
多条由管道、控制操作数、&&、|| 等符号隔开的命令序列称为list。执行list后,会返回list中最后一条被执行的命令的状态码。
复合命令是bash提供的更为复杂的命令。书写命令时要注意符号间的空格
(list)
:list会在子shell环境中运行,因此list中的命令就算修改了环境变量,也不会影响当前shell的环境变量。
为将要运行的程序添加环境变量而不影响当前shell的方式还有:
PATH=/usr/confusing:$PATH yourprogram
即命令前直接设置变量,此时也不会产生子shell。
((expression))
:根据算法表达式expression计算的值返回对应的状态码。如果结果值不为零,状态码为0,否则返回1。[[ expression ]]
:根据条件表达式expression计算的值返回对应的状态码。如果表达式true,返回0,否则1。与[ expression ]
功能基本一致关于表达式,可以使用逻辑运算符进行组合:
( expression )
:提升表达式执行的优先级! expression
:取反表达式的状态码expression1 && expression2
:两个表达式为true(状态码为0),才true。expression2不被执行,当且仅当expression1返回0(true)。expression1 || expression2
:任意一个表达式为true,则true。expression2被执行,当且仅当expression1返回1(false)bash还提供了关于流程控制相关的命令:
for name in word ... ; do list ; done
for (( expr1 ; expr2 ; expr3 )) ; do list ; done
if list; then list; [ elif list; then list; ] ... [ else list; ] fi
其他的请查看man bash
手册。
shell只有一种类型,字符串。shell在执行命令之前,会查找变量、通配符、其他替换符号,然后替换,最终执行命令并传入处理过的参数。通过引号可以阻止这种行为:
\'
\"
替代。'
不能出现在里面"
不能出现在里面shell变量用于存储字面值、参与计算。bash为我们提供了一些特殊变量,用以获取相关的值,如当前shell的参数、进程号等等,但这些特殊变量不能被改变:
$1,$2,...
shift
可以删除第一个参数,其他参数前进补齐,即$2移入$1,$3移入$2,等等$#
$@
$0
$$
$?
exit num
,手动返回exit code,并结束当前shell。如果num不给出,默认上一条命令的exit code3.2小节提到了((expression))
可以计算算术表达式,下面给出所有的操作符:
id++
id--
++id
--id
-
+
unary minus and plus!
~
logical and bitwise negation**
exponentiation*
/
%
multiplication, division, remainder+
-
addition, subtraction<<
>>
left and right bitwise shifts<=
>=
comparison==
!=
equality and inequality&
bitwise AND^
bitwise exclusive OR|
bitwise OR&&
logical AND||
logical ORexpr?expr:expr
=
*=
/=
%=
+=
-=
<<=
>>=
&=
^=
|=
expr1 , expr2
复合命令 [[ ]]
与bash内置[ ]
命令作用基本一致,可以进行文件测试、字符串测试、算术测试。部分功能与3.5小节重叠,具体参数参考man test
${COMMAND}
允许命令的标准输出替换为命令行参数。如下面例子所示,echo 23
的输出23
替换了${echo 23}
[root@sidian Desktop]# echo 23
23
[root@sidian Desktop]# a=$(echo 23)
[root@sidian Desktop]# echo $a
23
在使用((expression))
时,该复合命令只会返回状态码,没有标准输出输出结果,可以使用$((expression))
获得它的值。
[root@sidian Desktop]# a=$((23+3))
[root@sidian Desktop]# echo $a
26
当然可以不用算术替换,只用算术表达式
[root@sidian Desktop]# ((b=23+33))
[root@sidian Desktop]# echo $b
56
. script
或source script
会在当前shell中导入并执行脚本中的命令#!/bin/sh
作为首行。