有关 linux 下 shell 的用法。

Shell字符串比较相等、不相等

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#!/bin/sh

#测试各种字符串比较操作。
#shell中对变量的值添加单引号,爽引号和不添加的区别:对类型来说是无关的,即不是添加了引号就变成了字符串类型,
#单引号不对相关量进行替换,如不对$符号解释成变量引用,从而用对应变量的值替代,双引号则会进行替代
#author:tenfyguo

A="$1"
B="$2"

echo "输入的原始值:A=$A,B=$B"

#判断字符串是否相等
if [ "$A" = "$B" ];then
echo "[ = ]"
fi

#判断字符串是否相等,与上面的=等价
if [ "$A" == "$B" ];then
echo "[ == ]"
fi

#注意:==的功能在[[]]和[]中的行为是不同的,如下

#如果$a以”a”开头(模式匹配)那么将为true
if [[ "$A" == a* ]];then
echo "[[ ==a* ]]"
fi

#如果$a等于a*(字符匹配),那么结果为true
if [[ "$A" == "a*" ]];then
echo "==/"a*/""
fi

#File globbing(通配) 和word splitting将会发生, 此时的a*会自动匹配到对应的当前以a开头的文件
#如在当前的目录中有个文件:add_crontab.sh,则下面会输出ok
#if [ "add_crontab.sh" == a* ];then
#echo "ok"
#fi
if [ "$A" == a* ];then
echo "[ ==a* ]"
fi

#如果$a等于a*(字符匹配),那么结果为true
if [ "$A" == "a*" ];then
echo "==/"a*/""
fi

#字符串不相等
if [ "$A" != "$B" ];then
echo "[ != ]"
fi

#字符串不相等
if [[ "$A" != "$B" ]];then
echo "[[ != ]]"
fi

#字符串不为空,长度不为0
if [ -n "$A" ];then
echo "[ -n ]"
fi

#字符串为空.就是长度为0.
if [ -z "$A" ];then
echo "[ -z ]"
fi

#需要转义<,否则认为是一个重定向符号
if [ $A /< $B ];then
echo "[ < ]"
fi

if [[ $A < $B ]];then
echo "[[ < ]]"
fi

#需要转义>,否则认为是一个重定向符号
if [ $A /> $B ];then
echo "[ > ]"
fi

if [[ $A > $B ]];then
echo "[[ > ]]"
fi

字符串比较,注意的几点

1
2
3
if [ "$A" = "$B" ];then
echo "[ = ]"
fi
  1. if 和 [ ] 之间要有空格
  2. [ ] 和“ ”之间要有空格
  3. “ ”和 = 之间要有空格
    否则都会报错

Shell分支语句 case···esac 语法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
case 值 in
模式1)
command1
command2
command3
;;
模式2)
command1
command2
command3
;;
*)
command1
command2
command3
;;
esac

# 匹配发现取值符合某一模式后,其间所有命令开始执行直至 ;;。
# ;; 与其他语言中的 break 类似,意思是不执行接下来的语句而是跳到整个 case 语句的最后。
# *)与default相似,如果上面没有匹配到的模式,则执行*)里的内容。

说明:case后为取值,值后为关键字 in,接下来是匹配的各种模式,每一模式最后必须以右括号结束。
值可以为变量或常数。

模式支持正则表达式,可以用以下字符:

1
2
3
4
5
*       任意字串
? 任意字元
[abc] a, b, 或c三字元其中之一
[a-n] 从a到n的任一字元
| 多重选择

举例:

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/sh 

case $1 in
start | begin)
echo "I am started!"
;;
stop | end)
echo "I am stopped!"
;;
*)
echo "Other command!"
;;
esac

/bin/bash^M: bad interpreter: No such file or directory

用 WebStorm 安装 shell 插件后,直接创建的 sh 文件,上传至服务器,执行时报错如下:

1
-bash: ./syncToGiteeAsUTomcat.sh: /bin/bash^M: bad interpreter: No such file or directory

删除第一行,则报错如下:

1
2
3
4
5
./syncToGiteeAsUTomcat.sh: line 4: $'\r': command not found
./syncToGiteeAsUTomcat.sh: line 6: $'\r': command not found
./syncToGiteeAsUTomcat.sh: line 7: syntax error near unexpected token `$'{\r''
'/syncToGiteeAsUTomcat.sh: line 7: `pullLocalAndPushToGitee() {
}

解决:

  1. 在终端 vim 一个文件,将代码粘贴进去,保存。
  2. 或者,在终端 vim 一个文件,sz 到本地,然后再将代码粘贴进去,上传。

root 用户,以另外一个用户的身份执行脚本

1
2
3
[root@centOS7BasicForTest source]# su - utomcat -lc "git push hjz"
fatal: not a git repository (or any parent up to mount point /)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).

su -utomcat 会切换到用户主目录,所以提示并不是 git 仓库。
解决办法:
把需要的脚本放到一个 shell 文件,在 shell 脚本文件中 cd 到项目目录,再执行相关操作指令。

特殊变量列表

变量 含义
$0 当前脚本的文件名
$n 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。
$# 传递给脚本或函数的参数个数。
$* 传递给脚本或函数的所有参数。
$@ 传递给脚本或函数的所有参数。被双引号(“ “)包含时,与 $* 稍有不同,下面将会讲到。
$? 上个命令的退出状态,或函数的返回值。
$$ 当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。

查目录下的文件个数

1
2
3
4
5
6
7
8
9
#以下命令均不包含".",".."目录,以及"."开头的隐藏文件,如需包含,ll 需要加上 -a参数
#当前目录下文件个数,不包含子目录
ll |grep "^-"|wc -l
#当前目录下目录个数,不包含子目录
ll |grep "^d"|wc -l
#当前目录下文件个数,包含子目录
ll -R|grep "^-"|wc -l
#当前目录下目录个数,包含子目录
ll -R|grep "^d"|wc -l

变量

变量名=变量值
注意:变量名前面不应加美元“$”符号。(和PHP不同)
等号“=”前后不可以有空格。
和C语言不同,Shell中不需要显式的语法来声明变量。
变量名不可以直接和其他字符相连,如果想相连,必须用括号:echo “this is $(he)llo!”

linux下移动隐藏文件夹的操作

1
mv * .[^.]* directory

其中,directory 是要移到的目标文件夹。

命令解释:

  1. mv 命令的最后一个参数是要移动文件的目标位置。
  2. 第一个 * 匹配除了隐藏文件的所有文件。
  3. 隐藏文件使用 .[^.]* 匹配。
  4. 匹配隐藏文件用 .[^.]*,为什么不用 .*,因为 .* 会匹配目录 ...
  5. .[^.]* 的意思是:以 . 开头,加不是 . 的一个任意字符,再加其他任意字符。

如果知道隐藏文件夹名,则直接写就好了,比如:

1
mv * .git directory

逻辑非、逻辑与、逻辑或

  1. 逻辑非: !

    1
    2
    if [ !表达式 ]
    if [ !-d $num ] 如果不存在目录$num
  2. 逻辑与:–a
    if [表达式1 –a 表达式2]1. 逻辑或:-o
    if [表达式1 –o 表达式2]

linux shell 中的sleep命令

  • sleep 1 睡眠1秒
  • sleep 1s 睡眠1秒
  • sleep 1m 睡眠1分
  • sleep 1h 睡眠1小时

清空文本文件内容

  • : > filename> filename: 清空 filename,如果文件不存在,则创建文件,“:”与“>”之间有无空格均可,“:”充当虚拟占位符,不产生任何输出。
  • true > filename:类似 :> filename
  • truncate -s 0 filename:truncate 用于调整文件大小,-s 0,设置文件大小为0字节
  • rf -f filename && touch filename:通过删除原文件,再创建同名文件的方式清空文件

> filename,这种方式最简洁,敲键盘次数最少,不过,某些 shell 中可能无法正常运行,如果 > filename 无法正常运行,就用 :> filename: 是 shell 内建命令,不需要安装额外的工具。