实用
grep -RiP ./ "something"
在当前的所有目录中查找有something字眼的文件,可以配合less使用。
ls
ls [选项] [文件或目录]
选项:
- -a:显示所有文件,包括隐藏文件
- -l:显示所有详细信息
- -d:查看目录属性,如
ls -ld /etc
可以直接查看etc目录的属性 - -h:人性化显示文件大小,一般与-l协同使用
- -i:显示inode,每个文件都有一个节点号,就是inode.
通常使用ls -l
比较多,但是ls -l
有个别名:ll
所以如果需要使用ls -l
,只要敲ll
就可以了。
通过ls - l可以获取详细信息,其中第一列表示文件权限,第二列表示当前文件引用次数,第三列表示文件的所有者,第四列表示文件的所属组。
目录处理命令
mkdir [-p] [目录名]
- -p 递归创建
创建一个目录不需要使用-p参数,但是如果创建多级目录,并且每级目录都不存在,需要使用-p参数。如mkdir -p qxg/qqxg
rmdir [目录名]
用于删除空白目录,如果目录中有内容,则无法删除。通常删除目录使用的命令是rm
rm [选项] [目录]
- r 删除目录
- f 强制删除,不会进行交互询问是否删除
比如 rm -rf /
会删除linux根目录下的所有文件。rm -rf /tmp/
是删除/tmp这个目录,而rm -rf /tmp/*
是删除/tmp目录下的所有目录。
通常不论删除目录还是文件,都会使用rm -rf
这种习惯用法。
cp [选项] [原文件或目录] [目标目录]
- -r 复制目录
- -p 连带文件属性复制
- -d 若源文件是链接文件,则复制链接属性
- -a 相当于 -pdr。如果想要复制的文件或目录和原来的一模一样,只要加上-a命令就ok了。
该命令可以复制文件也可以复制目录。
常见目录
- / 根目录
- /bin 存放必要的命令
- /boot 存放内核以及启动所需的文件等
- /dev 存放设备文件
- /etc 存放系统的配置文件
- /home 用户文件的主目录,用户数据存放在其主目录中
- /lib 存放必要的运行库
- /mnt 存放临时的映射文件系统,我们常把软驱和光驱挂装在这里的-
floppy和cdrom子目录下。 - /proc 存放存储进程和系统信息
- /root 超级用户的主目录
- /sbin 存放系统管理程序
- /tmp 存放临时文件的目录
- /usr 包含了一般不需要修改的应用程序,命令程序文件、程序库、手册和其它文档。
- /var 包含系统产生的经常变化的文件
链接命令
ln -s [源文件] [目标文件]
- -s 创建软连接
链接分为硬链接和软链接。假设有一个文件/home/qxg/good,那么通过ln /home/qxg/good /tmp/bad
创建该文件的硬链接,处于/tmp/下名为bad。那么在修改good文件的时候,bad文件也会跟着修改,但是删除good的时候,bad依然存在,可以理解为硬链接就是java中的引用,其只是指向了文件的实际位置。
而软链接就类似windows中的快捷方式,一般推荐使用软链接的形式。
但是注意一点,在创建链接的时候,源文件的路径一定要写绝对路径。
文件搜索
locate
locate 文件名
locate的特点是搜索速度比较快,其在后台数据库中按文件名搜索,其中/var/lib/mlocate
就是其所搜索的数据库。但是如果创建一个新的文件的时候,不会被搜索到,因为数据库不是实时更新的。但是可以通过updatedb
命令来强制进行更新,然后再搜索就可以找到。
但是locate的弱点是只能搜索文件名。
locate搜索的规则是按照/etc/updatedb.conf配置文件进行搜索
whereis和which
whereis 命令名
- b 只查找可执行文件
- m 只查找帮助文件
搜索命令所在路径以及帮助文档所在位置。
如:whereis ls
会打印出:
ls: /bin/ls /usr/share/man/man1/ls.1.gz /usr/share/man/man1p/ls.1p.gz
类似这种样式的命令还有很多,比如想要知道我是谁用whoami
,想要知道命令是干什么用whatis
.
which
同样也是搜索命令的执行文件,并且如果该命令有对应的别名,也会被显示出来。
如执行which ls
会打印:
alias ls='ls --color=auto'
/bin/ls
可以看到ls
其实是执行的ls --color=auto
,表示不同的文件以不同的颜色列出。
find
find [搜索范围] [搜索条件]
find搜索的内容会和名字一模一样,如果想要模糊搜索,可以使用通配符,通配符有以下几种:
- * 匹配任意内容
- ? 匹配任意一个字符
- [] 匹配任意一个括号以内的字符
eg:
-
find / -name install.sh
在根目录搜索install.sh名字的文件。 -
find /root -iname install.sh
不区分大小写搜索 -
find /root -user root
按照所有者搜索 -
find /root -nouser
查找没有所有者的文件 -
find /var/log/ -mtime +10
查找10天前修改的文件,-10表示10天内,10表示10天当天。-atime表示文件访问,-ctime 表示修改文件属性。 -
find . -size 25k
按照文件大小搜索,+25k表示大于25k的文件,-25k表示小于25k的文件。k表示千字节,M表示兆字节,注意k不能是大写,M不能是小写。 -
find . -inum 252342
查找inode节点为252342的文件
复杂eg: -
find /etc -size +20k -a -size -50k
其中-a 表示and ,左右两个条件都要满足,所以该命令表示查找大于20k小于50k的文件。当然也有-o 表示or。 -
find /etc -size +20k -a -size -50k -exec ls -lh {} \;
查找大于20k且小于50k的文件,并且通过ls -lh显示出来。其中-exec 命令 {} \;
表示对搜索结果执行操作。
grep
grep [选项] 字符串 文件名
- -i 忽略大小写
- -v 排除指定字符串
在某文件中匹配符合条件的字符串,如grep "some" test.sh
在test.sh中查找some字符串。
find 和 grep的区别是,find是在系统中搜索文件,grep是在文件中包含的字符串。find是通配符匹配,grep是正则表达式匹配。
用户和组
一个用户可以有多个用户组,一个主组其他附组。
- /etc/group保存的是用户的组信息,其格式为
组名称:组密码占位符:组编号:组中用户名列表
其中1~499编号是用户装的软件所使用 - /etc/gshaow存储当前系统中用户组的密码信息,其格式为:
组名称:组密码:组管理者:组中用户名列表
- /etc/passwd 存储当前系统中所有用户的信息,其格式为:
用户名:密码占位符:用户编号:用户组编号:用户注释信息:用户主目录:shell类型
- /etc/shadow 存储用户密码
用户组 -
groupadd
添加组 -
groupmod -n [修改后的组名] [修改前的组名]
修改组名 -
groupmod -g [修改后的pid] 要修改的组名
修改组编号 -
groupadd -g 888 boss
创建888编号的用户组boss -
groupdel
删除用户组,删除前,先删除用户组中的用户
用户 -
useradd -g [用户组] [用户]
将某一用户添加到用户组里 -
useradd -d /home/qxg qxg
创建qxg的时候指定主目录,默认和名字一样 - 如果创建用户没有指定用户组的时候,会默认创建和用户同名的用户组
-
useradd -c [注释] [用户]
给用户添加注释 -
usermod -l [新用户名] [老用户名]
更改用户名 -
usermod -g [目标group] [user]
将用户修改到目标用户组 -
userdel [user]
删除用户,不删除目录userdel -r [user]
删除用户并删除主目录
其他 -
touch /etc/nologin
禁止除root用户 登录到系统中 -
passwd -l [user]
锁定某个用户 -
passwd -u [user]
解锁某个用户 -
passwd -d [user]
用户无密码登录 -
passwd [user]
修改用户密码
权限
使用ls -l
列出来的文件信息,第一列的内容就是权限内容:-rw-r--r--
.
其中第一位表示文件类型(- 文件,d 目录, l 软链接文件),后边三位一组,每组分别表示文件所有者的权限,所属组的权限,非所属组的权限。完整的一组权限为rwx,r表示读,w表示写,x表示执行。
shell
echo命令
echo [选项] [输出内容]
- -e 支持反斜杠控制的字符转换
如 \a表示警告音,\b表示退格键,\r表示换行等等
还可以通过-e将输出的内容显示出某种颜色。
第一个脚本
在shell中#号表示注释,但是第一行的#!/bin/bash不能省略,表示linux的标准脚本。
比如创建一个脚本hello.sh:
#!/bin/bash
echo "lalala"
那么运行脚本的方式有两种:
- chmod 755 hello.sh 赋予运行权限,然后./hello.sh直接运行
- sh hello.sh运行 或者bash hello.sh
bash基本功能
命令别名
- alias 查看系统中所有命令的别名
- alias 别名 = '原命令' 来创建别名。
- 将别名写入到~/.bashrc 中,则永久生效
- unalias 别名 用来删除别名
常用快捷键
- ctrl + c 强制终止当前命令
- ctrl + l 清屏
- ctrl + a 光标移动到命令行首
- ctrl + e 光标移动到命令行尾
- ctrl + u 从光标所在位置删除到行首
- ctrl + z 把命令放入后台
- ctrl + r 在历史命令中搜索
- ctrl + d 表示退出(exit)
-
shift + PageUp
显示上一个屏幕内容,使用clear后,可以使用这个命令查看
历史命令
history [选项] [历史命令保存文件]
- -c 清空历史命令
- -w 把缓存中的历史命令写入历史命令保存文件
- !n 表示重复执行第n条历史命令
- !! 重复执行上一条命令
- !字符串 重复执行最后一次以这个字符串开头的命令
重定向
输出重定向
- > 覆盖
- >> 追加
- 2>标准错误输出
- 2>> 标准错误输出 追加方式,左右没空格
- 命令 &> 文件,覆盖方式把正确和错误信息都重定向
- 命令 &>>文件 不解释
- 命令>>文件1 2>>文件2
输入重定向
- wc < log.log
多命令
- cmd1;cmd2 命令之剑没有逻辑关系,但是cmd1执行完后cmd2执行
- cmd1&&cmd2 命令1执行完后,命令2才执行,命令1执行不正确命令2不执行。
- cmd1 || cmd2 命令1未正确执行则命令2才执行,命令1执行正确,则命令2不执行。
ls &> /dev/null 命令操作后,显示的内容直接丢到垃圾桶里。
历史命令默认保存1000条,如果觉得不够,可以到/etc/profile中修改HISTSIZE
历史命令保存在~/.bash_history下
变量规则
- 单引号中的专业字符均无用,双引号中$有特殊含义
- 赋值方式是aa=123
- 而如果想要将命令结果赋给aa,可以使用() ,如 aa =(ls),将ls的结果赋给aa。
- 变量赋值的时候左右不能加空格。
- 调用变量需要在前边加上
$
如有个变量x=5,调用x变量需要使用$x
- 所有的变量都是字符串类型,比如
x=5
,那么$x
是字符串,不能对其做加减等运算。 - 如果想要做加减运算,需要使用
$(())
,如$(( 10 + 20 ))
-
x="$x"456
/x=$(x)456
都是变量叠加,将原来的x加上后缀456 -
set
命令会查询到当前系统中所以的变量。set -u
执行后,那么echo $a
当a变量不存在就会显$示错误信息,而默认情况是显示空字符。 -
unset
删除变量,unset x
不需要加上$
,同样也可以删除环境变量 -
export 变量名=变量值
,定义环境变量方式 eg:export x=5
。 -
env
查看环境变量 - 建议将环境变量写成大写
- PS1变量:用于定义命令行前边那一串的格式,如
ubuntu@localhost:/home/ubuntu #
,具体怎么改,百度一下 -
locale
用于显示当前语系变量,重要的是LANG
和LC_ALL
,LANG
是定义系统主语系的变量,LC_ALL
定义整体语系变量。 -
locale -a
会显示当前支持的所有语言环境。
位置参数变量
位置参数变量 | 作用 |
---|---|
$n |
n为数字,0表示命令本身,1~9表示参数从第一个到第九个,10个以上需要使用大括号`{10}` |
$* |
表示命令行中所有参数 |
$@ |
命令行中所有参数,不过区分对待,比如使用for n in $@的时候就会起作用 |
$# |
参数个数 |
预定义变量
预定义变量 | 作用 |
---|---|
$? |
如果值为0,表示上一个命令执行成功,其实多命令执行就是根据这个来的 |
$$ |
当前进程的进程号pid |
$! |
后台运行的最后一个进程的pid |
输入
read命令用于读取间盘输入,并且赋给某个变量
-
read -p "请输入名字" name
,-p表示输出提示信息 -
read -p "请输入名字" -t 30 name
,-t表示30s后将会直接停止。 -
read -p "请输入密码" -s passwd
,-s表示键盘输入的内容,命令行上不显示 -
read -p "输入[y/n]" -t 1 input
-t表示只接受对应个数的字符,接受完直接运行。
shell运算符
declare命令
声明变量类型,如果不声明变量类型,则默认是字符串类型。
declare [+/-] [选项] 变量名
- - :给变量设定类型属性
- + :取消变量类型属性
- -a:数组
- -i:整数
- -x:环境变量
- -r:只读变量
- -p:显示变量被声明的类型
数值运算方法
declare -i cc=$aa+$bb
-
cc=$(expr $aa + $bb)
+号左右必须有空格 cc=$(($aa+$bb))
cc=$[$aa+$bb]
环境变量配置文件
系统主要生效的环境变量有:
- /etc/profile
- /etc/profile.d/*.sh
- ~/.bash_profile
- ~/.bashrc
- /etc/bashrc
正常登录:
非正常登录:
/etc/bashrc -> /etc/profile.d/*.sh
其他配置文件
- ~/.bash_logout 登出的时候环境变量会生效
- ~/.bash_history 历史命令的保存位置
- /etc/issue 登录前显示的信息
- /etc/issue.net 远程登录前显示信息
- /etc/motd 登录成功后显示的信息,
正则
awk,grep,sed是支持正则的,而find,cp,ls等只能使用通配符。
Linux中的基础正则:
字符 | 作用 |
---|---|
* | 0次或多次 |
. | 除换行符的任意字符 |
^ | 行首 |
$ | 行尾 |
[] | 括号内任意字符 |
[^] | 非括号内任意字符 |
转义,注意shell中的{}是特殊符号,用在正则中需要转义 | |
{n} | 出现n次 |
{n,} | 不小于n次 |
{n,m} | n~m次 |
cut命令
cut命令用来进行列提取,grep是行提取
cut [OPTIONS] 文件名
- f 提取第几列
- d 分隔符,默认使用制表符
但是这个命令的智商比较低,只能截取规律的文件,如果目标文件的内容是多个空格隔开的,那么cut就不能起作用了。这个时候就要使用awk命令。
eg:cut -f 2,4 student.txt
awk
awk中的输出命令只认识print或printf,没有echo命令。
awk '条件1{动作1} 条件2{动作2}...' 文件名
- 条件一般使用关系表达式作为条件
- 动作一般是格式化输出如print,或流程控制等。
比如有以下文件:
Name Age Location
Mike 10 henan
Tok 20 hunan
使用awk如何输出第1列和第3列,因为分隔符是空格,cut是没法完成这个任务,那么使用awk呢?
答案如下:awk '{printf $1 "\t" $3 "\n"}' student.txt
或者awk '{print $1 "\t" $3}' student.txt
.
awk是按行执行命令,因为这个命令没有条件,所以每行都要执行,但是注意,其读取完行,才开始执行动作。而$1表示输入的第一个参数,所以可以按每行的输入执行对应的输出。
再说个问题:执行df -h 后,找到磁盘使用量大于的20%的,如果有就报警,这个怎么做呢?
df -h|grep "/dev/sda5" | awk '{print $5}'|cut -d "%" -f 1
BEGIN,END
awk 'BEGIN{printf "This is a transcript\n"} {printf $2 "\t" $4 "\n"}' student.txt
BEGIN是一个表达式,表示在最开始的时候执行后边的动作。
而END是在最后的时候执行后边的动作。
那么这个东东又有什么用呢?
比如/etc/passwd中的文件,我想截取其中第一列的内容,使用cut轻松完成cat /etc/passwd| cut -d ":" -f 1
,那么使用awk的话,就需要借助于BEGIN:
ccat /etc/passwd | awk 'BEGIN{FS=":"} {printf $1"\n"}'
,FS=":"
中的FS是内置的一个变量,表示的是分隔符,在刚开始的时候就指定分隔符,这样就可以输出对应的变量了。
而如果不加BEGIN:cat /etc/passwd | awk '{FS=":"} {printf $1"\n"}'
,那么执行结果将是这样的:
root:x:0:0:root:/root:/bin/bash
user1
user2
原因就是,读取第一行后,先赋变量,然后才开始执行动作,而这条命令是每行都会执行,但是第一行执行前,分隔符依然是:
所以就导致了以上的结果出现,解决办法就是加上BEGIN
再看一个例子:
cat student.txt|grep -v Name | awk '$4>70{printf $2 "\n"}'
,表示大于70分的打印出名字。
注意grep -v Name
表示取反,有Name的那一行不要.
sed
对数据进行选取,替换,删除 ,新增的命令
sed [OPTIONS] '[动作]' 文件名
- -n:一般sed会把所有数据输出到屏幕,而使用-n后,只会把经过sed命令处理的行输出到屏幕
- -e: 允许输入多条动作
- -i: 一般sed不会修改文件,只会将结果显示在屏幕,但是加上-i会修改文件。
动作:
a:追加,在某一行的后边添加一行或多行
c:行替换,用c后面的字符串替换原数据行
i:插入,在某一行的前边插入一行或多行。
d:删除,删除指定行
p:输出指定行
s:字符替换,用一个字符串替换另外一个字符串,与vim中的替换类似
行范围s/新字符串/旧字符串/g
sed -n '2p' student.txt
:查看当前文件的第二行,注意一定加上-n,如果没有-n将输出所有行。sed '2,4d' student.txt
删除第二行到第四行的数据sed '2a something' student.txt
:在第二行的后边加入一行内容sed '2i something' student.txt
:在第二行的前边加入一行内容sed '4c something' student.txt
:将第4行替换为somethingsed '4s/70/100/g' student.txt
将第四行的70替换为100,如果不加行数,则会替换全文内容。sed -e 's/furong//g;s/fengjie//g' student.txt
-e指定多条命令,命令之间使用;
隔开。
sort
sort [选项] 文件名
- -f : 忽略大小写
- -n:以数值形进行排序,默认使用字符串
- -r:反向排序
- -t:指定分隔符,默认是制表符
- -k n[,m] 按照指定的字段范围排序,一般与-t结合使用,-t将每行分为多个字段,然后通过-k n,m来指定按照第某个字段排序。
wc
wc [选项] 文件名
- -l:只统计行数
- -w:只统计单词数
- -m:只统计字符数
默认会都统计。
shell流程控制
条件判断
文件类型判断
以下都是判断文件是否存在,但是对应的文件类型有不同,格式是[选项] 文件名
- -b 块设备文件
- -c 字符设备文件
- -d 目录文件
- -e 单纯判断文件是否存在
- -f 普通文件
- -L 符号链接文件
- p 管道文件
- -s 非空文件
- -S 套接字文件
用的最多的是 -d
,-e
,-f
。
比如:
[ -e /root/install.log ]
或test -e /root/install.log
表示判断/root/install.log是否存在
以上写法都对,但是一般用第一种写法,但是第一种写法中括号两边要有空格。
[ -e /root/install.log] && echo yese || echo no
文件存在会打印yes,不存在打印no。可以将来cmd&&cmd||cmd
理解为if esle
语句。
根据文件权限判断
以下都是判断文件是否存在,同时判断文件是否有对应的权限
- -r 读权限
- -w 写权限
- -x 执行权限
文件比较
- 文件1 -nt 文件2 :判断文件1的修改时间是否比文件2的新,nt: new than
- 文件1 -ot 文件2 :old than
- 文件1 -ef 文件2:判断文件1是否和文件2的Inode号一致。
两个整数之间的比较
格式是num1 [选项] num2
- -eq :判断两个整数是否相等
- -ne:不相等
- -gt:大于
- -lt:小于
- -ge:大于等于
- -le:小于等于
字符串之间的比较
- -z 字符串 判断字符串是否为空
- -n 判断字符串是否非空
- 字符串 ==字符串2
- 字符串 != 字符串2
但是判断的时候要加上双引号,否则会出错,比如[ -z $name ]
多重条件判断
- 判断1 -a 判断2:逻辑与
- 判断1 -o 判断2:逻辑或
- !判断:逻辑非
if
单分支if条件语句
if [ 条件判断 ];then
程序
fi
或者
if [ 条件判断 ]
then
程序
fi
双分支if
if [ 条件判断 ]
then
条件成立,执行
else
条件不成立,执行
fi
如,判断读取的字符串是不是一个目录
#!/bin/bash
read -t 30 -p "input" dir
if [ -d $dir ]
then
echo "是目录"
else
echo "不是"
fi
多分支if
if [ 条件1 ]
then
程序
elif [ 条件2 ]
then
程序
...
else
程序
fi
tips
- 在判断字符相等时利用 == 判断要注意两边都要有空格。
- if [ -n "num1" -a -n "num2" -a -n "$op" ]
shell编程类似的这种对于变量的判断一定要记得加双引号,虽然有时候显得没必要,但是在程序比较大时可能会因为这种小细节出错,这种问题应该调试半天也不一定能发现.
case
case $变量名 in
"值1")
程序1
;;
"值2")
程序2
;;
*)
默认程序
;;
esac
其中对于每个匹配的值,都可以使用正则来表示
for
for 变量 in 值1 值2 值3...
do
程序
done
如
for i in 1 2 3 4 5
do
echo $i
done
另一种格式:
for (( i=1;i<=100;i++))
do
程序
done
while
while [ 条件判断 ]
do
程序
done
until
until和while刚相反,until是条件成立才终止
until [ 条件判断 ]
do
程序
done