打造高效的工作环境 – Shell 篇 | 酷 壳 - CoolShell
Shell echo 命令
Shell 的 echo 指令与 PHP 的 echo 指令类似,都是用于字符串的输出。命令格式:
echo string
显示普通字符串
# 几个一样的结果
echo "It is a test"
echo It\ is\ a\ test
echo It is a test显示转义字符
echo "\"It is a test\"" # 双引号也可以省略
---
"It is a test"显示变量
#!/bin/sh
name="Hello!"
echo "$name It is a test"显示换行
echo -e "OK! \n" # -e 开启转义
echo "It is a test"
---
OK!
It is a test显示不换行
#!/bin/sh
echo -e "OK! \c" # -e 开启转义 \c 不换行
echo "It is a test"
---
OK! It is a test显示结果定向至文件
echo "It is a test" > myfile原样输出字符串,不进行转义或取变量
echo '$name\"'
---
$name\"显示命令执行结果
echo `date` # 这里使用的是反引号 `, 而不是单引号 '。
---
Thu Jul 24 10:08:46 CST 2014其他
echo "hello" # hello
echo $? # 0
grep foobar mcd.sh
echo $? # 1
true
echo $? # 0
false
echo $? # 1
false || echo "Oops failed" # 或操作
false && echo "Oops failed" # 且操作
false ; echo "Oops failed" # 分割Shell read 命令
read 命令一个一个词组地接收输入的参数,每个词组需要使用空格进行分隔;如果输入的词组个数大于需要的参数个数,则多出的词组将被作为整体为最后一个参数接收。
# test.sh
read firstStr secondStr
echo "第一个参数:$firstStr; 第二个参数:$secondStr"
$ sh test.sh
一 二 三 四
第一个参数:一; 第二个参数:二 三 四read 命令的参数:
- -p 输入提示文字
- -n 输入字符长度限制(达到 6 位,自动结束)
- -t 输入限时
- -s 隐藏输入内容
read -p "请输入一段文字:" -n 6 -t 5 -s password
echo -e "\npassword is $password"
$ sh test.sh
请输入一段文字:
password is asdfghShell test 命令
Shell 中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。
数值测试
-eq、-ne、-gt、-lt、-ge、-le运算符:等于、不等于、大于、小于、大于等于、小于等于
num1=100
num2=100
if test $[num1] -eq $[num2]
then
echo '两个数相等!'
else
echo '两个数不相等!'
fi字符串测试
=—— 等于 = True!=—— 不想等 = True-z 字符串—— 字符串长度为零 = True-n 字符串—— 字符串长度不为零 = True
num1="ru1noob"
num2="runoob"
if test $num1 = $num2
then
echo '两个字符串相等!'
else
echo '两个字符串不相等!'
fi文件测试
-e 对象存在
-d 对象存在 & 属于目录
-f 对象存在 & 属于常规文件
-L 对象存在 & 属于符号链接
-h 对象存在 & 属于软链接
-s 对象存在 & 长度不为0
-r 对象存在 & 可读
-w 对象存在 & 可写
-x 对象存在 & 可执行
-O 对象存在 & 属于当前用户
-G 对象存在 & 属于当前用户组
-c 对象存在 & 属于字符型特殊文件
-b 对象存在 & 属于块特殊文件
-nt 判断file1是否比file2新 [ "/data/file1" -nt "/data/file2" ]
-ot 判断file1是否比file2旧 [ "/data/file1" -ot "/data/file2" ]cd /bin
if test -e ./bash
then
echo '文件已存在!'
else
echo '文件不存在!'
fi逻辑操作
Shell 还提供了与( -a )、或( -o )、非( ! )三个逻辑操作符用于将测试条件连接起来,其优先级为: ! 最高, -a 次之, -o 最低。例如:
cd /bin
if test -e ./notFile -o -e ./bash
then
echo '至少有一个文件存在!'
else
echo '两个文件都不存在'
fiShell printf 命令
- printf 命令模仿 C 程序库(library)里的 printf() 程序。
- printf 由 POSIX 标准所定义,因此使用 printf 的脚本比使用 echo 移植性好。
- printf 使用引用文本或空格分隔的参数,外面可以在 printf 中使用格式化字符串,还可以制定字符串的宽度、左右对齐方式等。默认的 printf 不会像 echo 自动添加换行符,我们可以手动添加
\n。
printf format-string [arguments...]
printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg
printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234
printf "%-10s %-8s %-4.2f\n" 杨过 男 48.6543
printf "%-10s %-8s %-4.2f\n" 郭芙 女 47.9876格式替代符
%-10s指一个宽度为 10 个字符(- 表示左对齐,没有则表示右对齐),任何字符都会被显示在 10 个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。%-4.2f指格式化为小数,其中 .2 指保留 2 位小数。- %d: Decimal 十进制整数 — 对应位置参数必须是十进制整数,否则报错!
- %s: String 字符串 — 对应位置参数必须是字符串或者字符型,否则报错!
- %c: Char 字符 — 对应位置参数必须是字符串或者字符型,自动截取字符串的第一个字符,否则报错!
- %f: Float 浮点 — 对应位置参数必须是数字型,默认显示 6 位小数,否则报错!
- %b: 字符串 — 相对应的参数被视为含有要被处理的转义序列之字符串
#!/bin/bash
# format-string为双引号
printf "%d %s\n" 1 "abc"
# 单引号与双引号效果一样
printf '%d %s\n' 1 "abc"
# 没有引号也可以输出
printf %s abcdef
# 格式只指定了一个参数,但多出的参数仍然会按照该格式输出,format-string 被重用
printf %s abc def
# abcdef
printf "%s\n" abc def
# abc
# def
printf "%s %s %s\n" a b c d e f g h i
# a b c
# d e f
# g h i
# 如果没有 arguments,那么 %s 用NULL代替,%d 用 0 代替
printf "%s and %d \n"
# and 0
# %c 只会截取第一个字符使用
printf "%d %s %c\n" 1 "abc" "def"
# 1 abc d
# %b 进行转义字符
printf "a string, no processing: < %b >\n" "A\nB"
# a string, no processing:< A
# B >转义序列
| 序列 | 说明 |
|---|---|
\a | 警告字符,通常为 ASCII 的 BEL 字符 |
\b | 后退 |
\c | 抑制(不显示)输出结果中任何结尾的换行字符(只在%b 格式指示符控制下的参数字符串中有效),而且,任何留在参数里的字符、任何接下来的参数以及任何留在格式字符串中的字符,都被忽略 |
\f | 换页(formfeed) |
\n | 换行 |
\r | 回车(Carriage return) |
\t | 水平制表符 |
\v | 垂直制表符 |
\\ | 一个字面上的反斜杠字符 |
\ddd | 表示 1 到 3 位数八进制值的字符。仅在格式字符串中有效 |
\0ddd | 表示 1 到 3 位的八进制值字符 |
查找文件
find 命令
程序员们面对的最常见的重复任务就是查找文件或目录。所有的类 UNIX 系统都包含一个名为 find 的工具,它是 shell 上用于查找文件的绝佳工具。find 命令会递归地搜索符合条件的文件,例如:
# 查找所有名称为src的文件夹
find . -name src -type d
# 查找所有文件夹路径中包含test的python文件
find . -path '*/test/*.py' -type f
# 查找前一天修改的所有文件
find . -mtime -1
# 查找所有大小在500k至10M的tar.gz文件
find . -size +500k -size -10M -name '*.tar.gz'除了列出所寻找的文件之外,find 还能对所有查找到的文件进行操作。这能极大地简化一些单调的任务。
# 删除全部扩展名为.tmp 的文件
find . -name '*.tmp' -exec rm {} \;
# 查找全部的 PNG 文件并将其转换为 JPG
find . -name '*.png' -exec convert {} {}.jpg \;尽管 find 用途广泛,它的语法却比较难以记忆。例如,为了查找满足模式 PATTERN 的文件,您需要执行 find -name '*PATTERN*' (如果您希望模式匹配时是不区分大小写,可以使用 -iname 选项)
fd 命令
例如,fd 就是一个更简单、更快速、更友好的程序,它可以用来作为 find 的替代品。它有很多不错的默认设置,例如输出着色、默认支持正则匹配、支持 unicode 并且我认为它的语法更符合直觉。以模式 PATTERN 搜索的语法是 fd PATTERN。
locate 命令
这就要靠 locate 了。 locate 使用一个由 updatedb 负责更新的数据库,在大多数系统中 updatedb 都会通过 cron 每日更新。这便需要我们在速度和时效性之间作出权衡。而且,find 和类似的工具可以通过别的属性比如文件大小、修改时间或是权限来查找文件,locate 则只能通过文件名。 这里有一个更详细的对比。
man & tldr 命令
在上一节中我们介绍过,最常用的方法是为对应的命令行添加 -h 或 --help 标记。另外一个更详细的方法则是使用 man 命令。man 命令是手册(manual)的缩写,它提供了命令的用户手册。
例如,man rm 会输出命令 rm 的说明,同时还有其标记列表,包括之前我们介绍过的 -i。事实上,目前我们给出的所有命令的说明链接,都是网页版的 Linux 命令手册。即使是您安装的第三方命令,前提是开发者编写了手册并将其包含在了安装包中。在交互式的、基于字符处理的终端窗口中,一般也可以通过 :help 命令或键入 ? 来获取帮助。
有时候手册内容太过详实,让我们难以在其中查找哪些最常用的标记和语法。 TLDR pages 是一个很不错的替代品,它提供了一些案例,可以帮助您快速找到正确的选项。