# Linux常用命令
## 1.日常操作指令
### 1.pwd
>查看当前所在的目录
### 2.date
> 查看当前系统时间
### 3.who last
> who 查看当前在线 (whoami查看当前登录的用户)
>
> last 查看最近的登录历史
### 4.ls
> ls / 查看根目录下的所有内容
>
> ls -l 以列表的方式展示 -a 显示隐藏文件 -h 显示文件大小
## 2.常用操作
### 1.创建文件夹
> 创建文件 。
>
> mkdir abc 相对路径的写法
>
> mkdir -p aaa/bbb/ccc 可以创建多层文件
>
> mkdir /data 绝对路径的写法
### 2.删除文件夹
> rmdir 可以删除空目录
>
> rm -r aaa 可以把整个文件夹以及其中所有的子节点删除。(带有删除提示)
>
> 注意:r表示递归。(recursion)
>
> rm -rf aaa 强制删除(无提示)
>
> rm -rf /* 删除全部
### 3.修改文件夹名称
> mv aaa hhh 修改文件名称
>
> mv file.1 /data/hello.1 移动文件到指定目录并修改文件名
### 4.创建文件
> touch file.1 创建一个空文件
>
> echo "hello linux ..." > file.1 利用重定向将输出内容写入到file.1文件中
>
> echo "bye,bye!" >> file.1 将指定内容重定向到目标,不覆盖原有内容
>
> (> 会覆盖文件原有内容,>> 在文件原有内容的基础上进行追加)
>
> 可以使用cat 命令查看文件内容。
>
> ls > file.2 也是可以的,关于>用法:只要前面有输出内容都可以重定向到后面的文件中
``使用vi创建文件:``
> vi file.3
>
> 1.一般模式:只接受快捷键 ,进入vi编辑器的默认模式。
>
> ``gg:``直接跳到首行
>
> ``G:``直接跳到尾行
>
> ``i:``进入编辑模式
>
> ``a:``在光标的后一位开始插入
>
> ``A:``在该行的最后插入
>
> ``dd:``删除当前行 3dd 一次删除光标后3行
>
> ``yy:``复制当前行 3yy 一次复制3行 ``p:``进行粘贴
>
> ``v Ctrl+v Shift+v:``分别对应字符模式,块模式,行模式。该模式下y复制,p粘贴
>
> 2.编辑模式:Esc退出编辑模式回到一般模式。
>
> 3.底行模式 : 输入: 表示进入底行模式。
>
> ``%s/haha/sbsbsb:``查到所有haha字符并替换成sbsbsb
>
> ``/指定内容:``直接查找到指定内容
>
> ``wq`` 保存文件并退出vi
>
> ``wq!`` 强制保存文件,并退出vi
>
> q!强制退出
>
> ``e!`` 放弃所有修改,从上次保存文件开始再编辑
> cat 查看文件 。
>
> cat -n 文件名称 显示行号查看文件。
>
> cat -n test.log | more 使用管道命令 查看并分页显示文件。
> more /etc/profile more 指令是一个基于 VI 编辑器的文本过滤器,以全屏幕的方式按页显示文本文件内容
>
> 空格 向下翻一页。
>
> 回车 向下翻一行。
>
> q 退出more 不再显示文件内容。
>
> Ctrl + F 向下滚动一屏幕。
>
> Ctrl + B 返回上一屏。
>
> = 输出当前行号。
>
> :f 输出文件名和当前行号。
>
>
>
> less 指令用来分屏查看文件内容,它的功能与 more 指令类似,但是比 more 指令更加强大,支持 各种显示终端。less 指令在显示文件内容时,并不是一次将整个文件加载之后才显示,而是根据显示 需要加载内容,对于显示大型文件具有较高的效率。
>
> less 要查看的文件
>
> 空格 向下翻动一页。
>
> pagedow 下翻一页
>
> pageup 上翻
>
> q 退出 。
>
> /字符串 向下查找
>
> ?字符串 向上查找。
> head -n 5 /etc/profile 显示头五行。
>
> tail 文件名 查看文件后10行 。
>
> tail -n 5 文件名
>
> tail -f 文件 实时追踪该文档的更新 。
> 软链接也叫符号链接,类似于 windows 里的快捷方式,主要存放了链接其他文件的路径
>
> 基本语法
>
> ln -s 原文件或目录 软链接名 (功能描述:给原文件创建一个软链接)
>
> ln -s /root linktoroot
>
> rm -rf linktoroot (注意 linktoroot 后不要加/)
> history 查看历史命令 。
>
> history 10
>
> !155
> date
>
> 1) date (功能描述:显示当前时间)
>
> 2) date +%Y (功能描述:显示当前年份)
>
> 3) date +%m (功能描述:显示当前月份)
>
> 4) date +%d (功能描述:显示当前是哪一天)
>
> 5) date "+%Y-%m-%d %H:%M:%S"(功能描述:显示年月日时分秒)
>
> date -s 字符串时间 date -s "2019-10-10 10:10:10" 设置当前系统时间。
> cal 显示本月日历 calendar
> locate 指令可以快速定位文件路径。locate 指令利用事先建立的系统中所有文件名称及路径的 locate 数据库实现快速定位给定的文件。Locate 指令无需遍历整个文件系统,查询速度较快。为了保 证查询结果的准确度,管理员必须定期更新 locate 时刻。 •基本语法locate 搜索文件 •特别说明 由于 locate 指令基于数据库进行查询,所以第一次运行前,必须使用 updatedb 指令创建 locate 数 据库。
>
> updatedb 更新locate 数据库 。
>
> locate 文件名称。
> grep 和管道指令 。
>
> grep 过滤查找 , 管道符,“|”,表示将前一个命令的处理结果输出传递给后面的命令处理。
>
> grep [选项] 查找内容 源文件
>
> -n number 显示匹配行及行号。
>
> -i ignore 忽略大小写比较。
>
> cat hello.txt | grep -ni haha
>
>
### 5.文件权限操作
> 权限解读:drwxr-xr-x
>
> d:标识节点类型(d:文件夹 -:文件 l:链接)
>
> r:可读 w:可写 x:可执行
>
> 第一组rwx: 表示这个文件的拥有者对它的权限
>
> 第二组rwx: 表示这个文件的所属组对它的权限
>
> 第三组rwx: 表示这个文件的其他用户(相对于上面两类用户)对它的权限
>
> 修改权限
>
> 有权限就是1 没权限就是0
>
> rwx 111 7
>
> r-x 101 5
>
> r-x 101 5
>
> chmod 755 文件名称 。
>
> u 表示文件的拥有者 。
>
> g 表示组的权限 。
>
> o 表示其他人。
>
> a 所有 。
>
> chmod u-w,g+r
### 6.基本用户管理
>1、添加用户
>
> useradd 用户名
>
> passwd 密码
>
>useradd -d /home/pet tom 添加用户的同时指定家目录。
>
>userdel -r xm 删除小明 连同家目录 。
>
>userdel xm 删除小明保留家目录。
>
>查询用户。 id 用户名
>
>显示用户id 所在组的id 组名。
> 添加组 groupadd 组名
>
> 删除组 groupdel 组名
> useradd -g 用户组 用户名 创建用户的时候就指定用户组。
>
> usermod -g 用户组 用户名 修改用户组
> /etc/passwd 文件 用户(user)的配置文件
>
> 记录用户的各种信息 每行的含义:用户名:口令:用户标识号:组标识号:注释性描述:主目录:登录 Shell
>
> /etc/shadow 口令的配置文件
>
> 每行的含义:登录名:加密口令:最后一次修改时间:最小时间间隔:最大时间间隔:警告时间:不活动 时间:失效时间:标志
>
> /etc/group 组(group)的配置文件,记录 Linux 包含的组的信息
>
> 每行含义:组名:口令:组标识号:组内用户列表 ject
>2、用户的切换
>
> su 用户名 切换成指定用户
>
> exit 切换回原来的用户。 从高权限到低权限用户不需要密码,反之需要。
>
> su 切换成root
>
> sudo 执行当前命令的时候使用root权限
>
> 权限配置的文件在/etc/sudoers文件中
>
>3、主机名称
>
> hostname 查看主机名称
>
> /etc/sysconfig/network 可以永久修改主机名称
>
>4、IP地址修改
>
> ifconfig 查看ip信息
>
> /etc/sysconfig/network-scripts/ifcfg-eth0
### 7.挂载
>rpm是由红帽公司开发的软件包管理方式,使用rpm我们可以方便的进行软件的安装、查询、卸载、升级等工作。 但是rpm软件包之间的依赖性问题往往会很繁琐,尤其是软件由多个rpm包组成时。
>
>Yum 能够从指定的服务器自动下载RPM包并且安装,可以自动处理依赖性关系,并且一次安装所有依赖的软体包,无须繁琐地一次次下载、安装。
>
>1.当有图形化界面的时候,会自动挂载到/media文件夹中,里面的packages就有我们需要的各种rpm安装包
>
>2.当我们安装非图形化界面的Linux后则需要手动挂载
>
> 1.首先创建挂载后存放光盘内容的目录。
>
> mkdir /mnt/cdrom
>
> 2.使用挂载命令,将光盘中的内容挂载到指定目录。
>
> mount -t iso9660 -o ro /dev/cdrom /mnt/cdrom
>
> (-t 表示文件系统的设备类型,iso9660 为光盘。)
>
> (-o 表示文件挂上来后的模式,是可读还是可写 ro 只读)
>
> 3.取消挂载
>
> umount /mnt/cdrom
### 8.查看文件大小
>du -s /opt 查看汇总之后的文件大小
>
>du -sh /opt 查看汇总之后的人能看懂的。(带单位)而不是显示当前文件在linux文件系统中占多少元数据
### 9.查看分区大小
>df -h 查看分区使用情况
### 10.关机,重启
> shutdown
>
> shutdown -h now : 表示立即关机
>
> shutdown -h 1 : 表示 1 分钟后关机
>
> shutdown -r now: 立即重启
>
> halt
>
> 就是直接使用,效果等价于关机
>
> reboot
>
> 就是重启系统。
>
> syn : 把内存的数据同步到磁盘
>
> 当我们关机或者重启时,都应该先执行以下 sync 指令,把内存的数据写入磁盘,防止数据丢失。 x
### 11.压缩,解压缩。
> gzip 将文件压缩 。
>
> gzip a.txt 压缩文件,压缩之后不保留原文件 。将生成 a.txt.gz 后缀文件。
>
> gunzip 解压。
>
> gunzip a.txt.gz 解压文件,不保留原文件。
> 压缩文件或目录的指令 。
>
> zip -r aa.zip a 将当前目录下的a文件夹 ,压缩成aa.zip
>
> zip -r package.zip /home/ 将home下的所有内容压缩成package.zip 。
>
> 解压缩文件或者目录的指令。
>
> unzip -d /opt/ package.zip 将指定zip包中的内容解压到指定目录。
> tar 打包指令,最后打包文件是.tar.gz的文件。
>
> -c 产生.tar打包文件
>
> -v 显示详细信息
>
> -f 指定压缩后的文件名
>
> -z 打包同时压缩
>
> -x 解包.tar文件
>
> tar -zcvf ab.tar.gz a.txt b.txt 将a.txt 和 b.txt 打包成tar.gz格式
>
> tar -zcvf home.tar.gz /home/ 将home目录下的所有文件打包成 home.tar.gz
>tar -zxvf a.tar.gz 将a.tar.gz文件解压到当前路径下 。
>
>tar -zxvf a.tar.gz -C /opt/ 解压到指定目录下,需要加入 -C 参数,并且指定文件要事先存在。
## 3.Linux目录结构
/bin:存放必要的命令、标准系统实用程序、增加的用户程序。
/boot:存放启动Linux时使用的一些核心文件、内核。
/dev:存放设备文件。
/etc:存放设置文件、系统管理所需要的配置文件和子目录。
/home:用户文件的主目录,存放用户数据。
/lib:存放系统最基本的动态链接共享库、必要的运行库。
/lost+found:存放系统意外关机时未保存的文件。
/media: linux系统会自动识别一些设备,例如U盘、光驱等等,当识别后,linux会把识别的设备挂载到这个目录下。
/mnt:系统提供该目录是为了让用户临时挂载别的文件系统的,我们可以将光驱挂载在/mnt/上,然后进入该目录就可以查看光驱里的内容了。
/opt:这是给主机额外安装软件所摆放的目录。比如你安装一个ORACLE数据库则就可以放到这个目录下。默认是空的。
/proc:这个目录是一个虚拟的目录,它是系统内存的映射,我们可以通过直接访问这个目录来获取系统信息。
/root:该目录为系统管理员,也称作超级权限者的用户主目录。
/sbin:s就是Super User的意思,这里存放的是系统管理员使用的系统管理程序。
/selinux:这个目录是Redhat/CentOS所特有的目录,Selinux是一个安全机制,类似于windows的防火墙,但是这套机制比较复杂,这个目录就是存放selinux相关的文件的。
/srv:该目录存放一些服务启动之后需要提取的数据。
/sys:这是linux2.6内核的一个很大的变化。该目录下安装了2.6内核中新出现的一个文件系统 sysfs 。sysfs文件系统集成了下面3种文件系统的信息:针对进程信息的proc文件系统、针对设备的devfs文件系统以及针对伪终端的devpts文件系统。该文件系统是内核设备树的一个直观反映。当一个内核对象被创建的时候,对应的文件和目录也在内核对象子系统中被创建。
/tmp:这个目录是用来存放一些临时文件的。
/usr:这是一个非常重要的目录,用户的很多应用程序和文件都放在这个目录下,类似于windows下的program files目录。
/usr/bin:系统用户使用的应用程序。
/usr/sbin:超级用户使用的比较高级的管理程序和系统守护程序。
/usr/src:内核源代码默认的放置目录。
/var:这个目录中存放着在不断扩充着的东西,我们习惯将那些经常被修改的目录放在这个目录下。包括各种日志文件。
/run:是一个临时文件系统,存储系统启动以来的信息。当系统重启时,这个目录下的文件应该被删掉或清除。如果你的系统上有 /var/run 目录,应该让它指向 run。
# shell编程
## 1、变量
注意,变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样。同时,变量名的命名须遵循如下规则:
- 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
- 中间不能有空格,可以使用下划线(_)。
- 不能使用标点符号。
- 不能使用bash里的关键字(可用help命令查看保留关键字)。
1.变量可以被重新定义
2.使用readonly可以将变量定义为只读
3.unset可以删除变量 不能删除只读变量
```shell
echo "hello the world!"
your_name="zhangchaomiao"
echo ${your_name}
myWeb="http://www.baidu.com"
readonly myWeb
#myWeb="http://www.sohu.com"
echo ${myWeb}
home="hubei"
unset home
echo ${home}//空
```
除了显式地直接赋值,还可以用语句给变量赋值,如:
```shell
for file in ls /etc
或
for file in $(ls /etc)
```
## 2、变量类型
运行shell时,会同时存在三种变量:
- **1) 局部变量** 局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。
- **2) 环境变量** 所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。
- **3) shell变量** shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行
## 3、shell字符串
**字符串是shell编程中最常用最有用的数据类型(除了数字和字符串,也没啥其它类型好用了),字符串可以用单引号,也可以用双引号,也可以不用引号。**
单引号字符串的限制:
- 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
- 单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。
```shell
your_name='runoob'
str="Hello, I know you are \"$your_name\"! \n"
echo -e $str
```
输出结果为
```shell
Hello, I know you are "runoob"!
```
双引号的优点:
- 双引号里可以有变量
- 双引号里可以出现转义字符
### 拼接字符串
```shell
your_name="runoob"
# 使用双引号拼接
greeting="hello, "$your_name" !"
greeting_1="hello, ${your_name} !"
echo $greeting $greeting_1
# 使用单引号拼接
greeting_2='hello, '$your_name' !'
greeting_3='hello, ${your_name} !'
echo $greeting_2 $greeting_3
输出结果为
hello, runoob ! hello, runoob !
hello, runoob ! hello, ${your_name} !
```
### 获取字符串长度
```shell
string="abcde"
echo ${#string} #输出 5
```
### 提取子字符串
```shell
#参数1表示从索引1处开始提取 参数4表示截取4个字符
string="runoob is a great site"
echo ${string:1:4} # 输出 unoo
```
### 查找子字符串
```shell
#查找字符 i 或 o 的位置(哪个字母先出现就计算哪个):
string="runoob is a great site"
echo expr index "$string" io # 输出 4
```
## 4、shell数组
### 创建数组
```shell
array_name=(value0 value1 value2 value3)
array_name[0]=value0
array_name[1]=value1
array_name[n]=valuen
可以不使用连续的下标,而且下标的范围没有限制。
```
### 读取数组
```shell
#使用 @ 符号可以获取数组中的所有元素
echo ${array_name[@]}
```
### 获取数组长度
```shell
#*或@都可以
echo ${#array_name[*]}
```
### 获取数组单个元素长度
```shell
#获取第n个数组元素的长度
echo ${#array_name[n]}
```
## 5、传递参数
```shell
#$0为执行的文件名 $n为第n个参数
echo "执行的文件名:$0";
echo "第一个参数为:$1";
echo "第二个参数为:$2";
echo "第三个参数为:$3";
echo "传递到脚本的参数个数:$#";
#使用""将$*括起来传的参数等价于一个参数"a b c"
#使用""将$@括起来传的参数等价于三个参数"a""b""c"
echo "显示所有向脚本传递的参数:"$*"";
echo "脚本运行的当前进程ID号:$$";
echo "后台运行的最后一个进程的ID号:$!";
echo "显示shell使用的当前选项:$-";
echo "显示最后命令的退出状态0表示无错误:$?";
```
## 6、运算符
1.expr是一款表达式计算工具
2.表达式和运算符之间必须要有空格
3.完整的表达式要被``包含而不是单引号
```shell
val=`expr 2 + 2`
echo "两数之和为 : $val"
```
### 算术运算符
```shell
a=10
b=20
val=`expr $a + $b`
echo "a + b : $val"
val=`expr $a - $b`
echo "a - b : $val"
#乘号做运算时需在前边加上\
val=`expr $a \* $b`
echo "a * b : $val"
#a/b结果为0
val=`expr $b / $a`
echo "b / a : $val"
val=`expr $b % $a`
echo "b % a : $val"
#if与括号与变量间全都要加上空格
if [ $a == $b ]
then
echo "a 等于 b"
fi
if [ $a != $b ]
then
echo "a 不等于 b"
fi
```
### 关系运算符
```shell
:<<EOF
-eq:检测两个数是否相等,相等返回 true
-ne:检测两个数是否不相等,不相等返回 true
-gt:检测左边的数是否大于右边的
-lt:检测左边的数是否小于右边的
-ge:检测左边的数是否大于等于右边的
-le:检测左边的数是否小于等于右边的
EOF
a=10
b=20
if [ $a -eq $b ]
then
echo "$a -eq $b : a 等于 b"
else
echo "$a -eq $b: a 不等于 b"
fi
```
### 逻辑运算符
```shell
#-O 逻辑或运算 || 短路或
#-a 逻辑与运算 && 短路与
a=10
b=20
if [ $a != $b ]
then
echo "$a != $b : a 不等于 b"
else
echo "$a == $b: a 等于 b"
fi
if [ $a -lt 100 -a $b -gt 15 ]
then
echo "$a 小于 100 且 $b 大于 15 : 返回 true"
else
echo "$a 小于 100 且 $b 大于 15 : 返回 false"
fi
if [[ $a -lt 100 || $b -gt 100 ]]
then
echo "返回 true"
else
echo "返回 false"
fi
```
### 字符串运算符
```shell
:<<EOF
=检测字符串是否相等 !=
-z检测字符串长度是否为0 为0返回true
-n长度不为0返回true
$ 检测字符串是否为空 不为空返回true
EOF
a="abc"
b="efg"
if [ -n "$a" ]
then
echo "-n $a : 字符串长度不为 0"
else
echo "-n $a : 字符串长度为 0"
fi
```
### 文件测试运算符
```shell
:<<!
文件测试运算符
-b 检测文件是否是块设备文件
-c 检测文件是否是字符设备文件
-d 检测文件是否是目录
-f 检测文件是否是普通文件
-g 检测文件是否设置了SGID位
-k 检测文件是否设置了粘着位
-p 检测文件是否是有名管道
-u 检测文件是否设置了SUID位
-r 检测文件是否可读
-w 检测文件是否可写
-x 检测文件是否可执行
-s 检测文件是否为空 不为空返回true
-e 检测文件(包括目录)是否存在
!
file="/root/桌面/test.sh"
if [ -r $file ]
then
echo "文件可读"
else
echo "文件不可读"
fi
if [ -w $file ]
then
echo "文件可写"
else
echo "文件不可写"
fi
if [ -x $file ]
then
echo "文件可执行"
else
echo "文件不可执行"
fi
if [ -f $file ]
then
echo "文件为普通文件"
else
echo "文件为特殊文件"
fi
if [ -d $file ]
then
echo "文件是个目录"
else
echo "文件不是个目录"
fi
if [ -s $file ]
then
echo "文件不为空"
else
echo "文件为空"
fi
if [ -e $file ]
then
echo "文件存在"
else
echo "文件不存在"
fi
```
## 7、echo命令
```shell
#最外层双引号可以省略
echo \"It is a test\"
#read命令从标准输入中读取一行 并把每个字段的值指定给shell变量
#-p输入提示文字 -n输入字符长度限制 -t输入限时 -s隐藏输入内容
read -p "请输入一段文字" -n 6 name
echo "$name It is a test"
#-e开启转义 -n换行 -c不换行
echo -e "OK! \n"
echo "It is a test"
#命令使用``
echo `date`
```
## 8、printf命令
```shell
:<<!
转义序列
\a 警告字符,通常为ASCII的BEL字符
\b 后退
\c 不显示输出结果中任何结尾的换行字符
\f 换页
\n 换行
\r 回车
\t 水平制表符
\v 垂直制表符
\\ 一个字面上的反斜杠字符
\ddd 表示1到3位数八进制值的字符,仅在格式字符串中有效
\0ddd 表示1到3位的八进制值字符
!
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
# format-string为双引号
printf "%d %s\n" 1 "abc"
# 单引号与双引号效果一样
printf '%d %s\n' 1 "abc"
# 没有引号也可以输出
printf %s abcdef
# 格式只指定了一个参数,但多出的参数仍然会按照该格式输出,format-string 被重用
printf %s abc def
printf "%s\n" abc def
printf "%s %s %s\n" a b c d e f g h i j
# 如果没有 arguments,那么 %s 用NULL代替,%d 用 0 代替
printf "%s and %d \n"
```
## 9、流程控制
### if语句
```shell
a=10
b=20
if [ $a == $b ]
then
echo "a 等于 b"
elif [ $a -gt $b ]
then
echo "a 大于 b"
elif [ $a -lt $b ]
then
echo "a 小于 b"
else
echo "没有符合的条件"
fi
```
### for循环
当变量值在列表里,for循环即执行一次所有命令,使用变量名获取列表中的当前取值。命令可为任何有效的shell命令和语句。in列表可以包含替换、字符串和文件名。in列表是可选的,如果不用它,for循环使用命令行的位置参数。
```shell
#一般格式
for var in item1 item2 ... itemN
do
command1
command2
...
commandN
done
#写成一行
for var in item1 item2 ... itemN; do command1; command2… done;
```