Linux常用命令

0. 在线使用 Linux Shell

参考 https://www.sohu.com/a/343421845_298038

JS/UIX - Terminal

地址:https://www.masswerk.at/jsuix/index.html

进入后,点击open terminal即可。它提供简单的终端环境,没有自带gcc等编译套件,不过练习基本命令和shell脚本还是可以的。

1. 常用命令

1.1 ls 命令 - 显示指定工作目录下的内容

详见 https://www.runoob.com/linux/linux-comm-ls.html

显示指定工作目录下的内容(列出目前工作目录所含之文件及子目录)

语法:

1
2
3
4
5
6
7
8
9
10
11
12
ls [-alrtAFR] [name...]

参数:
-a: 显示所有文件及目录 (.开头的隐藏文件也会列出)
-l: 除文件名称外,亦将文件型态、权限、拥有者、文件大小等资讯详细列出

ls -l 可写作 ll

常用写法:
ll
ls -al

1613903492422

结合 grep 使用:

查看文件 log.txt 是否存在于当前目录下:

1
2
3
4
>ls | grep log.txt
log.txt
>ls -al | grep log.txt
-rw-rw-r--. 1 mozhiyan mozhiyan 0 4月 15 17:26 log.txt

1.2 查看文件内容:cat

1613903531146

1.3 创建文件: touch

1613903625026

此时,若想往text2中写入内容,可用 echo "hello word">>text2

1613903728662

>>代表在末尾追加,若使用>则会把之前的内容覆盖

1613903859605

当然,也可直接vim text2对文件进行编辑

注:无论是 echo "hello">file 还是 echo "hello">>file ,如果file不存在都会先创建file文件

类似的用法有:cat ./result.lst>>aa.txt(将result.lst文件中的内容追加到aa.txt的末尾)

1613904004258

1.4 mv - 为文件或目录改名、或将文件或目录移入其它位置

详见 https://www.runoob.com/linux/linux-comm-mv.html

1613904102186

1613904249971

👆注:若test目录不存在,则该命令将text4重命名为test

1613904395981

1.5 rm - 删除一个文件或者目录

详见 https://www.runoob.com/linux/linux-comm-rm.html

删除文件:rm 文件名

删除文件夹:rm -r 文件夹名。-r 将目录及以下之档案亦逐一删除

1613904534240

1613904600604

-f 直接删除,无需逐一确认,见如下示例:

1613904845877

1.6 cp - 复制文件或文件夹

语法:

1
2
3
4
5
6
7
8
9
10
cp [options] source dest

参数:
-a:此选项通常在复制目录时使用,它保留链接、文件属性,并复制目录下的所有内容。其作用等于dpR参数组合。
-d:复制时保留链接。这里所说的链接相当于 Windows 系统中的快捷方式。
-f:覆盖已经存在的目标文件而不给出提示。
-i:与 -f 选项相反,在覆盖目标文件之前给出提示,要求用户确认是否覆盖,回答 y 时目标文件将被覆盖。
-p:除复制文件的内容外,还把修改时间和访问权限也复制到新文件中。
-r:若给出的源文件是一个目录文件,此时将复制该目录下所有的子目录和文件。
-l:不复制文件,只是生成链接文件。

例如,将当前路径下的a.txt复制到另外一个文件夹下:

1
>cp a.txt /data/test/

将文件夹xgb_pipeline复制到另一个路径下:

1
>cp -r xgb_pipeline /data/test/

将当前路径下的多个文件复制到另一个路径下:

1
>cp a.txt b.json /data/test/

2. 压缩打包命令 - tar、zip、unzip

来自 https://blog.csdn.net/weixin_44901564/article/details/99682926

打包与压缩的区别:

打包是指将多个文件或者目录放在一起,形成一个总的包,这样便于保存和传输,但是大小是没有变化的,压缩是指将一个或者多个大文件或者目录通过压缩算法使文件的体积变小以达到压缩的目的,可以节省存储空间。

tar命令可以进行打包或压缩、解压,zip与unzip主要进行压缩与解压。 (用于压缩时,tar与zip的主要区别:tar命令主要用于unix系统下,zip命令主要用于windows 系统下。例如想要在unix系统压缩文件后传给windows系统使用,一般会使用zip命令,进行解压更加方便)

2.1 tar命令

tar命令常用参数

参数 描述
-z 是否同时具有gz属性
-j 是否同时具有bz2属性
-J 是否同时具有xz属性
-x 解压缩、提取打包的内容
-t 查看压缩包内容
-c 建立一个压缩,打包文档
-C 切换到指定目录,表示指定解压缩包的内容和打包的内容存放的目录
-v 显示压缩或者打包的内容
-f 使用文件名,在f后面要接压缩后的文件的名字,只要用到tar命令,-f选项是必须要用的,-f参数在使用的时候一定排在其他参数的后面,在最右边
-p 保留备份数据的原本权限与属性,常用于备份(-c)重要的配置文件
-P 保留绝对路径
2.1.1 打包

1613918040999

2.1.2 压缩

linux主要有三种压缩方式: 1.gzip:是公认的压缩速度最快,压缩大文件的时候与其他的压缩方式相比更加明显,历史最久,应用最广泛的压缩方式 2.bzip:压缩形成的文件小,但是可用性不如gzip 3.xz:是最新的压缩方式,可以自动提供最佳的压缩率

建议压缩的时候标明后缀:

参数 作用 命名方式
-z 用于gzip压缩方式 文件名.tar.gz
-j 用于bzip2压缩方式 文件名.tar.bz2
-J 用于xz压缩方式 文件名.tar.xz

1613918385198

1613918409030

2.1.3 解压

1613918570956

tar命令在解压时不需要指明压缩的方式,它会自己选择跟压缩方式对应的方式去解压

1613918627839

👆原文中未给出命令,猜测为 tar -xf Golden.apk.tar.gz

1613918698529

2.1.4 补充

a.在打包和压缩的过程中,我们有时会看到这样的语句:tar: 从成员名中删除开头的“/”,这个并不是报错,是因为没有加上-P选项,没有保留原来的绝对路径去打包或者压缩,提取打包的内容跟解压一样,下面举一个例子:

1613919006930

1613919034567

解压的时候同理,如果在压缩文件的时候使用了-P选项,那么在解压时也要加上-P选项,不然也会出现tar: 从成员名中删除开头的“/”

b.在使用tar压缩或者打包的时候,可以通过增加 --exclude 来达到排除指定的文件的目的

1613919127279

压缩文件 与 想要排除指定的目录压缩或者打包 同理

  1. 使用 -r 选项增加.tar归档文件的内容

通过 tar --help 命令查看帮助

-r 选项的作用:把要存档的文件追加到档案文件的未尾。例如用户已经作好备份文件,又发现还有一个目录或是一些文件忘记备份了,这时可以使用该选项,将忘记的目录或文件追加到备份文件中

1613920583973

使用实例:

1613920618990

(先将1进行归档,再追加2)

1.归档操作

1613920677791

生成.tar文件,目录归档完毕

2.将calculating_time.sh追加进入.tar文件中

1613920716990

查看.tar文件的归档信息:

1613920751128

可以看到calculating_time.sh文件已经被追加到档案的末尾了

提取Check_Configuration_20201118_PM.tar 到/mnt目录下:

1613920796143

使用-r选项追加文件至.tar文件成功

2.2 zip命令和unzip命令

在使用 zip 跟 unzip 命令之前先查看系统有没有安装这两个命令的包,没有的话要自己安装 查看有没有安装zip跟unzip命令的命令:

rpm -q zip unzip

如果安装了,则会显示出命令的版本号

1613919407899

2.2.1 zip命令

基本用法:

1
zip [参数] [压缩包名] [压缩的目录或者文件的路径]

示例:

1
>zip -r xgb_pipeline.zip xgb_pipeline

zip命令常用参数

参数 描述
-m 将文件压缩后,删除原文件
-o 将压缩文件内的所有文件的最新变动时间设为压缩的时间
-q 安静模式,在压缩的时候不显示指令执行的过程
-r 递归压缩,将自定目录下的所有子文件以及文件一起处理
-x ”文件列表“,压缩时排除文件列表中的文件

实例

1613919749742

1613919795113

1613919829367

1613919855669

2.2.2 unzip命令

直接使用:

1
unzip xxx.zip

便可解压到当前目录下。

基本用法:

1
unzip [参数] [压缩文件]  (-d [目录])  //如果不使用括号内的内容,则解压文件到当前工作目录

unzip命令常用参数

参数 描述
-c 将解压缩的结果显示到屏幕上(显示每一个目录下的每一个文件的内容),同时对字符做适当的转换,但是并没有解压压缩包
-l 显示压缩文件内所包含的文件
-t 检查压缩文件是否正确
-v 执行时显示压缩文件的详细信息
-q 安静模式,执行时不显示任何信息
-d 指定文件解压后存储的目录
-x 指定不要处理压缩文件中的那些文件

实例

a.将harry.zip压缩包解压缩的结果显示出来:

1613920145339

具体会显示到每一个文件跟每一个文件的内容

b.显示jihe.zip压缩包里面所包含的文件

1613920185552

c.检查dajihe.zip压缩文件是否正确

1613920223598

全部OK表示全部文件都是正确的

d.不解压压缩文件dajihe.zip,查看压缩包里面的内容(查看显示的文件列表还包含压缩比率)

1613920257695

使用-v显示的信息比使用-l显示的信息更加详细

e.将dajihe.zip压缩包解压到/opt/目录下:

1613920322610

注:

1
2
3
4
5
unzip -l dajihe.zip
unzip -v dajihe.zip
unzip -c dajihe.zip
都不会解压,只是查看
unzip dajihe.zip会解压

3.Linux属主权限,chgrp,chown,chmod

来自 https://www.cnblogs.com/CYHISTW/p/11031429.html

1613905079507

1613905119945

1613905151971

1613905209772

1613905243202

1613905317808

1613905345753

1613905383386

1613905411968

可使用 chmod +x 文件名 使文件变为可执行文件,例如:

1613905651103

1613905697607

输入i进行编辑模式,完成后,按esc再输入:wq 保存并退出

1613905784062

👆可以看到此时run.sh处于不可执行状态

1613905838720

1613905867580

成功执行

4. shell 命令行参数

参考
http://c.biancheng.net/cpp/view/2739.html
http://blog.csdn.net/jake_tian/article/details/97274630

运行脚本时传递给脚本的参数称为命令行参数。

变量 含义
$0 当前脚本的文件名
$n 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,获取第一个参数是$1,获取第二个参数是$2,以此类推
$# 传递给脚本或函数的参数个数
$* 传递给脚本或函数的所有参数。
$@ 传递给脚本或函数的所有参数。被双引号(" ")包含时,与 $* 稍有不同
$? 上个命令的退出状态,或函数的返回值。

例:脚本如下:

1
2
3
4
5
6
7
#!/bin/bash
echo "File Name: $0"
echo "First Parameter : $1"
echo "First Parameter : $2"
echo "Quoted Values: $@"
echo "Quoted Values: $*"
echo "Total Number of Parameters : $#"

运行:

1
2
3
4
5
6
7
$./test.sh Zara Ali
File Name : ./test.sh
First Parameter : Zara
Second Parameter : Ali
Quoted Values: Zara Ali
Quoted Values: Zara Ali
Total Number of Parameters : 2

关于$?:上条命令的返回值。0表示没有错误,其他任何数值表示有错误。

参考
https://blog.csdn.net/aLLLiyyy/article/details/103184367
https://blog.csdn.net/weixin_39928768/article/details/111582889

例如:如果上条命令执行失败,则重复执行,shell脚本如下:

1
2
3
4
5
6
7
python test.py

while(($?==1))
do
sleep 30 # 休眠30s
python test.py
done

5. shell 日期加减运算

参考
http://blog.sina.com.cn/s/blog_ad6555610101b5ud.html
https://www.cnblogs.com/zhzhang/p/6846300.html
https://www.cnblogs.com/simple-li/p/14040777.html
http://www.dutycode.com/post-60.html

假如今天是 2012-04-22

1
2
3
4
5
6
7
8
9
10
11
12
13
$ date -d "+1 day" +%Y-%m-%d
2012-04-23

$ date -d "-1 day" +%Y-%m-%d
2012-04-21

$ date -d "2012-04-10 -1 day" +%Y-%m-%d
2012-04-09

$ date -d "+1 week" +%Y-%m-%d
2012-04-29

同理还可 month, year

例:脚本示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/bin/bash

if [ $# == 0 ] ; then
ydate=`date -d -1days "+%Y%m%d"`
ydateother=`date -d -1days "+%Y-%m-%d"`
tdate=`date -d -0days "+%Y%m%d"`
tdateother=`date -d -0days "+%Y-%m-%d"`
elif [ $# == 1 ] ; then
ydate=$1
ydateother=`date -d ${ydate} +"%Y-%m-%d"`
tdate=`date -d "${ydate} 1days" +"%Y%m%d"`
tdateother=`date -d ${tdate} +"%Y-%m-%d"`
elif [ $# == 2 ] ; then
ydate=$1
ydateother=`date -d ${ydate} +"%Y-%m-%d"`
tdate=$2
tdateother=`date -d ${tdate} +"%Y-%m-%d"`
else
echo "please do not input if calcute yedterday."
echo "please input like if calcute 20170510 one day: 20170510"
echo "please input like if calcute 20170510 and 20170512 two days : 20170510 20170511"
exit -1
fi
echo ${ydate}'--'${ydateother}'--'${tdate}'---'${tdateother}

例: 按月执行201904到202010的py脚本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/bash
i=201904 # 定义开始月份
while [ $i -le 202010 ] # 当i小于等于202010时执行循环语句
do
dateNo1=$(date +"%Y-%m-%d %H:%M:%S") # 获取当前时间(年月日时分秒)
echo "开始执行($dateNo1): $i" # 打印当前时间(年月日时分秒)
python tmp_sn_union_mem_20201125.py $i # 执行python脚本,传入月份参数。 此处也可做其他操作
dateNo2=$(date +"%Y-%m-%d %H:%M:%S") # 获取当前时间(年月日时分秒)
echo "结束执行($dateNo2): $i" # 打印当前时间(年月日时分秒)
i=$[$i + 1] # 当前i值加1
if [ $i -eq 201913 ] # 判断i值是否等于201913,条件必须写在 [] 里
then
i=202001 # 如果i值等于201913,则让i值为202001
fi # if结束标记
done # while结束标记

注:

1
2
3
4
fi                    容易忘记判断结束标记
done 容易忘记循环执行结束标记
i=$[$i + 1] 变量加减运算要写在 $[] 里面。
if [ $i -eq 201913 ] 条件必须写在 [] 里

附:数值比较:

-eq 相等(equal)
-ne 不等(not equal)
-gt 大于(greater than)
-lt 小于(less than)
-ge 大于等于 (greater than or equal)
-le 小于等于 (less than or equal)

注:crontab任务调度中,%是个特殊字符,要在前加""进行转义

例:

1
0 10 * * * cd /home/zzh && sh test.sh $(date -d "1 day ago" +"\%Y\%m\%d") >/dev/null 2>&1

6. shell 变量

参考 https://www.runoob.com/linux/linux-shell-variable.html

定义变量时,变量名不加$,如:

1
a=10

注:变量名和等号之间不能有空格

使用一个定义过的变量时,在变量名前加 $,如:

1
2
3
a=10
echo $a
echo ${a}

变量名外面的花括号是可选的,加花括号是为了帮助解释器识别变量的边界。

已定义的变量,可以被重新定义:

1
2
3
4
a=10
echo $a
a=20
echo $a

注:第二次赋值的时候不能写成 $a=20,使用变量时才加 $

7. shell 字符串

7.1 单引号

1
str='this is a string'

单引号字符串的限制:

  • 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
  • 单引号字符串中不能出现单独一个的单引号(转义后也不行),但可成对出现,作为字符串拼接使用

7.2 双引号

1
2
3
4
5
6
your_name="runoob"
str="Hello, I know you are \"$your_name\"!"
echo $str

# 输出:
Hello, I know you are "runoob"!

双引号的优点:

  • 双引号里可以有变量
  • 双引号里可以出现转义字符

8. shell 基本运算符

参考 https://www.runoob.com/linux/linux-shell-basic-operators.html

原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如expr。expr是一款表达式计算工具,使用它能完成表达式的求值操作。

例如,两个数相加:

1
2
3
4
5
6
7
#!/bin/bash

val=`expr 2 + 2`
echo "两数之和为: $val"

# 结果
两数之和为: 4

注:表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2

8.1 算数运算符

image-20210904144648161

注:条件表达式要放在方括号之间,并且要有空格,例如: [$a==$b] 是错误的,必须写成 [ $a == $b ]。(方括号之间要有空格,运算符和变量之间也要有空格)

image-20210904145343228

8.2 关系运算符

关系运算符只支持数字,不支持字符串,除非字符串的值是数字。

image-20210904145650517

image-20210904145812074

8.3 布尔运算符

image-20210904150231679

image-20210904150309883

8.4 逻辑运算符

image-20210904150411459

image-20210904150440602

8.5 字符串运算符

image-20210904150658570

image-20210904150725984

9. shell 中各种括号的作用

参考
https://www.jb51.net/article/123081.htm
https://www.jianshu.com/p/3e1eaaa3fee8

9.1 单小括号 ()

一般在命令替换的时候使用

1
2
3
4
5
6
#!/bin/bash

today=$(date +%y%m%d)

# shell扫描一遍命令,发现了$()结构,便将$()中的命令执行一次,得到其标准输出,再将此输出赋值给today
# 等同于today=`date +%y%m%d`

9.2 双小括号 (())

参考 http://c.biancheng.net/view/2480.html

使用双括号,在比较过程中使用高级数学表达式

符号 描述
val++ 后增
val-- 后减
++val 先增
--val 先减
! 逻辑求反
~ 位求反
** 幂操作
<< 左位移
>> 右位移

&&逻辑与,||逻辑或

双小括号 (( )) 是 Bash Shell 中专门用来进行整数运算的命令,它的效率很高,写法灵活,是企业运维中常用的运算命令。(())是一种数学计算命令,它除了可以进行最基本的加减乘除运算,还可以进行大于、小于、等于等关系运算,以及与、或、非逻辑运算。

注:(( )) 只能进行整数运算,不能对小数(浮点数)或者字符串进行运算。

双小括号 (( )) 的语法格式为:

1
((表达式))

通俗地讲,就是将数学运算表达式放在(())之间。

表达式可以只有一个,也可以有多个,多个表达式之间以逗号,分隔。对于多个表达式的情况,以最后一个表达式的值作为整个 (( )) 命令的执行结果。

1
可以使用 $ 获取 (( )) 命令的结果,这和使用 $ 获得变量值是类似的。

image-20210905110953010

在 (( )) 中使用变量无需加上$前缀,(( )) 会自动解析变量名,这使得代码更加简洁,也符合程序员的书写习惯。

【实例1】利用 (( )) 进行简单的数值计算。

image-20210905111242247

【实例2】利用 (( )) 进行逻辑运算。

image-20210905111449347

image-20210905115217853

运行结果如下:

image-20210905115317618

1
可以直接使用if (($i<5)), 如果不使用双括号, 则为if [ $i -lt 5 ]。

【实例3】利用 (( )) 进行自增(++)和自减(--)运算。

1
2
3
4
val=10     
((val++))
echo $val
# 输出 11

image-20210905111705126

【实例4】利用 (( )) 同时对多个表达式进行计算。

image-20210905112032741

9.3 单方括号 []

方括号定义了测试条件。第一个方括号 ([) 后和第二个方括号 (]) 前都要加一个空格,否则会报错。方括号主要包括4类判断:

(1)数值比较:

1
2
3
if [ $val1 -eq $val2 ]
if [ $val1 -le $val2 ]
...

(2)字符串比较:

1
2
3
4
if [ $str1 = $str2 ]
if [ $str1 != $str2 ]
if [ -n $str1 ] # 检查str1的长度是否非0
if [ -z $str1 ] # 检查str1的长度是否为0

例:test.sh脚本如下:

image-20210904182927259

运行结果:

image-20210904183031882

经过测试,数值也可以使用=, !=,且对于数值与字符串,=与==效果貌似一样?

image-20210904190918657

运行结果:

image-20210904190947396

(3)文件比较

image-20210904190420085

image-20210904190456860

(4)符合条件比较

1
2
[ condition1 ] && [ condition2 ]
[ condition1 ] || [ condition2 ]

注:[ ]中的 逻辑与 和 逻辑或 使用 -a 和 -o 表示,例: if [ $a -ne 1 -a $a != 2 ],或写作:if [ $a -ne 1 ] && [ $a != 2 ]

9.4 双方括号 [[]]

  • 双方括号提供了字符串比较的高级特性
  • 括号中可以定义一些正则表达式来匹配字符串
  • 注意不是所有的shell都支持双方括号

image-20210904190701945

注:&&、||、< 和 > 操作符能够正常存在于[[ ]]条件判断结构中,比如可以直接使用 if [[ $a != 1 && $a != 2 ]]

9.5 例子

1
2
3
4
5
6
7
8
9
if ($i<5) 
if [ $i -lt 5 ]
if [ $a -ne 1 -a $a != 2 ]
if [ $a -ne 1] && [ $a != 2 ]
if [[ $a != 1 && $a != 2 ]]
for i in $(seq 0 4);do echo $i;done
for i in `seq 0 4`;do echo $i;done
for ((i=0;i<5;i++));do echo $i;done
for i in {0..4};do echo $i;done

10. shell if else 语句

参考 http://c.biancheng.net/view/1262.html

10.1 if 语句

1
2
3
4
if condition
then
statement(s)
fi

如果要将then 和 if 写在一行,要加个分号:

1
2
3
if  condition;  then
statement(s)
fi

实例1:下面的例子使用 if 语句来比较两个数字的大小:

image-20210905110030266

实例2:在判断条件中也可以使用逻辑运算符,例如:

image-20210905112205882

10.2 if else 语句

1
2
3
4
5
6
if  condition
then
statement1
else
statement2
fi

image-20210905113102953

10.3 if elif else 语句

1
2
3
4
5
6
7
8
9
10
11
12
13
if  condition1
then
statement1
elif condition2
then
statement2
elif condition3
then
statement3
...
else
statementn
fi

image-20210905113316626

例2:

来自 https://www.tutorialspoint.com/unix/if-elif-statement.htm

image-20210905113545472

11. shell while

参考
http://c.biancheng.net/view/2804.html
https://blog.csdn.net/weixin_44324367/article/details/111312156
shell 之 循环执行某操作 - Simple-Sir - 博客园 (cnblogs.com)

1
2
3
4
while condition
do
statements
done

while 语句和 if else 语句中的 condition 用法都是一样的,可以使用 test 或 [] 命令,也可以使用 (()) 或 [[]]

【实例1】计算从 1 加到 100 的和。

image-20210905114028564

【实例2】计算从 m 加到 n 的值。

image-20210905115543470

【实例3】输出0~10的所有整数

image-20210905115630118

12. 重定向 >

参考 linux shell中"2>&1"含义 - hongxinerke - 博客园 (cnblogs.com)

1表示标准输出 2表示标准错误 2>&1 的意思就是将标准错误重定向到标准输出

例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
>./test_run.sh >test_run.sh.log 2>&1
输出结果保存到test_run.sh.log(标准输出与错误)(>会覆盖已存在的内容)

>./test_run.sh >>test_run.sh.log 2>&1
输出结果追加到test_run.sh.log(标准输出与错误)(>>追加到末尾)

>./test_run.sh >test_run.sh.log
输出结果保存到test_run.sh.log(标准输出),错误信息输出到屏幕

>./test_run.sh 2>test_run.sh.log
输出结果(不包含错误信息)到屏幕,错误信息保存到test_run.sh.log


例有crontab任务:
*/2 * * * * root cd /opt/xxxx/test_S1/html/xxxx/admin; php index.php task testOne >/dev/null 2>&1 &
可以把/dev/null 可以看作"黑洞". 它等价于一个只写文件. 所有写入它的内容都会永远丢失. 而尝试从它那儿读取内容则什么也读不到.
可以把 & 在命令的最后加上,表示让程序后台执行。

0 5 * * * 表示每天5:00执行

补充:如何既将结果保存到文件,又输出到屏幕:可使用 tee,示例如下

1
>./pythonsql.sh | tee pythonsql.log

13. crontab 定时执行shell脚本

参考
linux crontab定时执行shell脚本 - 龙昊雪 - 博客园 (cnblogs.com)
linux定时运行命令脚本——crontab_阳光岛主-CSDN博客

crontab命令说明: crontab命令被用来提交和管理用户的需要周期性执行的任务,与windows下的计划任务类似,当安装完成操作系统后,默认会安装此服务工具,并且会自动启动crond进程,crond进程每分钟会定期检查是否有要执行的任务,如果有要执行的任务,则自动执行该任务。

1
2
3
4
5
6
7
8
9
语法
 crontab (选项) (参数)
选项
 -e:编辑该用户的计时器设置;
 -l:列出该用户的计时器设置;
 -r:删除该用户的计时器设置;
 -u<用户名称>:指定要设定计时器的用户名称。
参数
 crontab文件:指定包含待执行任务的crontab文件。

crontab命令:

1
2
crontab -e -> 编辑(进入后,press i 进行编辑,:wq保存并退出)
crontab -l -> 查看

crontab文件的含义: 用户所建立的crontab文件中,每一行都代表一项任务,每行的每个字段代表一项设置,它的格式共分为六个字段,前五段是时间设定段,第六段是要执行的命令段,格式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
minute hour day month week command     
顺序:分 时 日 月 周
其中:
minute: 表示分钟,可以是从0到59之间的任何整数。
hour:表示小时,可以是从0到23之间的任何整数。
day:表示日期,可以是从1到31之间的任何整数。
month:表示月份,可以是从1到12之间的任何整数。
week:表示星期几,可以是从0到7之间的任何整数,这里的0或7代表星期日。
command:要执行的命令,可以是系统命令,也可以是自己编写的脚本文件。
在以上各个字段中,还可以使用以下特殊字符:

星号(*):代表所有可能的值,例如month字段如果是星号,则表示在满足其它字段的制约条件后每月都执行该命令操作。
逗号(,):可以用逗号隔开的值指定一个列表范围,例如,“1,2,5,7,8,9”
中杠(-):可以用整数之间的中杠表示一个整数范围,例如“2-6”表示“2,3,4,5,6”
正斜线(/):可以用正斜线指定时间的间隔频率,例如“0-23/2”表示每两小时执行一次。同时正斜线可以和星号一起使用,例如*/10,如果用在minute字段,表示每十分钟执行一次。

注释行要在行首用#来表示

crontab文件条目的一些例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
30 21 * * * /apps/bin/cleanup.sh
上面的例子表示每晚的21:30运行/apps/bin目录下的cleanup.sh。

45 4 1,10,22 * * /apps/bin/backup.sh
上面的例子表示每月1、10、22日的4:45运行/apps/bin目录下的backup.sh。

10 1 * * 6,0 /bin/find -name "core" -exec rm {} ;
上面的例子表示每周六、周日的1:10运行一个find命令。

0,30 18-23 * * * /apps/bin/dbcheck.sh
上面的例子表示在每天18:00至23:00之间每隔30分钟运行/apps/bin目录下的dbcheck.sh。

0 23 * * 6 /apps/bin/qtrend.sh
上面的例子表示每星期六的23:00运行/apps/bin目录下的qtrend.sh。

你可能已经注意到上面的例子中,每个命令都给出了绝对路径。当使用crontab运行shell脚本时,要由用户来给出脚本的绝对路径,设置相应的环境变量。

13.1关于路径

关于路径错误,因为在crontab中使用了绝对路径执行脚本,因此在该脚本中引用的其它脚本也都需要使用绝对路径,才能被crontab找到并执行。如何避免绝对路径复杂的设置呢,可采用如下格式:

1
2
3
4
0 5 * * * cd /data/test-ml;sh crontab_run.sh >>/data/test-ml/crontab_run.sh.log 2>&1 &

0 5 * * * cd /data/test-ml && ./crontab_run.sh >>/data/test-ml/crontab_run.sh.log 2>&1 &
每天5点执行,并将输出保存至crontab_run.sh.log(包括标准输出与标准错误)

建议使用此方式,先进入该目录,然后再执行脚本;否则,执行脚本中的其它脚本都需要加绝对路径

13.2 crontab 中传入时间参数

参考 linux内crontab传时间参数_大大盒子的博客-CSDN博客

1
15 4 * * * /home/temp/post_analysis/post_analysis_sqoop.sh $(date -d "1 day ago" +"\%Y-\%m-\%d") >/dev/null 2>&1

14 Linux shell 管道 |

参考 http://c.biancheng.net/view/3131.html

Shell 有一种功能,就是可以将两个或者多个命令(程序或者进程)连接到一起,把一个命令的输出作为下一个命令的输入,以这种方式连接的两个或者多个命令就形成了管道(pipe)

Linux 管道使用竖线|连接多个命令,这被称为管道符。Linux 管道的具体语法格式如下:

1
2
command1 | command2
command1 | command2 [ | commandN... ]

管道符|与两侧的命令之间可以存在也可以不存在空格。

当在两个命令之间设置管道时,管道符|左边命令的输出就变成了右边命令的输入。只要第一个命令向标准输出写入,而第二个命令是从标准输入读取,那么这两个命令就可以形成一个管道。大部分的 Linux 命令都可以用来形成管道。

使用管道的优点:省去创建临时文件。

【示例】将 ls 命令的输出发送到 grep 命令:

1
2
[c.biancheng.net]$ ls | grep log.txt
log.txt

上述命令是查看文件 log.txt 是否存在于当前目录下。

我们可以在命令的后面使用选项,例如使用-al选项:

1
2
[c.biancheng.net]$ ls -al | grep log.txt
-rw-rw-r--. 1 mozhiyan mozhiyan 0 4月 15 17:26 log.txt

我们也可以重定向管道的输出到一个文件(使用重定向操作符>或>>将管道中的最后一个命令的标准输出进行重定向),比如将上述管道命令的输出结果发送到文件 output.txt 中:

1
2
3
[c.biancheng.net]$ ls -al | grep log.txt >output.txt
[c.biancheng.net]$ cat output.txt
-rw-rw-r--. 1 mozhiyan mozhiyan 0 4月 15 17:26 log.txt

15. 在 Linux shell 中查看与处理文件常用的命令

15.1 less

使用管道将 cat 命令的输出作为 less 命令的输入,这样就可以将 cat 命令的输出每次按照一个屏幕的长度显示,这对于查看长度大于一个屏幕的文件内容很有帮助。

1
cat /var/log/message | less

15.2 grep

参考 https://www.runoob.com/linux/linux-comm-grep.html

grep 命令用于查找文件里符合条件的字符串。

语法:

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
grep [-abcEFGhHilLnqrsvVwxy][-A<显示行数>][-B<显示列数>][-C<显示列数>][-d<进行动作>][-e<范本样式>][-f<范本文件>][--help][范本样式][文件或目录...]

参数:
-a 或 --text : 不要忽略二进制的数据。
-A<显示行数> 或 --after-context=<显示行数> : 除了显示符合范本样式的那一列之外,并显示该行之后的内容。
-b 或 --byte-offset : 在显示符合样式的那一行之前,标示出该行第一个字符的编号。
-B<显示行数> 或 --before-context=<显示行数> : 除了显示符合样式的那一行之外,并显示该行之前的内容。
-c 或 --count : 计算符合样式的列数。
-C<显示行数> 或 --context=<显示行数>或-<显示行数> : 除了显示符合样式的那一行之外,并显示该行之前后的内容。
-d <动作> 或 --directories=<动作> : 当指定要查找的是目录而非文件时,必须使用这项参数,否则grep指令将回报信息并停止动作。
-e<范本样式> 或 --regexp=<范本样式> : 指定字符串做为查找文件内容的样式。
-E 或 --extended-regexp : 将样式为延伸的正则表达式来使用。
-f<规则文件> 或 --file=<规则文件> : 指定规则文件,其内容含有一个或多个规则样式,让grep查找符合规则条件的文件内容,格式为每行一个规则样式。
-F 或 --fixed-regexp : 将样式视为固定字符串的列表。
-G 或 --basic-regexp : 将样式视为普通的表示法来使用。
-h 或 --no-filename : 在显示符合样式的那一行之前,不标示该行所属的文件名称。
-H 或 --with-filename : 在显示符合样式的那一行之前,表示该行所属的文件名称。
-i 或 --ignore-case : 忽略字符大小写的差别。
-l 或 --file-with-matches : 列出文件内容符合指定的样式的文件名称。
-L 或 --files-without-match : 列出文件内容不符合指定的样式的文件名称。
-n 或 --line-number : 在显示符合样式的那一行之前,标示出该行的列数编号。
-o 或 --only-matching : 只显示匹配PATTERN 部分。
-q 或 --quiet或--silent : 不显示任何信息。
-r 或 --recursive : 此参数的效果和指定"-d recurse"参数相同。
-s 或 --no-messages : 不显示错误信息。
-v 或 --invert-match : 显示不包含匹配文本的所有行。
-V 或 --version : 显示版本信息。
-w 或 --word-regexp : 只显示全字符合的列。
-x --line-regexp : 只显示全列符合的列。
-y : 此参数的效果和指定"-i"参数相同。

【示例1】在当前路径下,查找后缀有 file 字样的文件中包含 test 字符串的文件,并打印出该字符串的行。

1
grep test *file 

结果如下所示:

1
2
3
4
>grep test test* #查找前缀有“test”的文件包含“test”字符串的文件  
testfile1:This a Linux testfile! #列出testfile1 文件中包含test字符的行
testfile_2:This is a linux testfile! #列出testfile_2 文件中包含test字符的行
testfile_2:Linux test #列出testfile_2 文件中包含test字符的行

【示例2】以递归的方式查找符合条件的文件。例如,查找指定目录/etc/acpi 及其子目录(如果存在子目录的话)下所有文件中包含字符串"update"的文件,并打印出该字符串所在行的内容,使用的命令为:

1
grep -r update /etc/acpi 

【示例3】查看result.csv中出现100001的行并输出

1
>cat result.csv | grep 100001

1649855242323

将输出结果存入文件:

1
>cat result.csv | grep 100001 >output.txt

查找并返回行号:

1
>cat result.csv | grep -n 100001

1649856944592

若想在另一个文件中查看相同行号的内容:

1
> cat result2.csv | sed -n '334007p'

1649858199759

15.3 wc

参考 https://www.runoob.com/linux/linux-comm-wc.html

wc命令用于计算字数

语法:

1
2
3
4
5
6
7
8
wc [-clw][--help][--version][文件...]

参数:
-c或--bytes或--chars 只显示Bytes数。
-l或--lines 显示行数。
-w或--words 只显示字数。
--help 在线帮助。
--version 显示版本信息。

【示例1】返回行数,字数,字节数

1
2
3
4
5
6
7
8
9
10
11
$ cat testfile  
Linux networks are becoming more and more common, but scurity is often an overlooked
issue. Unfortunately, in today’s environment all networks are potential hacker targets,
fro0m tp-secret military research networks to small home LANs.
Linux Network Securty focuses on securing Linux in a networked environment, where the
security of the entire network needs to be considered rather than just isolated machines.
It uses a mix of theory and practicl techniques to teach administrators how to install and
use security applications, as well as how the applcations work and why they are necesary.

$ wc testfile # testfile文件的统计信息
3 92 598 testfile # testfile文件的行数为3、单词数92、字节数598

【示例2】查看文件中包含多少个逗号,结合 grep

1
>cat result.txt | grep -o ',' | wc -l

1649857332971

15.4 sed

sed 可依照脚本的指令来处理、编辑文本文件。

语法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
sed [-hnV][-e<script>][-f<script文件>][文本文件]

参数说明:
-e<script>或--expression=<script> 以选项中指定的script来处理输入的文本文件。
-f<script文件>或--file=<script文件> 以选项中指定的script文件来处理输入的文本文件。
-h或--help 显示帮助。
-n或--quiet或--silent 仅显示script处理后的结果。
-V或--version 显示版本信息。

动作说明:
a :新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)~
c :取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!
d :删除,因为是删除啊,所以 d 后面通常不接任何东东;
i :插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);
p :打印,亦即将某个选择的数据印出。通常 p 会与参数 sed -n 一起运行~
s :取代,可以直接进行取代的工作哩!通常这个 s 的动作可以搭配正规表示法!例如 1,20s/old/new/g 就是啦!

假如有如下文件:

1
2
3
4
5
6
7
8
9
10
$ cat testfile #查看testfile 中的内容  
HELLO LINUX!
Linux is a free unix-type opterating system.
This is a linux testfile!
Linux test
Google
Taobao
Runoob
Tesetfile
Wiki

【示例1】列出文件的5到7行:

1
2
3
4
$ cat testfile | sed -n '5,7p'
Google
Taobao
Runoob

【示例2】搜索 testfile 有 oo 关键字的行:

1
2
3
$ cat testfile | sed -n '/oo/p'
Google
Runoob

【示例3】数据的查找与替换:

除了整行的处理模式之外, sed 还可以用行为单位进行部分数据的查找与替换

语法格式如下:

1
sed 's/要被取代的字串/新的字串/g'

将 testfile 文件中每行第一次出现的 oo 用字符串 kk 替换,然后将该文件内容输出到标准输出:

1
>sed -e 's/oo/kk/' testfile

注:sed 后面接的动作,要以 '...' 两个单引号括住

g 标识符表示全局查找替换,使 sed 对文件中所有符合的字符串都被替换,修改后内容会到标准输出,不会修改原文件:

1
>sed -e 's/oo/kk/g' testfile

选项 i 使 sed 修改文件:

1
>sed -i 's/oo/kk/g' testfile

批量操作当前目录下以 test 开头的文件:

1
>sed -i 's/oo/kk/g' ./test*

【示例4】将文件中的的逗号替换为写入另一个文件:

1
>cat ./docs/a.txt |sed 's/,/\t/g' >./docs/b.txt

直接修改原文件:

1
>sed -i 's/,/\t/g' ./docs/a.txt

15.5 关于vim

15.5.1 快速清空文件内容

参考 https://blog.csdn.net/qq_21238607/article/details/119541193

1
2
3
#命令模式下
G # 跳至文件最后一行
d1G # 删除首行至光标所在行的所有数据

👆 注:输入完 d1G后,会立马清空,不会要求确认等操作。

15.5.2 撤销与恢复

参考 http://c.biancheng.net/view/6332.html

1650364215210

注意,以上这 3 种命令都必须在 Vim 编辑器处于命令模式时才能使用。

15.6 上传与下载文件

参考 https://blog.51cto.com/superw/1943250

  1. 上传到服务器:
1
rz

选择相应的文件即可

  1. 从服务器上下载文件:
1
sz text.csv

选择相应的保存路径即可