linux command
linux command
图形界面能做到的事情,命令行也能做到,命令行能做到的事情,图形界面不一定能做到
what is a shell
shell的中文译为“壳”,这里的“壳”是相对于操作系统内核而言的,用户通过shell来与操作系统的内核交互,操作系统启动以后呈现在用户面前的也许是可以进行交互的图形界面或者是漆黑的命令行界面,它们都叫作shell,图形界面和命令行提供了不同的与操作系统内核交互的能力,通常来说图形界面更为简单直观而命令行更为灵活强大,shell的本质是一个命令解释器(图形界面捕捉鼠标的点击动作等信息,命令行则对输入的命令字符串进行解析),捕获并解析用户输入,调用各种程序来响应用户的交互
wildcard character
通配符是命令行中简单而有效的字符串匹配解决方案,值得注意的是不要将其与正则表达式相混淆
? 任意一个字符
* 任意多个字符,注意该通配符无法越过路径分隔符进行匹配
[abc] 自定义字符集,仅匹配集合中的一个字符
[!abc] 自定义字符集取反,仅匹配一个不在集合中的字符
[[:class:]] 预定义字符集,仅匹配一个字符,class可以是alnum, alpha, digit, lower, upper
redirection
默认情况下,程序的标准输入流来自于系统的标准输入文件(一般映射为键盘),程序的标准输出流以及标准错误输出流则流向系统标准输出文件(一般映射为屏幕),所谓重定向就是指改变程序输入/出流的流向
重定向程序标准输出流,ls程序默认标准输出流指向系统标准输出文件
$ ls -l /usr/local > test.txt
# => because output is redirected to file, so display nothing
$ > test.txt
# => create or clean a file
$ ls -l /usr >> test.txt
# => append content into file
重定向程序标准错误输出流,ls程序默认标准错误输出流指向系统标准错误输出文件
$ ls -l /usr/empty 2> test.txt
# => redirect error information into file, so display nothing
$ ls -l /usr/nothing 2>> test.txt
# => append content into file
$ ls -l /usr/nothing 2> /dev/null
# => redirect content into black-hole
重定向标准输出流和标准错误输出流到同一个文件
$ ls -l /usr/local /usr/empty > test.txt 2>&1
# => old-style
$ ls -l /usr/local /usr/empty &> test.txt
# => new-style
$ ls -l /usr/local /usr/empty &>> test.txt
# => append content into file
重定向程序标准输入流,cat程序默认的标准输入流指向系统的标准输入文件
$ cat
hello world # input from standard-input
hello world # display in standard-output
$ cat < test.txt
# => read from file, and display in standard-output
$ cat test.txt > temp.txt
# => redirect std-input and std-output
pipe
管道的本质还是重定向,只不过是将一系列程序的标准输入和标准输出链接起来而已,准确来讲是将上一个程序的标准输出重定向到下一个程序的标准输入,从数据处理的角度来看,我们可以认为管道是对数据流的多级处理工具
$ ls -l /usr/bin /bin | sort | uniq | wc -l
tee
在管道中如果某个程序想要重定向标准输出流到文件的话,就意味着紧跟在后面的程序将得不到输入流,tee就是为解决此问题而生的
$ ls -l /usr/bin | tee test.txt | wc -l
cat
-
合并多个文件,
cat movie.part.*.mp4 > movie.mp4
-
创建文件,
cat > profile.txt
-
显示文件内容,
cat profile.txt
uniq
剔除已排序数据中的重复行,内容可来自标准输入或文件
$ uniq test.txt
$ ls -l ~ | uniq
$ ls -l ~ | uniq -d
# => display duplicate items
wc
单词计数程序,统计内容行数,单词数,字节数,内容可来自文件或标准输入
$ ls -l | wc -l
head/tail
提取文件头和文件尾
$ head -n 10 test.txt
# => file head 10 line
$ head -n -10 test.txt
# => except file tail 10 line
$ tail -n 10 test.txt
# => file tail 10 line
$ tail -n +10 test.txt
# => except file head 10 line
$ head -n 100 test.txt | tail -n 50
# => from 50 to 100 line
$ tail -f /var/log/messages
# => blocked monitor system messages
command expansion
在你键入命令到命令被执行期间发生了命令扩展,比如通配符,家目录符号等都被扩展为精确的描述后命令才开始执行,此外这里需要提及两个在命令扩展之前进行的命令预处理步骤:对转义符的解析以及对命令参数进行分割(以空白作为分隔符)
-
通配符的扩展,又称之为路径扩展,通配符常用于匹配路径名(文件/目录的路径)
-
家目录符号扩展,将
~
扩展为当前用户家目录的绝对路径,~bob
扩展为特定用户家目录的绝对路径 -
算术表达式扩展,即计算算术表达式的结果,算术表达式的格式:
$((expression))
,表达式仅允许整数运算,可以使用的运算符有+,-,*,**,/,%,表达式中可以插入任意空格,表达式是可以嵌套的并且可以简化书写格式,例:将$(( $((5+2)) * 4))
简化为$(( (5+2) * 4))
-
大括号扩展,扩展成一系列类似项,例如:
picture.0{0..2}.png
将扩展为picture.00.png, picture.01.png, picture.02.png
,profile.{a, k}.txt
将扩展为profile.a.txt, profile.k.txt
,a{b{1, 2}, c{3, 4}}
将扩展为ab1, ab2, ac3, ac4
-
变量扩展,如果变量不存在则扩展为一个空串,变量命令格式:
$varname
-
命令扩展,如果在一个命令中嵌入另一个命令则先要扩展执行被嵌入的命令,例:
file $(which find)
,老式的写法是用反引号包住命令 -
历史命令扩展,
!!
扩展为最近执行的命令,!number
最近执行的第几个命令,!some
最近以some开头的命令,!?some
最近包含some的命令
避免命令扩展的方法,可以通过使用引号包裹命令来阻止命令的扩展,双引号可以阻止含空白的参数被分割,通配符和家目录符的扩展,以及大括号扩展都将失效,如果使用单引号包裹命令则所有的命令扩展都将失效(包括转义符),如果你仅仅只是希望个别命令扩展是失效的,你可以使用转义符对其进行转义
shortcut
在GUI程序中下面有的快捷键可能被占用了,但在terminal下所有的快捷键都能正常工作的
Ctrl-A 光标移动到行首
Ctrl-E 光标移动到行尾
Ctrl-F 光标前移一个字符
Ctrl-B 光标后移一个字符
Alt-F 光标前移一个单词
Alt-B 光标后移一个单词
Ctrl-L 跟clear功能相同
Ctrl-D 删除光标处的字符
Ctrl-T 光标处的字符和它前面的字符对调
Alt-T 光标处的单词和它前面的单词对调
Alt-L 光标处到单词尾的字符转为小写
Alt-U 光标处到单词尾的字符转为大写
Ctrl-K 剪切光标到行尾的文本
Ctrl-U 剪切光标到行首的文本
Alt-D 剪切光标到单词尾的文本
Alt-Backspace 剪切光标到单词头的文本
Ctrl-Y 将缓存区的文本粘贴到光标处
Alt-$ 等效于两次tab
Alt-* 将自动补齐的匹配项都插入命令行
Ctrl-R 进入历史命令查找模式
version upgrade
软件是会经常升级的,当安装新版本软件时将旧版本软件删除并不是一个好的做法,尤其对于像python之类被系统严重依赖的软件,删除旧的软件将会带来意想不到的各种系统功能故障,更好的做法是给升级一个过渡期甚至保持多版本共存,以python为例,假定python的安装位置为/usr/bin/python
且系统现在的版本为2.6,现要升级到2.7,首先保留旧版本软件mv /usr/bin/python /usr/bin/python2.6
,将2.7版安装到/usr/bin/python2.7
,再创建指向新版本的符号链接文件ln -s /usr/bin/python /usr/bin/python2.7
,这样在软件升级之后,你随时可以通过变化符号链接文件的指向来在两个版本之间切换
command type
命令行中输入的命令可以分为:可执行程序以及脚本文件,内建shell命令,shell函数,alias命令。
查看命令类型: type builtin
查看命令路径: which ls
,因为是根据PATH来进行搜索的,所以shell内建命令以及shell函数是无法找到的,或者whereis ls
搜索合适的命令: apropos keyword
或man -k keyword
命令简介: whatis ls
alias
$ type ll
# => ll is aliased to `ls -l --color=auto'
$ alias
# => list current aliases
$ alias alias_name='command'
# => set alias for current termianl session
$ \ls
# => use the original command, not alias
$ unalias alias_name
# => unset alias for current terminal session
为特定用户设置别名,在~/.bashrc
文件中添加别名,并source ~/bashrc
在当前会话中生效
为所有用户设置别名,在/etc/bashrc
文件中添加别名,并source /etc/bashrc
在当前会话中生效
CentOS Release Version
$ cat /etc/*release
$ cat /etc/issue
$ cat /etc/issue.net
$ rpm -q centos-release
$ lsb_release -d -s # lsb => Linux Standard Base
Kernel Version & Machine Architecture
$ uname -r # kernel version
$ uname -m # machine architecture
$ arch # machine architecture
$ cat /proc/version # kernel version and machine information
script interpter path
常常可以看到shell脚本的开头有这么一行:#!/bin/bash
,该行的作用就是在运行脚本时告诉系统去哪里可以找到脚本解释器,同样对于python,perl,ruby也一样,需要在脚本文件的第一行中给出执行该脚本的解释器位置,但是对于这些脚本语言有个问题,脚本开发者不能假设用户脚本解释器的安装位置,当然一般情况下用户会将其安装到/usr/bin/
下面,例如你可以在python脚本文件开头写:#!/usr/bin/python
,但是如果用户将解释器安装到了别的位置的话该脚本就无法执行了,这里有一个好一点的方法,系统中提供了一个可执行程序/usr/bin/env
(链接到/bin/env
),你可以这样来声明解释器位置:#!/usr/bin/env python
,env程序负责从PATH中找到可用的解释器
software package type
linux下如果你用yum搜索可用packages的时候一般你会得到两种类型的包: package.i686和package-devel.i686,那么这两种包的区别在哪呢?package-devel.i686是提供给基于这个包进行开发的人使用的,该包中除了提供binary,libinary,resouces之外还提供了头文件,学过C语言应该知道,你要使用一个库(包)的话必须引用该库的头文件才行,而package.i686中只有binary,libinary等,所以如果仅仅因为系统需要软件的功能而安装的话就直接装package.i686,但如果你是用于开发或者该包是被别的包依赖的话就要安装package-devel.i686了
compress and archive type
$ gzip test.txt
# => generate file test.txt.gz and remove original file
$ gzip -r mydir
# => recursive compress directory
$ gzip -c test.txt > test.txt.gz
# => reserve original file
$ gzip -tv test.txt.gz
# => test compressed file
$ gzip -d test.txt.gz
# => uncompress file
$ gunzip test.txt
# => uncompress file
$ gunzip -c test.txt
# => display compressed file content
$ zcat test.txt.gz
# => display compressed file content
$ zless test.txt.gz
# => display compressed file content
$ bzip2 test.txt
$ bunzip2 test.txt.bz2
$ bzcat test.txt.bz2
$ bzip2recover test.txt.bz2
压缩程序gzip,归档压缩后文件后缀名为.tar.gz,解压示例: tar -vxz -f example.tar.gz
压缩程序bzip2,压缩归档后文件后缀名为.tar.bz2,解压示例: tar -vxj -f example.tar.bz2
压缩程序xz,压缩归档后文件后缀名为.tar.xz,解压示例: tar -vxJ -f example.tar.xz
rsync
rsync是本地与远程(或本地)数据的同步工具
$ rsync -av workspace backup
$ rsync -av --delete workspace backup
$ rsync -av --delete --rsh=ssh workspace remote-host-name:/path/to/backup
$ rsync -av --delete rsync:://rsync.example.com/path/to/backup workspace
user and group
操作系统通过用户来管理对计算机资源的使用,通过组来方便对用户的管理。
每个用户有一个用户名和一个用户ID(UID),用户ID是操作系统真正用来管理标识用户的,UID为32位长,从0开始,最大一般到60000。用户分为:root用户(uid为0)、系统用户(uid 1~499)、普通用户(uid 500+)。一个用户可以属于一个主组,并同时属于一个或多个附属组
文件/目录的文件系统常规权限是针对三类用户:所有者,组成员,其他人设置的,每类用户对文件/目录的读,写,执行对应三个权限位,所有常规权限位共有9位
用户、组信息保存在以下三个文件中:/etc/passwd
(用户信息),/etc/shadow
(用户密码),/etc/group
(组信息)
查看用户id以及组id: id
文件/目录所有者或超级用户可以更改文件/目录的权限: chmod 600 test.txt
或chmod a=rwx, o=r test.txt
新建文件/目录的权限由umask决定,文件的最高权限是666,目录的最高权限是777,普通用户默认umask是0002,所以新建文件的权限是664,新建目录的权限是775,超级用户的umask是022,所以新建文件的权限是644,新建目录的权限是755,可以通过umask命令来查看或修改umask,值得注意的是umask是一个4位数,一般将最高位设为0即可
文件系统的特殊权限位,权限位总共由12位构成,除了上面提及的普通读写执行共9位权限位外,还有三个特殊权限位,setuid位,当为可执行文件设置了该权限位后,试图执行该程序的用户的权限将会提升为该程序文件所有者的权限,setgid权限位,当对目录设置该权限位后,用户在该目录下创建的文件并非属于用户的主组而是属于该目录的主组,sticky位,设置了该权限后,除非该文件/目录的所有者和超级用户,任何用户都无法删除该项,三个特殊权限位的设置方法依次为: chmod u+s program
,chmod g+s directory
,chmod +t item
超级用户权限
更改用户: chown bob test.txt
更改用户组: chown :bob test.txt
更改用户和用户组: chown bob: test.txt
或chown bob:bob test.txt
更改用户的密码,使用命令passwd
切换账户: su [-[l]] [username]
切换到别的账户执行命令: su -c 'command'
,值得注意的是,切换到别的账户会导致开启新的shell,所以要执行的命令要在新shell中进行扩展,故而在当前shell要用单引号包裹避免命令扩展发生
sudo机制,超级用户掌握有授予特定权利的控制权,可以精确到被授权用户可以执行哪些命令,被信任授权的用户只需要使用自己的密码即可执行受限命令,并且不会开启新的shell
process
查看进程树: pstree
显示系统资源使用情况: vmstat 5
查看系统当前的运行进程信息: ps aux
实时查看系统运行的进程状态: top
要想将程序运行在后台,只需要在命令尾部添加&
,之后返回进程id以及作业号
查看当前的作业: jobs
后台作业回到前台: fg %jobnum
终止当前进程Ctrl-C,暂停当前进程Ctrl-Z(本质是向进程发送信号),被暂停的进程既可以移到后台运行也可以移到前台运行
向进程发送信号: kill [-signal] PID...
shell session environment
当启动shell程序时会从系统配置文件以及用户配置文件中读取内容来设置shell会话的环境,比如PATH变量的构建,命令行提示符样式的设置等,在shell会话期间你可以随意更改这些环境设置,但修改的效果也仅仅停留于会话期间,除非修改相应的配置文件
显示环境变量和shell变量以及函数: set
显示环境变量: printenv
shell会话可以分为login会话和non-login会话,前者要求在开启shell会话时输入用户名和密码,后者则无需登录即可直接进行shell会话,例如图形界面下进入的虚拟终端就是non-login会话,不同类型会话的区别在于启动会话时读取的配置文件不同,login会话启动时读取/etc/profile
和~/.bash_profile
(没有该文件则依次尝试~/.bash_login
,~/.profile
)配置文件,而non-login会话启动时读取/etc/bashrc
和~/.bashrc
配置文件,并且non-login会话继承父进程的环境设置,一般来说如果要设置PATH则修改~/.bash_profile
文件,其余环境设置建议放在~/.bashrc
文件中,如果修改了配置文件为了使其在当前会话中生效,需要使用source
命令重新读取配置文件
device mount
文件系统(设备)的挂载,即将文件系统(设备)与系统目录树的某个节点关联起来,只有将设备挂载后才可以通过系统目录树访问该设备
显示系统启动时挂载的设备: cat /etc/fstab
显示当前挂载的设备: mount
挂载CD-ROM到目录树: mount -t iso9660 /dev/hdc /mnt/test/
,被挂载的节点必须是一个目录,如果该目录不为空则直到卸载设备之前原内容不可见
卸载设备: umount /dev/hdc
,因为外设一般都使用了缓存区技术来读写数据,所以在手动拔出外设之前务必要将其卸载,以确保缓存区数据完全写入了外设
系统启动时在挂载文件系统之前会先对文件系统完整性进行检测,检测程序是fsck
,各文件系统被检测的先后顺序由/etc/fstab
文件的最有一列指定,并且fsck会尽力对损坏的文件系统进行修复,将修复的文件放在/lost+found
目录中
dd
该程序不是以文件为单位进行数据复制,而是以设备数据块进行数据复制的,dd if=/dev/sdd of=/dev/sde
CD-ROM
-
创建CD-ROM镜像文件,由挂载的CD-ROM来创建镜像文件:
dd if=/dev/cdrom of=test.iso
,由若干文件创建镜像文件:genisoimage -o test.iso -R -J ~/dir/
-
檫除待写入光盘的内容:
wodim dev=/dev/myrom blank=fast
-
将镜像文件写入光盘:
wodim dev/dev/myrom test.iso
如果仅仅只要查看镜像文件的内容,可以将镜像文件挂载到目录树: mount -t iso9660 -o loop test.iso /mnt/tmp
disk format
-
卸载设备的所有分区
-
对设备进行分区:
fdisk /dev/sdb
-
将分区格式化为期望的文件系统:
mkfs -t ext3 /dev/sdb1
grep
Description:
以行为处理单位对FILEs或者标准输入的内容进行基本正则表达式(BRE)匹配,默认输出匹配的行(可以改变该行为)
Usage:
grep [OPTIONS] PATTERN [FILE...]
grep [OPTIONS] [-e PATTERN | -f PATTERN_FILE] [FILE...]
Options:
Match selection and interpretation:
-E, --extend-regexp PATTERN is 扩展正则表达式(ERE)
-F, --fixed-strings PATTERN is a set of newline-separated fixed strings
-G, --basic-regexp PATTERN is 基本正则表达式(BRE), *default*
-P, --perl-regexp PATTERN is perl正则表达式
-e, --regexp=PATTERN 用该正则表达式匹配,通过该选项可以指定多个PATTERN
-i, --ignore-case 不区分大小写,以前用的是-y
-w, --word-regexp 强制PATTERN仅匹配整个单词
-x, --line-regexp 强制PATTERN仅匹配整行
-z, --null-data 行结束符不再是换行符而是值为0的byte
-f, --file=FILE 从文件中加载要用到的PATTERN,每行一个PATTERN
-v, --invert-match 提取不能匹配PATTERN的行
Output control:
-m, --max-count=NUM 限制最大匹配数量
-b, --byte-offset 显示输出内容在原内容中的byte-offset
-n, --line-number 为输出内容添加行号
--line-buffered flush output on every line
-H, --with-filename 显示输出内容来自哪个文件
-h, --no-filename 不显示输出内容来自哪个文件
--label=LABEL standard input以LABEL作为文件名
-o, --only-matching 不整行显示而是仅仅显示匹配部分
-q, --quiet, --slient 不显示匹配情况,如果有匹配退出码为0
--binary-files=TYPE 假定二进制文件的类型"binary","text","without-match"
-a, --text 等价与--binary-files=text
-I 等价与--binary-files=without-match
-d,--directories=ACTION 如何处理目录:"read","recurse","skip"
-R,-r,--recursive 等价与-directories=recurse
-D, --devices=ACTION 如何处理devices,FIFO,socket:"read","skip"
--include=FILE_PATTERN 符合FILE_PATTERN的文件作为输入文件
--exclude=FILE_PATTERN 输入文件中排除符合FILE_PATTERN的文件和目录
--exclude-from=FILE 输入文件中排除符合FILE的文件
--exclude-dir=PATTERN 输入文件中排除符合PATTERN的目录
-L,--files-without-match输出不含有任何匹配项的文件名
-l,--files-with-matches 输出含有至少一个匹配项的文件名
-c, --count 显示每个文件中匹配(或没匹配)的总行数
-T, --initial-tab make tabs line up(if needed)
-Z, --null print 0 byte after FILE name
context control:
-B,--before-context=NUM 显示匹配内容附近的若干行
-A,--after-context=NUM
-C,--context=NUM around
-NUM 等价与--context=NUM
--color[=WHEN],
--colour[=WHEN] 高亮匹配内容,WHEN is 'always','never','auto'
-U, --binary 在行尾不移除CR字符(For MSDOS)
-u, --unix-byte-offsets 输出内容byte-offset时不对CR计数(For MSDOS)
Miscellaneous:
-s, --no-messages supperss(压制)错误messages,不予显示
-V, --version print version
--help print help information
--mmap 不考虑向后兼容
Example:
-
search for the given string in a single file:
grep "something" test.txt
-
search for the given string in multiple files:
grep "somethin" test*
-
case insensitive:
grep -i "Something" test.txt
-
using Regexp:
grep "line.*empty" test.txt
-
only metch word, not sub-string in word:
grep -w "is" test.txt
-
displaying lines before/after/around to the match:
grep -A 3 "something" test.txt
,grep -B 3 "something" test.txt
,grep -C 3 "something" test.txt
-
highlighting the matched:
export GREP_OPTIONS='--color=auto' GREP_COLOR='100;8'
,grep "something" test.txt
-
searching in all files recursively directory:
grep -r "something" *
-
invert to unmatched:
grep -v something test.txt
-
using multiple regexp and invert:
grep -v -e "some" -e "other" test.txt
-
just counting the number of the matched:
grep -c somethig test.txt
-
display only the file names with matched(or nomatched):
grep -l something test*
,grep -L something test*
-
show only matching string not the line:
grep -o "something" test.txt
-
show the position of match in the line:
grep -o -b "something" test.txt
-
with line number:
grep -n something test.txt
xargs
xargs程序可以将标准输入内容转换为别的程序需要的参数并传入参数调用程序: echo * | xargs ls -ld
,默认情况xargs将输入内容中的空白字符当成参数的分隔符,但你可以指定空字符作为参数分隔符: echo * | xargs --null ls -ld
,这在文件名中含有空格时很有用
file information
$ stat test.txt
file location
locate程序通过文件系统数据库查找文件: locate bin/md5
,实质上是查找匹配的路径字符串,因为文件系统数据库是由程序updatedb
进行定期更新的,所以对文件系统最新的改动不能通过locate找到,除非手动运行updatedb
find程序通过各种文件属性实时扫描目录进行文件查找,通过下面几个示例来了解一下强大的find程序:
$ find ~ -type f -name "*.png" -size +1M
$ find ~ \(-type f -not -perm 0600 \) -or \(-type d -not -perm 0700 \)
$ find ~ -type f -name "*~" -delete
$ find ~ -type f -name "*~" -exec ls -l '{}' ';'
$ find ~ -type f -name "*~" -ok rm '{}' ';'
$ find ~ -type f -name "*~" -exec ls -l '{}' +
$ find ~ -type f -name "*~" -print | xargs ls -l
$ find ~ -type f -name "*~" -print0 | xargs --null ls -l
查找binary,manual,source-file
$ whereis something
通过PATH路径搜索
$ which find
—————————-source———————————
when you modify or add something into a configure file, in order to make
effect in your current shell session, you should:
source .bash_profile
or
. .bash_profile
but if you delete a item in a configure file, the source
is not working
,you must open a new terminal.
————————find———————-
you can search any file by command find
find
directory: you want search in that directory, default is current dir
condition: file specifier
action: process the search result
example:
find
find . -name 'my*'
find . -nmae 'my*' -ls
find . -type f -mmin -10
————————–locate———————-
locate search file by linux built-in filesystem database(/var/lib/locatedb),
you should update database(command: updatedb) before search file
locate -i
-i: ignore case
example:
locate /etc/sysconfig
locate -i ~/python
—————Whereis——————-
search by program name, file types support: binary, man file, source file
whereis [-bms]programe_name
-b: just search binary file
-m: just search man page file
-s: just search source code file
$ locate