Linux Shell
Linux Shell
- By: luozaijin
- 22/6/23
[目录]
Shell Color
# Shell颜色设置
# 输出特效格式控制: (可用于echo)
# \033[0m 关闭所有属性
# \033[1m 设置高亮度
# \03[4m 下划线
# \033[5m 闪烁
# \033[7m 反显
# \033[8m 消隐
# \033[30m -- \033[37m 设置前景色
# \033[40m -- \033[47m 设置背景色
# 光标位置等的格式控制:
# \033[nA 光标上移n行
# \03[nB 光标下移n行
# \033[nC 光标右移n行
# \033[nD 光标左移n行
# \033[y;xH设置光标位置
# \033[2J 清屏
# \033[K 清除从光标到行尾的内容
# \033[s 保存光标位置
# \033[u 恢复光标位置
# \033[?25l 隐藏光标
# \33[?25h 显示光标
# 整理:
# 编码 颜色/动作
# 0 重新设置属性到缺省设置
# 1 设置粗体
# 2 设置一半亮度(模拟彩色显示器的颜色)
# 4 设置下划线(模拟彩色显示器的颜色)
# 5 设置闪烁
# 7 设置反向图象
# 24 关闭下划线
# 25 关闭闪烁
# 27 关闭反向图象
# 30 设置黑色前景
# 31 设置红色前景
# 32 设置绿色前景
# 33 设置棕色前景
# 34 设置蓝色前景
# 35 设置紫色前景
# 36 设置青色前景
# 37 设置白色前景
# 38 在缺省的前景颜色上设置下划线
# 39 在缺省的前景颜色上关闭下划线
# 40 设置黑色背景
# 41 设置红色背景
# 42 设置绿色背景
# 43 设置棕色背景
# 44 设置蓝色背景
# 45 设置紫色背景
# 46 设置青色背景
# 47 设置白色背景
# 49 设置缺省黑色背景
# 特效可以叠加,需要使用“;”隔开,例如:闪烁+下划线+白底色+黑字为 \033[5;4;47;30m闪烁+下划线+白底色+黑字为\033[0m
\033[30m #黑色字
\033[31m #红色字
\033[32m #绿色字
\033[33m #黄色字
\033[34m #蓝色字
\033[35m #紫色字
\033[36m #天蓝字
\033[37m #白色字
\033[40;37m #黑底白字
\033[41;30m #红底黑字
\033[42;34m #绿底蓝字
\033[43;34m #黄底蓝字
\033[44;30m #蓝底黑字
\033[45;30m #紫底黑字
\033[46;30m #天蓝底黑字
\033[47;34m #白底蓝字
\033[0m #结束语
语句常用命令
sleep 等待
- sleep命令语法
以下是Bash中sleep命令的语法:
sleep number[suffix]
可以使用正整数或小数作为时间值。后缀是可选部分。可以将以下任意一项用作后缀:
s
- 表示秒m
- 表示分钟h
- 表示小时d
- 表示天
例子: 睡眠2天9小时5分55秒,使用:
sleep 2d 9h 5m 55s
timeout 程序限时
程序限时的命令, 他会将程序运行时间限定在一定的时间内.
timeout 5s ping baidu.com # 5秒结束程序
s
代表 秒(默认)m
代表 分钟h
代表 小时d
代表 天
timelimit 程序限时
程序运行一个给定的命令,然后在指定的时间后使用一个给定的信号终止进程。它首先传递一个警告信号,然后在超时后发送杀死信号. 该程序一般需要下载
sudo apt install timelimit # 下载该程序
与timeout
选项不同,timelimit
有更多的选项,如killsig
、warnsig
、killtime
和warntime
。
timelimit -t 30 ping baidu.com # 30秒后结束
exit 退出脚本
退出(返回)命令,不等于 关闭,结束命令
将变量名与周围的文本分开
如果有一串字符串变量和字符创连接在一起如何将它们分开?
比如 \(vlue 是一个变量. 在将变量赋值给变量abc,\)abc=$vlueabc 但是vlue变量后还有字符
那如何识别字符串中的变量呢?
可以使用 ↓
$abc=${vlue}abc
$abc=abc${vlue}def
使用完整的变量引用语法,不仅要包括 $,还要在变量名周围加上花括号。
修改部分字符串
在 ${...} 内输入
格式 | 操作 |
---|---|
name:number:number | 从字符串name的索引位置number开始, 返回长度为number的子串 |
#name | 但会字符串的长度 |
name#pattern | 从字符串起始位置开始,删除匹配pattern的最短子串 |
name##pattern | 从字符串起始位置开始,删除匹配pattern的最长子串 |
name%pattern | 从字符串结束位置开始,删除匹配pattern的最短子串 |
name%%pattern | 从字符串结束位置开始,删除匹配pattern的最长子串 |
name/ pattern/ string | 替换字符串中第一次出现的pattern |
name// pattern// string | 替换字符串中所有出现的pattern |
Shell 输入/输出重定向
大多数 UNIX 系统命令从你的终端接受输入并将所产生的输出发送回到您的终端。一个命令通常从一个叫标准输入的地方读取输入,默认情况下,这恰好是你的终端。同样,一个命令通常将其输出写入到标准输出,默认情况下,这也是你的终端。
0 通常是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)。
重定向命令列表如下:
命令 说明
command > file 将输出重定向到 file。
command < file 将输入重定向到 file。
command >> file 将输出以追加的方式重定向到 file。
n > file 将文件描述符为 n 的文件重定向到 file。
n >> file 将文件描述符为 n 的文件以追加的方式重定向到 file。
n >& m 将输出文件 m 和 n 合并。
n <& m 将输入文件 m 和 n 合并。
<< tag 将开始标记 tag 和结束标记 tag 之间的内容作为输入。
附加引用
在字符串内将命令的结果输出至屏幕。
$(命令)
$ cat nu
echo There are $(who | wc –1) users logged in
$ nu # 执行程序
There are 13 users logged in
附图:
判断-循环
- 例子 1:
if [ $(ps -ef | grep -c "ssh") -gt 1 ]; then echo "true"; fi
ps: [] 内是条件,then 之后 是条件为真 则执行的命令 最后以fi 结束.
- 例子 2:
if condition
then
command1
command2
...
commandN
fi
- 例子 3:
if else 语法格式:
if condition
then
command1
command2
...
commandN
else
command
fi
- 例子 4:
if else-if else 语法格式:
if condition1
then
command1
elif condition2
then
command2
else
commandN
fi
for 遍历
与其他编程语言类似,Shell支持for循环。
for循环一般格式为:
for var in item1 item2 ... itemN
do
command1
command2
...
commandN
done
写成一行:
for var in item1 item2 ... itemN; do command1; command2… done;
ps: 当变量值在列表里,for 循环即执行一次所有命令,使用变量名获取列表中的当前取值。命令可为任何有效的 shell 命令和语句。in 列表可以包含替换、字符串和文件名。in列表是可选的,如果不用它,for循环使用命令行的位置参数。
while 语句
while 循环用于不断执行一系列命令,也用于从输入文件中读取数据。其语法格式为:
while condition
do
command
done
until 循环
until 循环执行一系列命令直至条件为 true 时停止。一般 while 循环优于 until 循环,但在某些时候—也只是极少数情况下,until 循环更加有用。
until 语法格式:
until condition
do
command
done
case ... esac
case ... esac 为多选择语句,与其他语言中的 switch ... case 语句类似,是一种多分枝选择结构,每个 case 分支用右圆括号开始,用两个分号 ;; 表示 break,即执行结束,跳出整个 case ... esac 语句,esac(就是 case 反过来)作为结束标记。
可以用 case 语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令。
补充:A|a) echo "你按下了A或是a" ;;
以上黄色高亮的 代码内 在选择的 半括号内有管道 | 表示 A 或者 a 都能触发这个选择。
case ... esac 语法格式如下:
case 值 in
模式1)
command1
command2
...
;;
模式2)
command1
command2
...
;;
esac
或
case 值 in
模式1) command1 ;;
模式2)command1 ;;
esac
- 实例 1
echo '输入 1 到 4 之间的数字:'
echo '你输入的数字为:'
read aNum
case $aNum in
1) echo '你选择了 1'
;;
2) echo '你选择了 2'
;;
3) echo '你选择了 3'
;;
4) echo '你选择了 4'
;;
*) echo '你没有输入 1 到 4 之间的数字'
;;
esac
- 实例 2
#!/bin/bash
while :
do
echo -n "输入 1 到 5 之间的数字:"
read aNum
case $aNum in
1|2|3|4|5) echo "你输入的数字为 $aNum!"
;;
*) echo "你输入的数字不是 1 到 5 之间的! 游戏结束"
break
;;
esac
done
跳出循环
break命令
break命令允许跳出所有循环(终止执行后面的所有循环)。
continue
continue命令与break命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环,下一次还继续循环。
- 实例 3
#!/bin/bash
while :
do
echo -n "输入 1 到 5 之间的数字: "
read aNum
case $aNum in
1|2|3|4|5) echo "你输入的数字为 $aNum!"
;;
*) echo "你输入的数字不是 1 到 5 之间的!"
continue
echo "游戏结束"
;;
esac
done
运算符
算术运算符
算符 | 说明 | 举例 |
---|---|---|
+ | 加法 | expr \(a +\)b 结果为 30。 |
- | 减法 | expr \(a -\)b 结果为 -10。 |
* | 乘法 | expr \(a \$b 结果为 200。<br/> `/` 除法 expr\)b / \(a 结果为 2。<br/> `%` 取余 expr\)b % \(a 结果为 0。<br/> `=` 赋值 a=\)b 将把变量 b 的值赋给 a。 |
== | 相等 | 用于比较两个数字,相同则返回 true。 \(a ==\)b 返回 false。 |
!= | 不相等 | 用于比较两个数字,不相同则返回 true。 \(a !=\)b 返回 true。 |
关系运算符
运算符 说明 举例
-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。
布尔运算符
运算符 | 说明 | 举例 |
---|---|---|
! | 非运算,表达式为 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。 |
逻辑运算符
运算符 | 说明 | 举例 |
---|---|---|
&& | 逻辑的 AND | 第一个命令成功则执行第二个命令,否则不执行. |
|| | 逻辑的 OR | 第一个命令成功则不执行第二个命令. |
字符串运算符
运算符 说明 举例
=
检测两个字符串是否相等,相等返回 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。
文件测试运算符
操作符 说明 举例
-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
: 检测文件是否存在并且是一个符号链接。
Shell test 命令
Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。
- 实例
num1=100
num2=100
if test $[num1] -eq $[num2]
then
echo '两个数相等!'
else
echo '两个数不相等!'
fi
算术表达式
一般格式:$((expression '解析引用锚文本失败,请尝试更新该引用指向的定义块后再重新打开该文档'))
附图:
用模式匹配进行测试 [[ ]]
** 你不想对字符串进行字面匹配,而是想看看它是否符合某种模式。**
在 if 语句中使用复合命令 [[ ]],以便在等量运算符右侧启用 shell 风格的模式匹配:
if [[ "${$A}" == "${B}" ]] # 比较变量A和变量B是否一样
if [[ "$VLUE" == *.@(jpg|jpeg) ]] # 匹配多个格式
[[ ]]
语法不同于 test 命令的老形式 [,它是一种较新的 bash 机制 ( bash 2.01 版左右才出现)。能够在[ ]
中使用的运算符也可用于 [[ ]]
,但在后者中,等号是一种更为强大的字符串比较运算符。就像我们一样,你也可以使用 =
或 ==
,两者在语义上相同。我们偏好 ==
(尤其是进行模式匹配时),这样更加醒目,但模式匹配功能可不是因此而有的,它源于复合命令 [[ ]]
数值测试
参数 说明
-eq
等于则为真
-ne
不等于则为真
-gt
大于则为真
-ge
大于等于则为真
-lt
小于则为真
-le
小于等于则为真
字符串测试
参数 说明
=
等于则为真
!=
不相等则为真
-z
字符串 字符串的长度为零则为真
-n
字符串 字符串的长度不为零则为真
文件测试
- 参数 说明
-e
文件名 如果文件存在则为真
-r
文件名 如果文件存在且可读则为真
-w
文件名 如果文件存在且可写则为真
-x
文件名 如果文件存在且可执行则为真
-s
文件名 如果文件存在且至少有一个字符则为真
-d
文件名 如果文件存在且为目录则为真
-f
文件名 如果文件存在且为普通文件则为真
-c
文件名 如果文件存在且为字符型特殊文件则为真
-b
文件名 如果文件存在且为块特殊文件则为真
扩展模式匹配说明
扩展模式 | 含义 |
---|---|
@ | 仅匹配一次 |
* | 匹配0次或多次 |
+ | 匹配1次或多次 |
? | 匹配0次或一次 |
! | 匹配除此之外的任何模式 |
匹配区分大小写,不过可以用 shopt -snocasematch(适用于 bash 3.1 以上版本)改变这种行为。该选项会影响到 case 和 [[ 命令。
Shell 数组
数组中可以存放多个值。Bash Shell 只支持一维数组(不支持多维数组),初始化时不需要定义数组大小.与大部分编程语言类似,数组元素的下标由 0 开始。
Shell 数组用括号来表示,元素用"空格"符号分割开,语法格式如下:
array_name=(value1 value2 ... valuen)
读取数组
读取数组元素值的一般格式是:
${array_name\[index\]}
创建关联数组
与数字索引数组不同,关联数组需要首先声明。可以使用关键字declare
和-A
(大写)选项来声明关联数组。语法定义为:
declare -A ARRAY_NAME
创建关联数组的通用方法可以按以下形式定义:
declare -A ARRAY_NAME
ARRAY\_NAME\[index\_foo\]=value_foo
ARRAY\_NAME\[index\_bar\]=value_bar
ARRAY\_NAME\[index\_xyz\]=value_xyz
其中index_
用于定义任何字符串。还可以通过以下方式编写以上形式:
declare -A ARRAY_NAME
ARRAY\_NAME=(\[index\_foo\]=value_foo
\[index\_bar\]=value\_bar
\[index\_xyz\]=value\_xyz
)
将元素添加到数组
可以选择通过分别指定元素的索引或关联键将元素添加到索引或关联数组。要将新元素添加到bash中的数组中,可以使用以下形式:
ARRAY\_NAME\[index\_n\]="New Element"
更新数组元素
可以通过按索引值为现有数组分配新值来更新数组元素。下面将使用值Yiibai
更改索引4
处的数组元素。
example_array=( "0 "1" "2" "3" "aaa" )
example_array\[4\]=bbb
从数组中删除元素
如果要从数组中删除元素,则在关联数组的情况下必须知道其索引或键。可以使用unset
命令删除元素:
unset ARRAY_NAME\[index\]
ps: 不添加元素就把整个列表删除了 或者添加 * or @ 也是将整个列表删除
切片数组元素
Bash数组也可以从给定的起始索引切到结束索引。要将数组从起始索引m
切到结束索引n
,可以使用以下语法:
SLICED\_ARRAY=(${ARRAY\_NAME\[@\]Ⓜ️n}")
使用数组变量
VULE=(A B C D) # 数组变量
echo ${VLUE[0] "&" VLUE[3]} # 索引变量
A&D # 输出内容
输入与输出
read
说明: 读取输入的字符,并赋予变量
- read -参数 "字符串" 变量
如果你在 read 语句中提供了多个变量名,那么read 会将输入解析为多个单词,依次赋给这些变量。如果用户输入的单词数较少,多出的变量就会被设为空(null)。如果用户输入的单词数多于变量数,则多出的单词会全部赋给最后那个变量。
-参数:
-a
后跟一个变量,该变量会被认为是个数组,然后给其赋值,默认是以空格为分割符。
-d
后面跟一个标志符,其实只有其后的第一个字符有用,作为结束的标志,会举例说 明。
-p
后面跟提示信息,即在输入前打印提示信息。
-e
在输入的时候可以使用命令补全功能。
-n
后跟一个数字,定义输入文本的长度,很实用。
-r
屏蔽,如果没有该选项,则作为一个转义字符,有的话 就是个正常的字符了。
-s
安静模式,在输入字符时不再屏幕上显示,例如login时输入密码。
-t
后面跟秒数,定义输入字符的等待时间。
-u
后面跟 fd
,从文件描述符中读入,该文件描述符可以是exec
新开启的。
- 例子
read -t 30 -p "please input your name: " name #提示“请输入姓名”并等待30秒,输入值保存到变量name中
printf
printf
命令格式化输出。
语法
printf Format [ Argument ... ]
描述
printf
命令转换、格式化并写 Argument 参数到标准输出。Argument 参数是由 Format 参数控制格式化的。格式化输出行不能超出 LINE_MAX 字节长度。
下列环境变量影响 printf 命令的执行:
LANG 在 LC_ALL 和相应的环境变量(以 LC_ 开头)没有指定语言环境时,确定语言环境编目使用的语言环境。
LC_ALL 确定用于覆盖由 LANG 或其它任何 LC_ 环境变量设置的任何语言环境编目值的语言环境。
LC_CTYPE 确定把文本字节数据顺序解释为字符的语言环境;例如,单一字节对应多字节字符的参数。
LC_MESSAGES 确定写消息使用的语言。
LC_NUMERIC 确定数字格式编排的语言环境。此环境变量影响使用 e、E、f、g 和 G 转换字符编写的数字的格式。
Format
参数是包含三种对象类型的一个字符串:
无格式字符复制到输出流。
转换规范,每个规范导致在值参数列表中检索 0 个或更多个项。
以下转义序列。在复制到输出流时,这些序列导致它们的相关操作在有此功能的设备上显示:
//
反斜杠
/a
警告
/b
退格
/f
换页
/n
换行
/r
回车
/t
跳格
/v
垂直跳格
/ddd
ddd 是 1、2 或 3 位八进制数字。这些转义序列作为由八进制数指定的具有数字值的字节显示。
Argument 参数是一个或多个字符串的列表,它在 Format 参数的控制下被写到标准输出。
Format 参数在必要的情况下会经常重新使用以满足 Argument 参数。将好像提供了空字符串 Argument 一样评估任何额外的 c 或者 s 转换规范;其它额外转换规范将好像提供了 0 Argument 一样评估。此处 Format 参数不包含转换规范仅出现 Argument 参数,结果是不确定的。
每个 Format 参数中的转换规范都具有如下顺序的语法:
%
(百分号)。
零或更多的选项,修改转换规范的含义。选项字符和它们的含义是:
-
转换结果在字段中左对齐。
+
符号转换结果常以符号(+ 或者 -)开始。
空格 如果符号转换的第一个字符不是符号,结果的前缀将是空格。如果空格和 + 选项字符都显示,则忽略空格选项字符。
#
此选项指定值转换到备用格式。对于 c、d、i、u 和 s 转换,选项没有作用。对于 o 转换,它增加精度来强制结果的第一数字是 a、0(零)。对于 x 和 X 转换,非零结果分别具有 0x 或 0X 前缀。对于 e、E、 f、g 和 G 转换,结果通常包含基数字符,即使基数字符后没有数字。对于 g 和 G 转换,结尾零不象通常一样除去。
0
对于 d、i、o、u、x、e、E、f、g 和 G 转换,前导零(跟在符号或底数的后面)用于填充字段宽度,将不用空格填充。如果显示 0 (零)和 - (减号)选项,0 (零)选项被忽略。对于 d 、i 、o 、u 、x 和 X 转换,如果指定精度,0 (零)选项将被忽略。
注:
其它转换,没有定义其行为。
可 选的指定最小值字段宽度的十进制数字字符串。如果转换值字符少于字段宽度,该字段将从左到右按指定的字段宽度填充。如果指定了左边调整选项,字段将在右边 填充。如果转换结果宽于字段宽度,将扩展该字段以包含转换后的结果。不会发生截断。然而,小的精度可能导致在右边发生截断。
可选的精度。精度是一个 .(点)后跟十进制数字字符串。如果没有给出精度,按 0(零)对待。精度指定:
d、o 、i 、u 、x 或 X 转换的最少数字显示位数。
e 和 f 转换的基数字符后的最少数字显示位数。
g 转换的最大有效数字位数。
s 转换中字符串的最大打印字节数目。
指示要应用的转换类型的一个字符,例如:
% 不进行转换。打印一个 %(百分号)。
d , i 接受整数值并将它转换为有符号的十进制符号表示法。精度指定显示的最小数字位数。如果值转换后可以用更少的位数来表示,将使用前导零扩展。缺省精度是 1。精度为零的零值转换的结果是空字符串。用零作为前导字符来指定字段宽度,导致用前导零填充字段宽度值。
o 接受整数值并将它转换为有符号的八进制符号表示法。精度指定显示的最小数字位数。如果值转换后可以用更少的位数来表示,将使用前导零扩展。缺省精 度是 1。精度为零的零值转换的结果是空字符串。用零作为前导字符来指定字段宽度,导致用前导零填充字段宽度值。不用八进制值表示字段宽度。
u 接受整数值并将它转换为无符号的十进制符号表示法。精度指定显示的最小数字位数。如果值转换后可以用更少的位数来表示,将使用前导零扩展。缺省精度是 1。精度为零的零值转换的结果是空字符串。用零作为前导字符来指定字段宽度,导致用前导零填充字段宽度值。
x , X 接受整数值并将它转换为十六进制符号表示法。字母 abcdef 用于 x 转换,字母 ABCDEF 用于 X 转换。精度指定显示的最小数字位数。如果值转换后可以用更少的位数来表示,将使用前导零扩展。缺省精度是 1。精度为零的零值转换的结果是空字符串。用零作为前导字符来指定字段宽度,导致用前导零填充字段宽度值。
f 接受浮点或者双精度值并将它转换为十进制符号表示法,格式为 [- ] ddd . ddd 。基数字符(在这里显示为十进制点)后的数字位数等于规定的精度。 LC_NUMERIC 语言环境编目确定在这个格式中使用的基数字符。如果不指定精度,则输出六个数字。如果精度是 0 (零),将不显示基数字符。
e , E 接受浮点或者双精度值并将它转换为指数表示的形式 [- ] d . dd e {+ |- }dd 。在基数字符前有一个数字(在这里显示为十进制点),基数字符后的数字位数等于规定的精度。 LC_NUMERIC 语言环境编目确定在这个格式中使用的基数字符。如果不指定精度,则输出六个数字。如果精度是 0(零),将不显示基数字符。E 转换字符在指数前生成带 E 而不是带 e 的数字。指数通常至少包含两个数字。然而,如果要打印的指数值大于两个数字,必要时需要打印附加指数数字。
g 、G 接受浮点和双精度值并转换为 f 或 e 转换字符的样式(或在 G 转换的情况下是 E),用精度指定有效数字的个数。尾零将从结果中除去。基数字符只有在其后是数字时显示。使用的样式取决于转换的值。样式 g 仅在转换的指数结果小于 -4,或大于或等于精度时使用。
c 接受值将其作为字符串并打印字符串中的第一个字符。
s 接受值将其作为字符串并打印字符串中的字符直到字符串结束或者达到精度指示的字符个数。如果没有指定精度,打印全部字符直到出现第一个空字符。
b 接受值将其作为字符串,可能包含反斜杠转义序列。打印来自转换字符串的字节直到字符串结束或者达到精度规范指示的字节数。如果没有指定精度,打印全部字节直到出现第一个空字符。
支持下列反斜杠转义序列:
先前列出的反斜杠转义序列在 Format 参数描述下。这些转义序列将被转换到它们表示的单个字符。
/c(反斜杠 c)序列,它不显示并使 printf 命令忽略 Format 参数中的字符串参数包含的剩余的所有字符串,所有剩余的字符串参数和所有附加字符
echo
echo - 显示一行文本
允许在标准输出上显示STRING(s).
-n
不输出行尾的换行符.
-e
允许对下面列出的加反斜线转义的字符进行解释.
-E
禁止对在STRINGs中的那些序列进行解释.
--help
显示帮助并退出(须单独运行)
--version
输出版本信息并退出(须单独运行)
在没有 -E 的情况下,可承认并可以内置替换以下序列:
\NNN
字符的ASCII代码为NNN(八进制)
\\
反斜线
\a
报警符(BEL)
\b
退格符
\c
禁止尾随的换行符
\f
换页符
\n
换行符
\r
回车符
\t
水平制表符
\v
纵向制表符
注释
单行注释 :
printf("Hello world") # 输出一个字符串.
多行注释
多行注释-方法1
#!/bin/bash
<<BLOCK
This is the first comment
This is the second comment<br/>
This is the third comment
BLOCK
echo "Hello World"
Shell
多行注释-方法2
#!/bin/bash: '
This is the first comment
This is the second comment
This is the third comment
'echo "Hello World"
位置参数
命令行参数命令行参数用于通过将输入传递给代码来使脚本更具动态性。在脚本运行时以以下形式传递这些参数:
./script_name arg1 arg2 arg3.....
说明:脚本名称和所有传递的参数之间不要有空格。在Bash Shell中,它们与以下默认参数或特殊变量的引用一起使用。
参数
$0
- 指定要调用的脚本的名称。
$1-$9
- 存储前9个自变量的名称,或可用作自变量的位置。
$#
- 指定传递给脚本的参数总数(计数)。
$*
- 通过将所有命令行参数连接在一起来存储它们。
$@
- 将参数列表存储为数组。
$?
- 指定当前脚本的进程ID。
$$
- 指定最后一个命令或最近执行过程的退出
$!
- 显示最后一个后台作业的ID。
Ps: \(符号 表示是已被赋予的变量名 后面的符号表示以上参数.\) 与 $@ 区别:都是引用所有参数。只有在双引号中体现出来。假设在脚本运行时写了三个参数 1、2、3,,则 " " 等价于 "1 2 3"(传递了一个参数),而 "@" 等价于 "1" "2" "3"(传递了三个参数)。
参数替换
$ {parameter:-value}
这种写法的意思:如果parameter
不为空,则使用它的值;否则,就使用value
。举例来说,在下列命令行中:
$ echo Using editor ${EDITOR:-/bin/vi}
如果变量EDITOR
不为空,Shell就使用该变量的值,否则使用/bin/vi
。
${parameter:=value}
和上一种写法类似,但如果parameter
为空的话,不仅会使用value
,而且还会将其分配给 parameter
(注意其中的=)。你不能使用这种方法给位置参数赋值,也就是说,parameter
不能是数字。
典型用法是测试某个导出变量是否已经设置,如果没有,则为其分配默认值:
${PHONEBOOK:=$HOME/phonebook}
这句的意思是如果PHONEBOOK
已经分配了值,那么不做任何操作,否则将其设为$HOME/phonebook
。
${parameter:?value}
如果parameter
不为空,Shell会替换它的值;否则,Shell将value
写入到标准错误,然后退出(别担心,如果是在登录Shell中完成的该操作,这并不会导致你登出系统)。如果忽略value
,Shell会输出默认的错误信息:
prog: parameter: parameter null or not set
下面是一个例子:
$ PHONEBOOK=
$ : ${PHONEBOOK:?"No PHONEBOOK file"}
No PHONEBOOK file
$ : ${PHONEBOOK:?} #没有给出value
sh: PHONEBOOK: parameter null or not set
$
你可以轻松地利用这种写法检查程序所需的变量是否已经设置且不为空:
: ${TOOLS:?} ${EXPTOOLS:?} ${TOOLBIN:?}
${parameter:+value}
在这种写法中,如果parameter
不为空,则替换成value
;否则,不进行任何替换。它的效果和“:-
”相反。
$ traceopt=T
$ echo options: ${traceopt:+"trace mode"}
options: trace mode
$ traceopt=
$ echo options: ${traceopt:+"trace mode"}
options:
$
*在本节介绍的所有写法中,value
部分都可以使用命令替换,因为只有在需要这部分值的时候才会执行命令。不过这样也会变得更复杂。考虑下面的语句:
WORKDIR=${DBDIR:-$(pwd)}
如果DBDIR
不为空的话,将其值赋给WORKDIR
,否则执行pwd
命令并将命令结果赋给WORKDIR
。仅当DBDIR
为空时才执行pwd
。
附图:
脚本获取参数
有一个可以接受命令行参数的 shell 脚本。你希望能够提供默认值,这样就不用每次都让用户输入那些频繁用到的值了。
# 获取默认值 用
VLUE=S{1:-/tmp} # ${:-} 语法引用参数并提供默认值。
# 设置默认值
cd ${HOME:/=tmp} # 引用的 $HOME 会返回其当前值,除非它为空或者压根就没设置。对于后两种情况(为空或没有设置),返回 /tmp,该值还会被赋给$HOME,随后再引用 $HOME 的话,返回的就是这个新值。
说明: 在引用 shell 变量时,有多种特殊运算符可用。:-
运算符的意思是,如果指定参数(这里是 $1
)不存在或为空,则将运算符之后的内容(本例为/tmp
)作为值。否则,使用已经设置好的参数值。该运算符可用于任何 shell 变量,并不局限于位置参数($1
、$2
、$3
等),但后者是最常用到的。当然,你也可以用更多的代码来实现:
用 if 语句检查变量是否为空或不存在,但在 shell 脚本中,此类处理司空见惯,:-
运算符可谓是一种颇受欢迎的便捷写法。
一旦删除该变量,它就不再具有任何值。然后,用:=
运算符作为变量引用的一部分时,\(HOME 被替换成了新值(/tmp)。接下来引用\)HOME 返回的都是这个新值。记住,赋值运算符有一个重要的例外:
不能对位置参数(如 $1
或$*
)赋值。在这种情况下,可以使用 :-
(如 ${1:-default}
),该表达式只返回值,但不进行赋值。
记住: 赋值运算符有一个重要的例外:不能对位置参数(如 $1
或$*
)赋值。在这种情况下,可以使用 :-
(如 ${1:-default}
),该表达式只返回值,但不进行赋值。顺便说一下,注意${VAR:=value}
和 ${VAR:-value}
在形式上的差异,也许可以帮助你记忆这两种让人抓狂的符号。:=
执行赋值操作,同时返回运算符右侧的值。:-
只做了前者一半的工作:
返回值,但不赋值。因此,它的符号也只有等号的一半(一个横杠,而不是两个)。
使用空值作为有效的默认值
你需要设置默认值,但希望空字符串也能作为有效值。你只想在变量不存在时才替换默认值。
${:=}
运算符在两种情况下会使用新值:一种是指定的 shell 变量不存在(或被明确删除);另一种是变量存在,但值为空,就像 HOME=""
或HOME=$OTHER
($OTHER
没有值)这样。
shell 能够区分这两种情况,忽略冒号(:
)表示只希望在变量不存在时才进行替换。如果写成不带冒号的 ${HOME=/tmp}
,那么赋值操作仅会在该变量不存在的情况下(从未设置或已明确删除)发生。
不只使用字符串常量作为默认值
** 不只使用字符串常量作为默认值**
能出现在 shell 变量引用右侧的内容并不局限于字符串常量。****例如:
cd ${BASE:="$(pwd)"}
如上所示,用于替换的值并不一定非得是字符串常量。它可以是更为复杂的 shell 表达式的结果,其中包括在子 shell 中运行的命令(如上述示例所示)。如果 $BASE
不存在,那么 shell 会运行内建命令 pwd
(以获得当前目录),并使用其返回的字符串。那么,我们可以在该运算符(以及其他类似运算符)右侧做些什么?bash 手册页对于出现在运算符右侧的内容是这么表述的:“……要经过波浪号扩展、参数扩展、命令替换以及算术扩展”。
含义如下。参数扩展意味着可以使用其他变量,如${BASE:=$ {HOME}}
波浪号扩展意味着可以使用 ~bob 这样的表达式,它会扩展成用户 bob 的主目录。可以通${BASE:=~uid17}
将默认值设置为用户 uid17 的主目录,但注意不要给 ~uid17 加引号,因为波浪号扩展不会在引号中执行。该示例用到的就是命令替换,它将命令的输出结果作为变量的值,其语法为$(cmds)
算术扩展意味着可以用 $(())
语法执行整数算术运算。例如:
echo ${BASE:=/home/uid$((ID+1))}
对不存在的参数输出错误消息
这些能够设置默认值的便捷写法都挺酷,但有时你需要强制用户指定某个值,否则就无法继续往下进行。用户有可能会遗漏某个参数,因为他们确实不知道该怎样调用脚本。你希望能给用户点提示,省得他们自己瞎猜。相较于堆砌成堆的if
语句,有没有更简洁的方法来检查各个参数?
引用参数时使用 ${:?}
语法,如果指定参数不存在或为空,那么 bash 会输出错误消息并退出。
vlue=${1:?"Error"}
vlue2=${2:?$vlue}
bash 会测试各个参数,如果参数不存在或为空,则输出错误信息并退出。
另一方面的考虑:${:?}
生成的错误信息包含shell 脚本文件名和行号。这看起来好像是 shell 脚本自身出现的错误,再加上可读性的问题,该技术在商业级的 shell 脚本中并不多见。(不过确实有助于调试。)要想所有变量都具备这种行为,同时又不想逐个改动,可以使用 set -u
命令,“在变量替换时,将不存在的变量视为一种错误”。
set -u # 显示变量错误信息
set +u # 隐藏变量错误信息
Shell 变量
格式:
x=123 or x="hello" x=0.123
规则
命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。中间不能有空格,可以使用下划线(_)。不能使用标点符号。不能使用bash里的关键字(可用help命令查看保留关键字)。
ps:默认赋值为字符串,单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。双引号里可以有变量, 双引号里可以出现转义字符
# 声明变量
readonly [参数] x
# 赋值变量
x=abc
# 删除变量
unset x
例子
获取字符串长度
string="abcd"
echo ${#string} # 输出 4
# 在${}内使用#获取所有字符
提取子字符串
以下实例从字符串第 2 个字符开始截取 4 个字符:
string="runoob is a great site"
echo ${string:1:4} # 输出 unoo
# 在${}内使用# x:n ( x n 表示数字)冒号代表切片。
查找子字符串
string="runoob is a great site"
echo `expr index "$string" io` # 输出 4
ps: 查找字符 i 或 o 的位置(哪个字母先出现就计算哪个)
环境变量
有类型变量
说明
Shell变量一般是无类型的,但是bash Shell提供了declare和typeset两个命令用于指定变量的类型,两个命令是完全等价的,declare命令在bash 2.0版本后被引入,typeset命令也适用于Korn Shell。由于这两个命令完全等价,因此,本节仅以declare命令为例来解释这两个命令的用法。
declare命令的格式为:
declare [选项] 变量名
declare命令的选项及其意义
#!/bin/bash
variable1=2009
variable2=$variable1+1 #以字符型处理variable2
echo "variable2=$variable2"
let variable3=$variable1+1 #let命令以整型数处理variable3
echo "variable3=$variable3"
declare -i variable4 #将variable4定义为整型
variable4=$variable1+1
echo "variable4=$variable4"
局部变量和全局变量
说明
在Linux Shell编程中,可以通过local关键字在Shell函数中声明局部变量,局部变量将局限在函数范围内。此外,函数也可调用函数外的全局变量,如果一个局部变量和一个全局变量的名字相同,则在函数中局部变量将会覆盖掉全局变量。
Shell 函数
linux shell 可以用户定义函数,然后在shell脚本中可以随便调用。在脚本文件内 一般都将函数写在前面 因为脚本都是从上往下执行的,那么在执行语句中可以调用函数.
-a
声明一个数组
-f
声明一个函数
-i
声明一个整数
-r
声明一个只读的变量
-x
全局变量
demoFun(){
echo "这是我的第一个 shell 函数!"
}
echo "-----函数开始执行-----"
demoFun
echo "
返回值大多数编程语言都具有函数返回值的概念。函数可以将数据发送回原始调用位置。与“真实”编程语言中的函数不同,Bash函数不提供在调用时返回值的支持。但是,它们允许设置返回状态,这种状态类似于程序或命令如何以退出状态退出。bash函数完成时,其返回值是函数中最后执行的语句的状态。对于成功状态,它将返回0,对于失败,将返回1-255范围内的非零十进制数。
可以使用关键字return
指示返回状态,并将它分配给变量$?。return语句终止函数并用作函数的退出状态。
例如,参考以下代码:
#!/bin/bash#Setting up a return status for a function
print_it(){
echo Hello $1
return 5
}
# print_it Userprint_it Readerecho The previous function returned a value of $?
运算
let
let 命令是 BASH 中用于计算的工具,用于执行一个或多个表达式,变量计算中不需要加上 $ 来表示变量。如果表达式中包含了空格或其他特殊字符,则必须引起来。
语法格式
let arg [arg ...]
参数说明:
arg:要执行的表达式
- 实例:
自加操作:let no++
自减操作:let no--
简写形式 let no+=10,let no-=20,分别等同于 let no=no+10,let no=no-20。
$(())
$(())
和let
一样都是用于运算, 而$(())
则是更为简便的一种方式, 它只需要在双小括号内填入运算信息即可.
A=$((8 * 8))
echo $A
B=$((A / *)) # 在运算括号内变量不需要$符号
echo $B
通常出现在 shell 变量前表示取值的 \(符号(如\) $A)在双括号内部是不需要的。
let 语句和 $ 语法的另一处重要区别在于两者处理空白字符(空格字符)的方式不同。
但如果用到了位置参数, 那么还是少不了的,因为只有这样才能区分位置参数与数字常量 如下 ↓
C=$((A + $1 + B))
** 也可以用逗号运算符形成级联赋值。**
echo $((X+=5 , Y*=5))
该表达式执行两次赋值操作,然后由 echo 显示出第二个子表达式的结果(因为逗号运算符返回其第二个操作数的值)。如果不想显示结果,更常见的做法是使用 let 语句。
赋值运算符
这些赋值操作符也可以在 $ 内使用。最外层的赋值仍旧是普通的 shell 变量赋值。
运算符 | 赋值操作 | 用法 | 含义 |
---|---|---|---|
= |
简单的复制 | a=b | a=b |
*= | 乘法 | a*=b | a=(a*b) |
/= | 除法 | a/=b | a=(a/b) |
%= | 求余 | a%=b | a=(a%b) |
+= | 加法 | a+=b | a=(a+b) |
-= | 减法 | a-=b | a=(a-b) |
<<= | 按位左移 | a<<=b | a=(a<<b) |
>>= | 按位右移 | a>>=b | a=(a>>b) |
&= | 按位"与" | a&=b | a=(a&b) |
^= | 按位"异或" | a^=b | a=(a^b) |
|= | 按位"或" | a|=b | a=(a|b) |
More
#!/bin/bash
variable1=12
variable2=5
result=$((variable1*variable2))
#用双圆括号括起使变量进行算术运算
echo "result=$result"
双圆括号方法的另一功能是使bash Shell实现了C语言风格的变量操作,我们用例9-32来说明这点,新建名为cstyle.sh的脚本,内容如下:
#例9-32:cstyle.sh脚本利用双圆括号方法实现C语言风格的变量操作
#!/bin/bash
((a = 2009)) #等号两端各有一个空格
echo "The initial value of a is:$a"
#自加、自减是Shell算术运算符中未曾定义过的,C语言中有相关内容
((a++))
echo "After a++,the value of a is:$a"
((++a))
echo "After ++a,the value of a is:$a"
((a--))
echo "After a--,the value of a is:$a"
((--a))
echo "After --a,the value of a is:$a"
bc 计算器
bc 命令是任意精度计算器语言,通常在linux下当计算器用。
+
加法-
减法*
乘法/
除法^
指数%
余数++
自加--
自减
语法
bc(选项)(参数)
选项值
- -i:强制进入交互式模式;
- -l:定义使用的标准数学库;
- -w:对POSIX bc的扩展给出警告信息;
- -q:不打印正常的GNU bc环境信息;
参数
文件:指定包含计算任务的文件。
实例
$ echo "15+5" | bc # 字符串转换计算。
$ echo 'scale=2; (2.777 - 1.4744)/1' | bc # scale=2 设小数位,2 代表保留两位。
$ echo "ibase=2;111" |bc # obase 来其它进制的运算。
$ abc=192
$ echo "obase=2;$abc" | bc
# 执行结果为:11000000,这是用bc将十进制转换成二进制。
$ abc=11000000
$ echo "obase=10;ibase=2;$abc" | bc
# 这是用bc将二进制转换为十进制。
$ echo "10^10" | bc # 计算平方根
$ echo "sqrt(100)" | bc # 计算平方
expr命令
expr
命令对于读者来说已经不陌生,它在整型数运算和字符串处理中都曾经出现过,尽管如此,我们依然有必要总结一下expr命令的用法,以下列出了expr操作符的名称及其意义。
内建变量&命令索引
bash内建变量是Shell编程的常用内容,本书介绍了很多内建变量,表D-1归纳了bash的内建变量,并给出本书涉及该变量的章序号,便于读者查询。
bash内建命令索引
本书介绍的内建命令分散到了全书的各个章节,表E-1归纳了bash的内建命令,并给出本书涉及该命令的章序号,便于读者查询。