- Commands
- nohup
- useradd
- nc
- strings
- bc
- basename
- dirname
- RANDOM
- seq
- envsubst
- read
- crontab
- uname
- uptime
- shopt
- chsh/chpass/chfn
- bash
- ex(vim)
- ed
- exit
- gcc
- make
- gzip/gunzip
- bzip2/bunzip2
- tar
- zip/unzip
- rsync
- touch
- fdisk
- mkfs
- fsck
- mount/unmount
- dd
- md5sum
- ping
- traceroute
- ifconfig
- apt-get
- netstat
- ftp
- lftp
- wget
- curl
- ssh
- scp
- sftp
- lsof
- rz/sz
- locate
- find
- test
- xargs
- exec
- awk
- yum
- brew
- vim(别名:ex)
- nano
- code
- open
- source
- let
- expr
- export
- ps
- top
- jobs
- fg/bg
- kill
- shutdown
- id
- chmod
- umask
- su
- sudo
- passwd
- chown
- chgrp
- clear
- printenv
- env
- set
- tee
- grep
- wc
- sort
- uniq
- cut
- paste
- join
- comm
- diff
- patch
- tr
- sed
- aspell
- nl
- fold
- fmt
- pr
- pgrep
- printf
- groff
- lpr
- a2ps
- lpstat
- lpq
- cancel
- cat
- alias
- unalias
- man
- info
- help
- whatis
- apropos
- which
- ln
- rm
- rmdir
- cp
- mv
- mkdir
- less
- more
- tail
- head
- file
- iconv
- ls
- cd
- pushd/popd
- cal
- date
- sleep
- tput
- df
- du
- free
- echo
- type
- pwd
- history
- whoami
- if
- for
- while
- until
- case
- getopts
如果你正在运行一个进程,而且你觉得在退出帐户时该进程还不会结束,那么可以使用 nohup
命令。该命令可以在你退出帐户/关闭终端之后继续运行相应的进程。
nohup command > myout.file 2>&1 &
增加用户。
# 增加用户
useradd -d /home/work work
# 创建密码
passwd work
瑞士军刀,接收文件利器。
接收机器:nc -l 9995 > testfile2
发送机器:nc 10.10.10.10 9995 < part-00000,其中 ip 为接收机器IP
在对象文件或二进制文件中查找可打印的字符串。
strings /bin/ls | grep -i libc
执行一些高级的数学计算,支持浮点数。
echo "4 * 0.56" | bc
no=54;
result=`echo "$no * 1.5" | bc`
echo "scale=2;3/8" | bc # 保留2位小数
echo "obase=2;100" | bc # 转为2进制
echo "obase=10;ibase=2;$no" | bc # ibase 输入进制,obase 输出进制
echo "sqrt(100)" | bc # Square root
echo "10^10" | bc # Square
获取文件名称,不包含路径。
PROGNAME="$(basename "$0")"
获取目录名称。
export SCRIPT_DIR="$(cd $(dirname $0); pwd)"
readonly JOBDIR=$(pwd)
readonly PROJDIR=$(cd $(dirname $0)/../; pwd);
通过 $RANDOM
可以生成随机数,默认范围是 0 ~ 32767。
echo $RANDOM
echo $RANDOM | md5
echo $RANDOM | md5 | cut -c 1-6
for i in seq 1000; do echo $RANDOM >> 1.txt; done
cat 1.txt | awk '{ if( length($0)<=3 ) print }' | wc -l
echo $((RANDOM%10))
还可以通过其他方式生成随机数。
# 使用 date 生成随机字符串
date +%s | md5sum | head -c 10
# 使用 /dev/urandom
cat /dev/urandom | head -n 10 | md5sum | head -c 10
# 使用 linux uuid
cat /proc/sys/kernel/random/uuid
# 使用 openssl
if [[ ! -z $(which openssl) ]]; then
echo $(openssl rand -base64 40 | sed 's/[^a-z]//g' | cut -c 3-12)
fi
# 使用 awk 中的随机函数
awk 'BEGIN{srand();print rand()*1000000}'
打印数字序列。
seq 9
seq 1 12
for i in $(seq 1 12); do echo $i; done
另外一个使用范围扩展 {..}
,还可以补充前置 0
。
for i in {01..12}; do echo $i; done
将环境变量传递给文件,envsubst 是一个非常好用的工具,尤其善于处理和环境变量相关的事务。
envsubst < original_file > destination_file
source source.txt && envsubst < tpl.txt > env_sub_txt_2
read -p var
读取用户输入赋值给变量 var,-p
参数提示文字。
read -p 'input a name: ' n
通过 crontab
命令,我们可以在固定的间隔时间执行指定的系统指令或 shell script 脚本。时间间隔的单位可以是分钟、小时、日、月、周及以上的任意组合,这个命令非常适合周期性的日志分析或数据备份等工作。
crontab [-u user] file crontab [-u user] [ -e | -l | -r ]
查看操作系统内核版本。
uname -a
cat /etc/issue
系统已经运行了多久了。
show how long system has been runnin
shopt
(sh option) 命令可以调整 Bash 的行为。它有好几个参数跟通配符扩展有关。
# 打开某个参数
$ shopt -s [optionname]
# 关闭某个参数
$ shopt -u [optionname]
# 查询某个参数关闭还是打开
$ shopt [optionname]
shopt
常见的参数如下:
dotglob 参数可以让扩展结果包括隐藏文件(即点开头的文件)。
nullglob 参数可以让通配符不匹配任何文件名时,返回空字符。
failglob 参数使得通配符不匹配任何文件名时,Bash 会直接报错,而不是让各个命令去处理。
extglob 参数使得 Bash 支持 ksh 的一些扩展语法,例如量词语法。
nocaseglob 参数可以让通配符扩展不区分大小写。
globstar 参数可以使得**匹配零个或多个子目录。该参数默认是关闭的。bash v4+ 才有。
Toggle the values of variables controlling optional behavior.
The -s flag means to enable (set) each OPTNAME;
the -u flag unsets each OPTNAME.
The -q flag suppresses output; the exit status indicates whether each OPTNAME is set or unset.
The -o option restricts the OPTNAMEs to those defined for use with `set -o'. With no options, or with the -p option, a list of all settable options is displayed, with an indication of whether or not each is set.
add or change user database information
开启子 shell。
vim - Vi IMproved, a programmer's text editor。
提供非可视化模式。
ed, red -- text editor.
不可见文本编辑器,可以输入命令对文本进行查看和编辑。
主要考察正则表达式的用法。
$ ed /etc/passwd
/^root/ # 显示以 root 开头的行
/\.$/ # 查询以 . 结尾的行
1,$p # 打印所有行,可视化显示
1,6p # 打印1,6行
1,$s/p.o/XXX/g # 全局替换
1,$s/^/>>/ # 行开头全部插入 >>
1,$s/^/ / # 行开头全部插入空格
1,$s/$/>>/ # 行末尾全部插入 >>
1,$s/..$// # 删除每行最后两个字符
/^$/ # 查询空行
/^\s+$/ # 查询空行(忽略空格)
1,$s/[aeiouAEIOU]//g # 删除所有元音
1,$s/[A-Z]/*/g
/[0-9]/
1,$s/[^a-zA-Z]//g
1,$s/[A-Za-z]\{4,7\}/X/g
1,$s/^.\{10\}//
1,$s/.\{5\}$//
1,$s/[a-zA-Z]\{6,\}/X/g
1,$s/\(.*\)\(.*\)/\2 \1/
退出当前 shell。
GNU C Compiler.
Utility to maintain programs
The configure
program is a shell script that is supplied with the source tree. Its job is to analyze the build environment.
The makefile
is a configuration file that instructs the make program exactly how to build the program. Without it, make will refuse to run.
The make
program will run, using the contents of Makefile to guide its actions. It will produce a lot of messages.
./configure
make
gzip 压缩文件。gunzip 解压缩文件。
gzip foo.txt
gunzip foo.txt.gz
类似 gzip,但是使用了不同的压缩算法,牺牲压缩速度,获取更高的压缩质量。
bzip2 foo.txt
bunzip2 foo.txt.bz2
打包/解包。
tar -czvf abc.tar.gz *
tar -xzvf abc.tar.gz *
find playground -name 'file-A' -exec tar rf playground.tar '{}' '+'
压缩成和解压缩 .zip
文件包, Windows 用户也可以用。
Linux 下优先使用 gzip,其次 bzip2,最后才 zip。
zip -r playground.zip playground
unzip ../playground.zip
检测两个文件夹的不同,并自动同步。
rsync options source destination
alias backup='sudo rsync -av --delete /etc /home /usr/local /media/BigDisk/backup'
创建文件或者修改文件修改时间(mtime)。
> newfile
touch newfile.md abc.js
touch {1..10}.js
创建分区使用 fdisk
命令,它是一个很低级的分区命令。
sudo umount /dev/sdb1
sudo fdisk /dev/sdb
格式化某个分区使用 mkfs
命令。
sudo mkfs -t ext4 /dev/sdb1
sudo mkfs -t vfat /dev/sdb1
修复磁盘分区使用 fsck
命令。
sudo fsck /dev/sdb1
输入 mount
可以查看挂载的设备,以及挂载到的文件系统树。
mount
mount -t iso9660 /dev/sdc /mnt/cdrom
unmount /dev/sdc
使用 dd
可以快速移动拷贝数据。
dd if=input_file of=output_file [bs=block_size [count=blocks]]
使用 md5sum
计算校验码。
md5sum image.iso
检测连接某个主机的网络是否通畅。
$ ping 10.232.232.com
$ ping qq.com
显示到某个主机的所有路由跳转。
$ traceroute www.qq.com
traceroute: Warning: www.qq.com has multiple addresses; using 182.61.200.6
traceroute to www.a.shifen.com (182.61.200.6), 64 hops max, 52 byte packets
1 * * *
2 * * *
查看本机 ip 可以使用 ifconfig
(最新版可以使用 ip
)。
主要查看 eth0
中的 inet
地址,另外 lo
地址为本机回文地址(127.0.0.1)。
Debian 系(例如 Ubuntu)安装软件。
apt-get update
apt-get install package_name
apt-get remove package_name
netstat 命令用于显示与IP、TCP、UDP和ICMP协议相关的统计数据,一般用于检验本机各端口的网络连接情况。
netstat -a # 列出所有当前的连接,包括所有状态的 tcp、udp、sockets
netstat -t # 列出所有 tcp 协议
netstat -u # 列出所有 udp 协议
netstat -l # 只列出监听中的连接
netstat -n # 禁用反向域名解析,加快查询速度,同时用户 ID 和端口号也优先使用数字显示
netstat -ant # 可以联合使用
netstat -p # 获取进程名、进程号以及用户 ID(需要 root 权限)
netstat -pe # 同时查看进程名(号)和进程所属的用户名
netstat -in # 输出网络接口设备的统计信息
netstat -aple | grep ntp # 查看某个服务是否运行
netstat -ant | grep 3306 # 查看某个端口是否打开(mac 下需要使用 lsof -i:port)
netstat -anp | grep pid # 查看某个 pid 状态(mac 下需要使用 lsof -p pid)
上传文件。
一个自动化 ftp 上传的代码如下:
#!/bin/bash
# Script to retrieve a file via FTP
FTP_SERVER=ftp.nl.debian.org
FTP_PATH=/debian/dists/stretch/main/installer-amd64/current/images/cdrom
REMOTE_FILE=debian-cd_info.tar.gz
# -n 禁止第一次连接的时候自动登陆
# hash 可以输出当前所记住的命令以及其缓存命中次数,利用 hash 缓存表可大大提高命令的调用速率
ftp -n << _EOF_
open $FTP_SERVER
user anonymous me@linuxbox
cd $FTP_PATH
hash
get $REMOTE_FILE
bye
_EOF_
ls -l "$REMOTE_FILE"
ftp 增强版,支持多个协议 (包括 HTTP)、失败重试功能、后台进程、TAB 填充,书签、排队、镜像、断点续传、多进程下载。
此命令的适用范围:RedHat、RHEL、Ubuntu、CentOS、SUSE、openSUSE、Fedora。
文档参考:http://lftp.yar.ru/lftp-man.html
lftp [用户名:密码@]ftp地址:传送端口(默认21)
lftp 192.168.1.8:21 # 匿名用户登录
lftp -u david 192.168.1.8 # 指定用户登录
ls
cd dir
# 下载
mget -c *.pdf # 把所有的pdf文件以允许断点续传的方式下载
mirror aaa/ # 将aaa目录整个的下载下来,子目录也会自动复制
pget -c -n 10 file.dat # 以最多10个线程以允许断点续传的方式下载 file.dat
# 上传
mirror -R 本地目录名 # 将本地目录以迭代(包括子目录)的方式反向上传到 ftp site
# 设置编码
set file:charset utf8
下载网络资源。
-O
输出文件名--no-check-certificate
不校验证书--header
添加头部信息,格式 "KEY:VALUE"
# 重试 10 次,日志放 log
wget -r --tries=10 http://fly.srk.fer.hr/ -o log
# 下载文件命名为 output.tar.gz,添加自定义 header
wget -O output.tar.gz --no-check-certificate --header "IREPO-TOKEN:07a2dd21-305a-496a-9b4e-be298821f13c" "https://abc.bbb.com/nodes/9074896/files"
构造 URL 发送请求。
transfer a URL.
curl is a tool to transfer data from or to a server, using one of the supported protocols (DICT, FILE, FTP, FTPS, GOPHER, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET and TFTP). The command is designed to work without user interaction.
Secure Shell(安全外壳协议) 的缩写,远程安全登录。
ssh [email protected]
ssh [email protected] commands
scp 为 secure copy 缩写,远程安全拷贝。
$ scp remote-sys:document.txt .
$ scp bob@remote-sys:document.txt .
sftp 为 secure ftp 缩写。
lsof(list open files)是一个列出当前系统打开文件的工具。
lsof # 列出所有打开的文件
lsof -i # 列出所有网络链接
lsof -i tcp # 列出所有 TCP 网络链接
lsof -i udp # 列出所有 UDP 网络链接
lsof -i :3306 # 列出谁在使用 3306 端口
lsof -p 34158 # 通过某个进程号显示该进程打开的文件
lsof -a -u yourname -i # 列出某个用户的所有活跃的网络端口
rz,sz 是 Linux/Unix 同 Windows 进行 ZModem 文件传输的命令行工具。优点就是不用再开一个 sftp 工具登录上去上传下载文件。
sz 将选定的文件发送(send)到本地机器。
rz 运行该命令会弹出一个文件选择窗口(receive),从本地选择文件上传到 Linux 服务器
从数据库快速检索文件名称。
递归遍历文件层次结构,查找符合条件的文件和目录,默认采用先序遍历,可以通过 -d
指定为后续遍历,格式为:
# path 为当前查找开始的目录
# {} 和 -exec 结合使用,代替匹配的文件
# \; 和 -exec 结合使用,表示命令结束
# -print 为预定义动作,还有 `-delete`,`-ls`,`-quit` 等动作
find path -option [ -print ] [ -exec -ok command ] {} \;
参数的值如果是数字,可以携带前缀:+n
表示 大于n
; -n
表示 小于n
,可用时间单位如下:
s
: 秒m
: 分h
: 时d
: 天w
: 月
时间可以组合,例如 -atime -1h30m
表达意思是最近 1 个半小时有访问的文件。
根据文件名称
来过滤文件,支持如下 globbing 字符:[]?*
。
find . -type f -name "[s-t]*.md" -print
根据正则表达式
来过滤文件,这里的正则表达式比 -name
支持的 globbing 要更加强大。
find . -regex "\./*[0-9]+\.png"
根据文件类型
来过滤文件,文件类型如下:
b
: 块设备文件c
: 字符设备文件d
: 目录f
: 普通文件l
: 符号链接文件p
: FIFOs
: socket
find . -type f -name "[s-t]*.md" -exec cat {} \;
find ~ -type f | wc -l
find ~ -type f -name "*.JPG" -size +1M | wc -l
根据文件大小
来过滤文件,大小单元如下:
b
: 块(512字节)c
: 字节w
: 字(2字节)k
: 千字节M
: 兆字节G
: 吉字节
# -size +500M,找出 500M 以上的文件
# print0 和 xargs -0 结合使用,用来解决文件名中有空格或特殊字符问题
# du -m 查看文件大小,以 M 单位显示
# sort -nr 按照文件大小降序排列
find / -size +500M -print0 | xargs -0 du -m | sort -nr
查找空文件。
find . -empty
类似 -print
的预定义动作,找到匹配文件并删除。
find ~ -type f -name '*.bak' -delete
find ~ -type f -name '*.bak' -print
find ~ -type f -and -name '*.bak' -and -print
find ~ -type f -name '*.bak' -ls
find ~ -type f -name '*.bak' -quit
根据路径查找文件。
find . -path "*wysiwyg*"
在过去 n 时间内被读取过的文件。
find . -name "*.log.*" -atime +7d | xargs rm
在过去 n 时间内文件数据元(例如权限等)修改过的文件。
在过去 n 时间内被修改过的文件。
find . -type f -mtime +7d -name "*.log" -exec mv {} /tmp/old_logs \;
最近 n 分钟有被访问过的文件。
最近 n 分钟文件数据元(例如权限等)修改过的文件。
最近 n 分钟有被修改过的文件。
打印出找到的路径(默认行为)。
find . -type f -name "[s-t]*.md" -print
遍历目录深度,类似的还有 maxdepth
和 mindepth
选项。
find . -type f -depth 1 -name "[s-t]*.md" -exec cat {} \;
查看比 file 更新的文件。
find playground -type f -newer playground/timestamp
execute 执行,直接执行后面的 command,不用询问是否执行。
由于大括号和分号对于 Shell 有特殊含义,因此需要转义或者单引号括起来。
find . -type f -name file.txt -exec cat {} \;
find . -type f -name file.txt -exec rm '{}' ';'
find ~ -type f -name 'foo*' -exec ls -l '{}' ';'
find ~ -type f -name 'foo*' -exec ls -l '{}' +
find playground -type f -name 'file-B' -exec touch '{}' ';'
类似 exec
,不过执行 command 前需要询问,需要输入 y
后才继续执行。
find . -type f -name file.txt -ok cat {} \;
find 经常和 xargs 联合使用,不过 xargs 一次执行的数量会有限制,这个需要注意。
find ~ -type f -name 'foo*' -print | xargs ls -l
( expression )
表达式运算,如果 expression
运行结果为 true,该表达式返回 true。
由于大括号对于 Shell 有额外含义,需要进行反斜杠转义。
-and与运算,可以省略
-and`。
expr -and expr
expr expr
-or
或运算。
# expr -or expr
find ~ \( -type f -not -perm 0600 \) -or \( -type d -not -perm 0700 \)
-not
非运算,也可以前置感叹号表示非 !expr
。
#-not expr
#!expr
find playground \( -type f -not -perm 0600 -exec chmod 0600 '{}' ';' \) -or \( -type d -not -perm 0700 -exec chmod 0700 '{}' ';' \)
测试条件,需要重点介绍。
test expression
# 等价于
[ expression ]
接收 pipe 数据流当做下一个命令的参数,需要重点介绍。
find ~ -type f -name 'foo*' -print | xargs ls -l
find ~ -type f -name 'foo*' -exec ls -l '{}' ';'
awk 既可以当做一个脚本命令,也可以当做一个脚本编程语言,awk 命令是三位创始人首字母缩写组合而成,因此没有特殊含义。
它依次处理文件的每一行,并读取里面的每一个字段。对于日志、CSV 那样的每行格式相同的文本文件,awk 可能是最方便的工具。
- grep 更适合单纯的查找或匹配文本
- sed 更适合编辑匹配到的文本
- awk 更适合格式化文本,对文本进行较复杂格式处理
# 完整模式
awk [-F re] [parameter...] ['pattern {action}'] [-f progfile][in_file...]
# 精简模式
awk -F delimeter 'pattern {action}' 文件名
参数说明:
-F
: 可选,设置字段分隔符,默认为空格和TAB,-F :
指定冒号为分隔符,-F [,:]
使用正则指定逗号和冒号为分隔符parameter
: 可选,为不同变量赋值pattern
: 模式(/pattern/
),或者条件($1 == a
)action
: 动作,例如print $1, $3
-f progfile
: 可选,允许 awk 调用并执行程序文件,该文件必须符合 awk 语法in_file
: awk 的输入文件,awk允许对多个输入文件进行处理。
举例说明:
# 最简单的例子
echo 'this is a test' | awk '{print $0}'
echo 'this is a test' | awk '{print $1, $2, $3, $4, $5}'
echo 'this is a test' | awk '{printf ("%-10s; %4s; %4s; %10s; \n", $1, $2, $3, $4)}'
echo 'this;is;a;test' | awk -F ';' '{print $1, $2, $3, $4}'
echo 'this,is:a:test' | awk -F [,:] '{print $1, $2, $3, $4}'
echo 'this,is,a,test' | awk -F [,,] '{print $1, $2, $3, $4}' # TODO: 这里只能打印出前两个字符 this is
awk /root/ /etc/passwd # 等价于 awk '/root/ {print $0}' /etc/passwd
awk /^root/ /etc/passwd
awk root /etc/passwd # 模式必须使用 // 括起来
# 使用 netstat 获取数据源
# 使用默认分隔符 FS 分割字段
# $0 表示整行,$1 表示第 1 列,$2 表示第 2 列
netstat -t | head -10 | awk '{print $0, $1, $2}'
# 添加模式匹配条件,只打印 state 为 ESTABLISHED 行
netstat -t | head -10 | awk '/ESTABLISHED/ {print $0}'
# 添加正则表达式匹配
netstat -a | head -100 | awk '$1 ~ /udp*/ {print $0}'
awk -F: '$1 ~ /^root/ {print $3, $4, $NF}' /etc/passwd
# 添加判断条件,第 1,2 行不打印
netstat -t | head -10 | awk 'NR > 2 {print $1, $2}'
# 可以使用 &&,|| 联合多个条件
netstat -t | head -10 | awk '/ESTABLISHED/ || NR == 1 {print NR")", $0}'
netstat -t | head -10 | awk '/ESTABLISHED/ && NR == 8 {print NR")", $0}'
# 可以使用 if 语句
netstat -t | head -10 | awk '{if( NR == 8 ) print NR")", $0}'
netstat -t | head -10 | awk '{if( $0 == "ok" ) print NR")", $0; else print "not found"}'
# 可以使用 BEGIN, END 块
netstat -t | head -10 | awk 'BEGIN { count=0 } { if ($1 == "tcp4") count++ } END { print count }'
netstat -t | head -10 | awk 'BEGIN { count=0 } { if ($1 ~ /tcp[46]/) count++ } END { print count }'
# 打印 99 乘法表
seq 9 | sed 'H;g' | awk -v RS='' '{for(i=1;i<=NF;i++)printf("%dx%d=%d%s", i, NR, i*NR, i==NR?"\n":"\t")}'
awk 处理中有很多内置变量。
变量 | 说明 |
---|---|
$n | 当前记录的第n个字段,字段间由FS分隔 |
$0 | 完整的输入记录 |
ARGC | 命令行参数的数目 |
ARGIND | 命令行中当前文件的位置(从0开始算) |
ARGV | 包含命令行参数的数组 |
CONVFMT | 数字转换格式(默认值为%.6g)ENVIRON环境变量关联数组 |
ERRNO | 最后一个系统错误的描述 |
FIELDWIDTHS | 字段宽度列表(用空格键分隔) |
FILENAME | 当前文件名 |
FNR | 各文件分别计数的行号 |
FS | 字段分隔符(默认是任何空格) |
IGNORECASE | 如果为真,则进行忽略大小写的匹配 |
NF | 一条记录的字段的数目 |
NR | 已经读出的记录数,就是行号,从1开始 |
OFMT | 数字的输出格式(默认值是%.6g) |
OFS | 输出记录分隔符(输出换行符),输出时用指定的符号代替换行符 |
ORS | 输出记录分隔符(默认值是一个换行符) |
RLENGTH | 由match函数所匹配的字符串的长度 |
RS | 记录分隔符(默认是一个换行符) |
RSTART | 由match函数所匹配的字符串的第一个位置 |
SUBSEP | 数组下标分隔符(默认值是/034) |
可以使用 BEGIN
和 END
来进行流程控制。
Proto Recv-Q Send-Q Local-Address Foreign-Address State
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN
tcp 0 0 coolshell.cn:80 124.205.5.146:18245 TIME_WAIT
tcp 0 0 coolshell.cn:80 61.140.101.185:37538 FIN_WAIT2
tcp 0 0 coolshell.cn:80 110.194.134.189:1032 ESTABLISHED
tcp 0 0 coolshell.cn:80 123.169.124.111:49809 ESTABLISHED
tcp 0 0 coolshell.cn:80 116.234.127.77:11502 FIN_WAIT2
tcp 0 0 coolshell.cn:80 123.169.124.111:49829 ESTABLISHED
tcp 0 0 coolshell.cn:80 183.60.215.36:36970 TIME_WAIT
tcp 0 4166 coolshell.cn:80 61.148.242.38:30901 ESTABLISHED
tcp 0 1 coolshell.cn:80 124.152.181.209:26825 FIN_WAIT1
tcp 0 0 coolshell.cn:80 110.194.134.189:4796 ESTABLISHED
tcp 0 0 coolshell.cn:80 183.60.212.163:51082 TIME_WAIT
tcp 0 1 coolshell.cn:80 208.115.113.92:50601 LAST_ACK
tcp 0 0 coolshell.cn:80 123.169.124.111:49840 ESTABLISHED
tcp 0 0 coolshell.cn:80 117.136.20.85:50025 FIN_WAIT2
tcp 0 0 :::22 :::* LISTEN
Redhat 系(例如 CentOS)安装软件。 性能指标从提供单一值升级到支持系统、网络、浏览器多维度下的指标分析,提高指标的置信度和可解释性,提高对业务的指导意义。
yum install package_name
yum erase package_name
MacOS 安装软件(需要额外安装 brew,mac 不自带)。
# 安装 brew
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
brew install package_name # 安装系统命令
brew cask install firefox # 安装 app
使用 vim 编辑某个文件。
a - 增加
i - 输入
ESC - 退出编辑模式,到命令行模式
:w - 保存
:x - 保存
:u - 撤销操作
1G - 返回第1行
G - 返回最后1行
^ - 返回行首
$ - 返回行尾
w - 下一个单词
b - 上一个单词
o - 下边增加一行
O - 上边增加一行
/pattern - 搜索某个pattern,按 n 导航
x - 删除当前字符
dd - 删除当前行(按住d进入了删除模式)
dG - 删除当前行以及后边所有内容
dw - 删除当前字符后边第一个单词
d$ - 删除当前字符后边所有字符
d/patt - 删除当前字符到模式匹配的内容
d0 - 删除当前字符到行首的字符
:3,9d - 删除3到9行
:3,$d - 删除第3行到末尾
:^,$d - 删除第3行到末尾
yy - 复制到当前行(按住y进入了复制模式,为啥 mac 不生效)
y$ - 复制到当前光标后的行
yG - 复制到当前行以及后边所有内容
yW - 复制到下个单词
p - 粘贴后边(复制后,需要用 p 来粘贴,不能用 ctrl + v)
P - 粘贴前边
:%s/pattern1/pattern2/g
:1,$s/pattern1/pattern2/g
使用 nano 编辑某个文件。
使用默认编辑器编辑某个文件。
打开某个目录,或者编辑某个文件。
执行某个文件,并重新读取最新的配置内容,这样无需重启终端,等价于 .
。
source ~/.bashrc
. ~/.bashrc
重启 shell 也会生效。
可以使用 let
进行基本整数计算。
no1=4; no2=5
# 注意 = 和 + 后旁边不能有空格
let r=no1+no2
let no1++
let no1--
let no1+=6
let no1-=6
计算表达式。
# 使用 expr 表达式
r=`expr $no1 + 4`
r=$(expr $no1 + 4)
设置环境变量,并导出,让子 shell 可用。
可以使用 export 单独设置环境变量,例如添加一个程序搜索路径(注意使用分号 colon 连接)。
PATH=$PATH:$HOME/xyz/bin
export PATH
export NPM_TOKEN=XXXX-XXXX-XXXX
这样当前 shell 的所有子进程都能读取该环境变量了。
显示所有进程使用 ps aux
(注意没有前缀 -),其中 a
显示所有用户进程,u
显示进展关联的用户,x
显示所有进程(不管有没有受控终端),由于信息较多,一般联合 grep
使用。
ps
只能显示某个时间快照的情况,使用 top
可以实时显示进程情况。
使用 jobs
可以查看所有后台进程,后台进程可以通过 command &
来实现。
fg %1
将 jobs 中 ID 为 1 的后台进程提取到前台。对应的,bg %1
将 jobs 中 ID 为 1 的从前台隐藏到后台。
如果想结束某个进程,使用 kill
命令,格式为 kill -signal PID...
,可以使用 kill -l
查看所有信号。
kill -l
kill -15 1212 # 默认信号(TERM)
kill -9 1212 # 强制结束(KILL),不等待资源处理,最后一根救命稻草
重启和关机
sudo shutdown -h now # 关机 halt
sudo shutdown -r now # 重启 reboot
使用 id
显示当前用户以及所在的组。
修改用户权限使用 chmod
,权限点分别为 read(4,简写为 r)、write(2,简写为 w)、execute(1,简写为 x)。
chmod +x script.sh # 添加执行权限
chmod -x script.sh # 去掉执行权限
chmod -R +x script.sh # 批量修改
chmod 775 script.sh # 也可以用数字
chmod u+x script.sh # 默认为用户权限,可以选择组(缩写为 g),其他人(缩写为 o)
chmod u+x,go=rx script.sh
另外可以使用 umask
来设置默认权限,如果该位标识为 1,说明要删除该权限。
umask # 显示默认权限 0022,说明要默认移除组、其他人写入的权限
使用 su
来使用一个新的账号登录,su -l user
,其中 user 可以省略,默认为超管账户,另外,-l
也可以简写为 -
,因此切换到超管登录直接输入 sudo su -
就可以了,此时提示符号变为 #
。
该命令会开启一个新的 shell。
sudo su -l root
sudo su -
使用 sudo
和 su
类似,不过更加受到控制,可以授权给某个用户以超管执行某些特定的命令(使用 sudo -l
查看哪些命令授权了),此时输入的是用户自己的密码,而不是超管的密码。
最后,sudo
不会开启一个新的 shell,也不会加载新用户的环境变量,而 su
会。
使用 passwd [user]
来修改密码
passwd
使用 chown
来更改文件或目录的用户(mac 下修改某些文件经常提示需要输入密码,此时可以使用 chown 将当前用户授权给要修改的文件),使用 chgrp
来更改文件或目录的组。
chown -R . user # 递归修改当前目录 owner 为 user
chown -R . user:group # 递归修改当前目录 owner 为 user,组为 group
sudo chown /etc/hosts yourname # 修改 /ect/hosts 当前用户,这样不用每次提示输入密码了
使用 chgrp
来更改文件或目录的组。
清除屏幕,等价于快捷键 control + L
。
printenv 打印所有环境变量(使用 env 命令一样的)。
$ printenv | less
$ printenv SHELL
$ env
打印所有环境变量。
set 命令不带参数时,不仅会打印所有环境变量,还会输出 shell 变量以及预定义的函数。
set | less
set -x # 打开调试开关,详细的日志输出
set -e # 如果任何语句的执行结果不是 true 则应该退出
set -o noglob # 关闭模式扩展,等价于 set -f
set +o noglob # 打开模式扩展,等价于 set +f
set -o pipefail # 表示在管道连接的命令序列中,只要有任何一个命令返回非0值,则整个管道返回非0值
使用 tee
(球座,发球区) 来暗度陈仓(搭车),除了向标准输出外,还可以输出到其他地方,也就是一个流可以流向多个地方。
The tee program reads standard input and copies it to both standard output (allowing the data to continue down the pipeline) and to one or more files.
ls /usr/bin | tee ls.txt | grep zip
# 覆盖模式
cat a* | tee out.txt | cat -n
# -a 追加模式
cat a* | tee -a out.txt | cat -n
# 使用 - 代替 stdin,也可以使用 /dev/stdin(其余设备包括 /dev/stderr, /dev/stdout, /dev/null)
echo who is this | tee -
使用 grep
可以搜索任意输入文件,返回匹配一个或者多个模式的所有行。
grep
使用简单模式和简单正则表达式(basic regular expressions,BREs),什么是 BREs 呢?
匹配字符:
.
任意字符[abc]
匹配一个字符[a-zA-Z0-9]
匹配一个字符[^123]
匹配非其中的一个字符[[:alpha:]]
字符类,还有其余的例如[[:digit:]]
,[[:punct:]]
,[[:space:]]
等
匹配量词:
\{m,n\}
匹配次数,至少 m 次,至多 n 次\?
匹配 0 次或者 1 次*
任何内容
位置锚定:
^
锚定行首$
锚定行尾,技巧:"^$" 用于匹配空白行。\b
锚定单词的边界\B
与\b
相反
分组引用:
\(string\)
将 string 作为一个整体方便后面引用\1
引用第 1 个左括号及其对应的右括号所匹配的内容\2
引用第 2 个左括号及其对应的右括号所匹配的内容\n
引用第 n 个左括号及其对应的右括号所匹配的内容
grep
它有几个兄弟:
egrep
可使用扩展正则表达式(如\?
变成?
,\{m,n\}
变成{m,n}
,增加了+
量词,增加了a|b
模式)fgrep
比grep
和egrep
都要快,因为它只能处理固定模式zgrep
等,输入文件可以为 gzip 压缩的文件
grep 'patricia' myfile
grep '^\.Pp' myfile
grep -v -e 'foo' -e 'bar' myfile
egrep '19|20|25' calendar
fgrep -c foo abc.txt
显示总共有多少行被匹配到了,而不是显示被匹配到的内容,注意如果同时使用 -cv
选项是显示有多少行没有被匹配到。
大小写不敏感,默认大小写敏感。
ls /bin /usr/bin | sort | uniq | grep -i zip # -i 忽略大小写
指定匹配模式,可以指定多个,他们之间是或关系(其中某个满足就返回那一行)。
grep -e bar -e foo abc.txt
显示行号。
grep -n -e bar -e foo abc.txt
被匹配的文本只能是单词,而不能是单词中的某一部分。
忽略模式匹配到的本条命令所在行。
ls /bin /usr/bin | sort | uniq | grep -v zip # -v 忽略本条命令行
grep -v -e bar -e foo abc.txt
如果有多个文件匹配,只显示匹配的文件名。
grep -l 'Move_history' *.c
将匹配到的内容以颜色高亮显示。
grep -n --color 'root' /etc/passwd
After,显示匹配到的字符串所在的行及其后 n 行。
Before,显示匹配到的字符串所在的行及其前 n 行。
Context,显示匹配到的字符串所在的行及其前后各 n 行。
使用 wc
可以统计行数(-l
,lines),单词数(-w
,words),字节数(-c
,chars)。
ls /bin /usr/bin | sort | uniq | wc -l # 统计代码行
注意,wc -l users
和 wc -l < users
有细微的差别,第一个命令知道数据来源来自 users 文件,第二个由于使用了重定向,wc
消费的数据来源不知道了。
排序。
sort # 标准输入,ctrl+d结束输入,然后排序
ls /bin /usr/bin | sort | uniq | wc -l # 统计代码行
# -u 去掉重复行
sort -u names,# 等价于 sort | uniq
# -r 反转排序
sort -r names
# -o 指定输出流(默认为标准输出)
sort names -o sorted_names # 等价于 sort names > sorted_names
sort names > names # 这个不能工作
sort names -o names # 这个可以
# -n 数字排序
du -h --max-depth=1 /home/yiifaa|sort -n -k1
去重,当重复的行不相邻时,uniq 命令是不起作用的,因此需要先排序,经常需要跟 sort
命令一起使用。
sort names | uniq -d # 列出重复字段
echo -e "abc\nabc\ndef" | uniq
ls /bin /usr/bin | sort | uniq | wc -l # 统计代码行
移除每行选中的部分。
cur -- cut out selected portions of each line of a file。
who | cut –c1-8 # 提取前8个字符
who | cut -c5- # 提取第5个字符到末尾
who | cut –c1-8,18- # 可以提取多个
who | cut –c1-8 | uniq | sort # 去重,排序
-d 指定分隔字段,默认使用 tab 分隔,sed -n l file 可以显示空白符号
-f 指定要提取的字段
cut -d: -f1 /etc/passwd # 提取:分隔的第一个字段
cut -d: -f1,2,4 /etc/passwd
cut -d: -f1,4- /etc/passwd
cut -d: -f1,3-5,6- /etc/passwd
merge corresponding or subsequent lines of files
cut 的反向操作。
paste names numbers
-d 指定分隔符
paste -d'+' names addresses numbers
-s 同一个文件的内容行拼接
paste -s names
ls | paste -d' ' -s -
relational database operator
行对行比较两个排序好的文件。
Compare Two Sorted Files Line by Line
比较两个文件。
Compare Files Line by Line
diff file1.txt file2.txt
diff -c file1.txt file2.txt
diff -u file1.txt file2.txt
给某个文件打 diff 补丁。
Apply a diff to an Original.
diff -Naur old_file new_file > diff_file
patch < diff_file
删除特定字符。
Transliterate or Delete Characters
语法:
tr from-chars to-chars
echo "lowercase letters" | tr a-z A-Z
echo "lowercase letters" | tr [:lower:] A
-s 多个连续字符替换成一个,依次对应,对应不上原样粘贴
echo "aaabbbccc" | tr -s ab
echo "abcabcabc" | tr -s ab
-d 删除字符
tr -d ' ' < intro
sed 's/ //g' intro
sed 是流式编辑(stream editor)的缩写,常用于文本替换和文本搜索,这个命令也是可以单独出书的命令,相比比较复杂。
sed 命令的作用依据第一个字母决定,这里主要将 sed 替换文本的功能。
例如 s
开头的搜索并替换文本(substitution)。
格式为:
s/regexp/replacement/g?
其中 regexp 支持正则,例如 \s\+$
,为当前行尾部空格;又例如出现 ^
为行开头。
其中 replacement 支持特殊字符,其中 &
为匹配文本,\1
到 \9
为圆括号子匹配。
其中 g
参数替换行中所有匹配文本。
其中 /
为分隔符,默认使用 /
,分隔符可以自定义,使用任意字符,例如:
echo "front" | sed 's_front_back_'
替换时,我们可以在 s
指令前指定替换影响的范围(address)(当前行,特定行,还是所有行),如果不指定,默认所有行。
echo "front" | sed '1s/front/back/'
echo "front\raaa\rbaawe\front\def" | sed '2,$s/front/back/g'
地址标注方式如下:
标注 | 描述 |
---|---|
n | 行号 |
$ | 最后一行 |
/regexp/ | 匹配正则的行号 |
addr1,addr2 | 行号范围,从 addr1 到 addr2 |
first~step | 指定初始行号,以及递增值 |
addr,+n | 指定初始行号,以及其后 n 行 |
addr! | 匹配除了 addr 的所有行 |
- 替换文件所有行匹配:
%s/old/new
,等同于%s/old/new/g
,注意%
符号 - 替换当前行第一个匹配:
s/old/new
- 替换当前行所有匹配:
s/old/new/g
- 第 m 行和 n 行前添加 4 个空格:
:m,n s/^/ /g
- 删除所有行尾空格:
%s/\s\+$//
- 去掉所有注释:
%s!\s*//.*!!
- 将所有不包含字符(空格也不包含)的空行删除:
g/^/s*$/d
- 将 MM/DD/YYYY 替换为 YYYY-MM-DD
sed 's/\([0-9]\{2\}\)\/\([0-9]\{2\}\)\/\([0-9]\{4\}\ )$/\3-\1-\2/' distros.txt
另外,sed 可以使用行内替换,添加参数 -i
,不过需要注意的是行内替换 mac 和 unix 语法不同,mac 下 sed -i
需要指定一个备份文件。
# unix 语法
sed -i "s/<buildid>/${buildId}/g" weirwood.json
# mac 语法,主要需要指定一个备份文件
sed -i ${backup_suffix} "s/SEMVER/${new_version}/g" $file
sed -n '1,5p' distros.txt # 打印 1 到 5 行
sed -n '/SUSE/p' distros.txt # 正则,过滤匹配 SUSE 的行
sed -n '/SUSE/!p' distros.txt # 正则否定,过滤不匹配 SUSE 的行
其中 -n
参数设置不打印所有行。
默认将删除后的内容显示出来,源文件不会变。
sed '5d'
sed '1,2d' intro
sed '/UNIX/d' intro
语法校验工具,检查错别字。
aspell check textfile
显示行号(cat -n),或者 (less -N)。
nl distros.txt | head
Wrap Each Line to a Specified Length
echo "The quick brown fox jumped over the lazy dog." | fold -w 12
fmt -w 50 fmt-info.txt | head
Format Text for Printing
pr -l 15 -w 65 distros.txt
ls /usr/bin | pr -3 -w 65 | head
pgrep 为 "Process-ID Global Regular Expressions Print" 的缩写。
用于根据名称查找当前正在运行的进程,并将与选择条件匹配的进程ID列出到stdout(屏幕)。
$ pgrep chrome
$ pgrep nginx
$ pgrep mysql
19226
19508
Format and Print Data,借鉴了 C 语言的函数。
# -5s - 左对齐
# -4.2f 保留2位小数
printf "I formatted the string: %s\n" foo
printf "%d, %f, %o, %s, %x, %X\n" 380 380 380 380 380 380
printf "%-5s %-10s %-4s\n" No Name Mark
printf "%-5s %-10s %-4.2f\n" 1 Sarath 80.3456
printf "%-5s %-10s %-4.2f\n" 2 James 90.9989
A document formatting system
The lpr program can be used to send files to the printer.
ls /usr/bin | pr -3 | lpr
The a2ps program (available in most distribution repositories) is interest- ing. As we can surmise from its name, it’s a format conversion program, but it's also much more
ls /usr/bin | pr -3 -t | a2ps -o ~/Desktop/ls.ps -L 66
Display Print System Status
lpstat -a
lpstat -s
Display Printer Queue Status
lpq
ls *.txt | pr -3 | lp
lpq
Cancel Print Jobs
cancel 603
lpq
从某个输入读取内容输出到标准输出中(屏幕)。
如果某个电影文件分成一百份,可以使用 cat
命令拼接回原文件,如果直接输入 cat
,那么会变成一个复读机,此时从键盘读取标准输入,然后显示到标准输出。按 ctrl+d 可以结束输入(EOF,end of file),按 ctrl+c 可以中断程序。
# movie.mpeg.001 movie.mpeg.002 ... movie.mpeg.099
# 通配符会按顺序扩展,因此不用担心顺序问题哦
cat movie.mpeg.0* > movie.mpeg
如果输入 cat > lazy_dog.txt
,那么会将标准输入重定向到文件 lazy_dog.txt。
cat file1 file2 # 显示
cat # 标准输入:键盘,输出:屏幕
cat > lazy_dog.txt # 标准输入:键盘,输出:文件
cat lazy_dog.txt # 标准输入:文件,输出:屏幕
cat < lazy_dog.txt # 标准输入:文件,输出:屏幕,等价于 cat lazy_dog.txt
cat movie.mpeg.0* > movie.mpeg # 通配符会按顺序扩展,因此不用担心顺序问题哦
可以使用 alias
创建别名,输入 alias aliasname
可以查看具体别名内容。取消别名使用 unalias aliasname
。
alias # 查看所有别名
alias ll='ls -Al' # 设置别名,需要使用引号引起来
alias tao='npm install --registry=https://registry.npm.taobao.org' # 创建
alias foo='cd /usr; ls; cd -' # 可以使用别名执行多条命令
alias tao # 查看别名内容
unalias foo # 取消别名
取消别名,见 alias
。
查看某个命令文档,例如 man bash
和 man ls
。
help command
man command
info command
whatis fdisk # 显示一行精简命令
apropos fdisk
command --help # 部分自定义命令
更高级的带超链接的教程,例如 info bash
和 info ls
,可以选择菜单进入或者输入 n
查看下一页。
获取某个命令帮助,例如 help cd
,某些命令可以通过 --help
获取使用帮助。
模糊搜索带有某个字符的所有命令,每个给出一行精简提示,例如 whatis ls
。
模糊搜索带有某个字符的命令,使用 apropos
(关于、至于的意思) 命令,例如 apropos ls
。
使用 which
来确定是否安装某个命令以及其位置,这个无法对全局函数和别名定位。
# -a 显示所有安装的命令
which node # /usr/local/bin/node
which npm # /usr/local/bin/npm
which cd # /usr/bin/cd
which cloc # /usr/local/bin/cloc
which -a bash # 如果安装了多个 bash,全部显示出来
p=$(which node)
p=`which node`
创建符号链接或者硬链接,默认创建硬链接(hard link,硬链接 inode 是一样的,无法给文件夹创建硬链接,无法跨文件系统创建硬链接),添加 -s
参数创建符号链接(symbolic link,soft link,如果源文件删除,符号链接失效,而硬链接不会)。
ln item hard-link-a
ln item hard-link-b
ln item hard-link-c
ls -alhi hard-link-a
ls -alhi item # 注意使用 i 查看 inode,同时查看硬链接文件数目
ln -s item soft-link-a
ln -s item soft-link-b
ln -s item soft-link-c
ls -alhi soft-link-a
ls -alhi item
rm item # 删除源文件后,快捷方式会失效
删除文件及目录 rm
(危险操作,谨慎操作)。
# -r --recursive,remove files&directories recursively
# -f --force,Ignore nonexistent files and do not prompt.
rm file1 file2
rm -rf dir1 # 递归,强制删除所有文件
删除目录,等价于 rm -r dir1
。
拷贝文件和目录,如果目标是文件且目标文件存在的话,cp
会覆盖原有文件内容,可以加上 -i
来提示是否覆盖。
# -n --no-clobber,do not overwrite an existing file (overrides a previous -i option)
# -a --archive
# -p same as --preserve=mode,ownership,timestamps
# -f --force,remove destination and try again
# -r --recursive,copy directories recursively
# -u --update copy only when the SOURCE file is newer than the destination file or when the destination file is missing
# -v, --verbose explain what is being done
cp a.txt b.txt # 复制一个文件,如果 b.txt 已经存在,会覆盖其原有内容,不存在,则拷贝一个副本
cp a.txt b.txt ../f # 拷贝 a.txt 和 b.txt 到 ../f 文件夹
cp -a a.sh dir1 # attribute,保留文件结构和属性,不保留目录结构
cp -p a.sh dir1 # preserve,保留 mtime, atime, flags, uid, gid 等属性
cp -n *.html dir1 # no overwirte,只拷贝没有或者更新过的文件(linux 使用 -u 参数)
cp -f *.html dir1 # force,强制拷贝,不需要提示
cp -r dir1 dir2 # recursive,递归拷贝 dir1 目录到 dir2
cp -v *.html dir1 # verbose,拷贝后显示详细信息
cp -arpnv dir1/* dir2
移动或者重命名文件,如果目标是文件且目标文件存在的话,mv
会覆盖原有文件内容,可以加上 -i
来提示是否覆盖。
# -f, --force, do not prompt before overwriting
# -n, --no-clobber, do not overwrite an existing file
# -t, --target-directory, move all SOURCE arguments into DIRECTORY
mv file1 file2 # 重命名,file1 不复存在
mv dir1 dir2 # 将 dir1 移动到 dir2,无需事先创建 dir2
mv -f 强制覆盖
mv -v 显示详情
mv -n 强制不覆盖目标文件,优先级最高,高于 -f
# -p, --parents, no error if existing, make parent directories as needed
# -v, --verbose
mkdir dir1 dir2 dir3 # 同时创建多个目录
mkdir -p dir1/dir2/dir3 # 创建多级目录
mkdir dir{1..10} # 同时创建10个目录(连续)
mkdir dir{a,b,c} # 创建3个目录(离散)
rm -rf dir{1..10} # 移除10个目录
使用 less
可以无干扰(全屏)查看文件内容,其中快捷方式如下,使用 -N
可以显示行号。
# 空格 下一页
# G 跳转末尾
# 1G 跳转第1行
# NG 跳转第N行
# /pattern 搜索内容,按 n 跳转下一个匹配
# q 退出
less -N abc.js
显示文件内容,一屏显示不下,需要按回车逐行显示。
使用 head
或者 tail
可以查看头部或者尾部多少行,另外可以使用 tail -f error.log
可以实时跟踪输出。
head -n 5 error.log
tail -n 5 error.log
tail -f error.log
参见 tail
。
确定文件/目录类型,可以查看文件编码(file encoding),图像尺寸什么的。
file dir1 # dir1: directory
file flex.md # flex.md: UTF-8 Unicode text
file index.html # index.html: HTML document text, ASCII text
file picture.jpg # picture.jpg: JPEG image data, 1910 x 960, JFIF standard 1.01
touch new_file
file new_file # data: ASCII text, with very long lines
file -i data # data: text/plain; charset=us-ascii
字符编码转码。
iconv -f UTF-8 -t UTF-8 test.txt
iconv -f ascii -t utf8 file2.txt > another.txt
列出文件和目录。
ls -a . # 显示所有文件,包括隐藏文件和 . 以及 ..(all)
ls -A . # 显示所有文件,除了 . 以及 ..(almost all)
ls -l . # 显示长格式(long)
ls -h . # 显示阅读友好,例如大小使用 M、K 等单位(human)
ls -Sl . # 按照文件大小排序(sort by size)
ls -i . # 显示文件的 inode 标识(inode)
ls -alhS . # 短格式可以联合使用(mac下都没有长格式选项)
alias ll='ls -Alh' # 还可以创建别名, list long
unalias ll # 取消别名
ls -l
文件长格式内容如下:
# 第1位为文件类型,例如 - 普通文件,d 为目录,c 为字符设备,l 为符号链接(软连接)文件,硬链接还是 - 开头,b 为块设备
# (rw-r--r--)为文件读写执行权限,分成三组 owner、group 和 other 组显示
# (1)为硬链接(hard link)文件数目
# (root root)为当前用户和用户所在组
# (3576296)为文件大小,默认单位字节(Byte),可以加上 `-h` 变为用户可阅读的
# (2017-04-03 11:05)为文件最后修改时间(mtime)
# (Experience ubuntu.ogg)为文件名称
-rw-r--r-- 1 root root 3576296 2017-04-03 11:05 Experience ubuntu.ogg
跳转目录。
cd ~ # 跳转当前用户主目录(home)
cd ~user_name # 跳转到某个用户的主目录(home)
cd - # 跳转到上一个目录(previous,同时打印出当前跳转路径)
cd / # 跳转到系统根目录(root)
cd . # 跳转当前目录
cd .. # 跳转上层目录
将目录压入堆栈 pushd
(push directory) 和推出堆栈 popd
(pop directory),这两个都是 csh
功能。
function publishPackage() {
pushd packages/$1
npm publish
popd
}
publishPackage angular;
显示日历。
cal # 今天
cal -d 2019-02 # 指定某个月份(不同版本可能不支持)
cal -y 2020 # 指定某年
date 用来显示或者设置系统时间。
使用 +
进行日期时间自定义格式化。
date +%s # 显示从1970年来的秒数,1598320492,毫秒数需要×1000
date --date "2020-08-23" +%s # 指定某个日期
date +%x # 2020/08/19
date +%A # 星期二
date +%B # 八月
date "+%Y/%m/%d %H:%M:%S" # 2020/08/19 19:58:19
start=$(date +%s)
end=`date +%s`
difference=$((end - start)) # 获取间隔的秒数
delay for a specified amount of time. 单位为秒。
Pause for NUMBER(支持浮点数哦) seconds. SUFFIX may be 's' for seconds (the default), 'm' for minutes, 'h' for hours or 'd' for days.
每隔 30s 重试,直到成功。
# 每次循环,shell 会派生一个进程,true is implemented as a binary in /bin
repeat() { while true; do $@ && return; done }
# 这个更快,shell 不会派生一个进程
repeat() { while :; do $@ && return; sleep 30; done }
repeat wget -c http://www.example.com/software-0.1.tar.gz
#!/bin/bash
echo -n Count:
tput sc
count=0
while true; do
if [ $count -lt 40 ]; then
let count++;
sleep 1;
tput rc;
tput ed;
echo -n $count;
else exit 0;
fi
done
tput 可以更改终端功能,如移动或更改光标,更改文本属性,清除终端屏幕的特定区域等。
tput sc # 记录当前光标位置
tput rc # 恢复光标到最后保存位置
tput ed # 清空光标所在位置到屏幕结尾的所有内容
tput el # 清除到行尾
tput civis # 隐藏光标
tput cnorm # 显示光标
tput setb # 背景色颜色代号
tput setf # 前景色颜色代号
现在为"终端时钟"添加,变换颜色和闪烁功能。
#!/bin/bash
for ((i=0;i<8;i++))
do
tput sc; tput civis # 记录光标位置,及隐藏光标
tput blink; tput setf $i # 文本闪烁,更改文本颜色
echo -ne $(date +'%Y-%m-%d %H:%M:%S') # 显示时间
sleep 1
tput rc # 恢复光标到记录位置
done
tput el; tput cnorm # 退出时清理终端,恢复光标显示
查看磁盘剩余空间。
-h --human-readable,人性化显示
df -h
查看磁盘使用统计。
--max-depth=N,统计的目录深度,当 N=0 时等同于 -s
-s --summarize,汇总显示
-h --human-readable,人性化显示
-a --all,显示所有大小,包括文件
-m 显示兆
-k 显示k字节
-b 显示字节数
# 查看一级目录各自汇总大小
du -h --max-depth=1
# 查看 /home 目录总大小
du -sh /home/*
#
du -h --max-depth=1 /home/yiifaa | sort -n -k1
查看磁盘剩余内存。
-h, --human,人性化显示
free -h
# 空格会合并成一个空格
echo hello world
# 使用单引号或者双引号会保留空格,单引号不会扩展,双引号会
echo "hello world"
# 遇到 globing 通配符会先扩展(~、*、?),实际打印当前所有路径,空格分割
echo *
echo ~
# 使用 -e 参数接收转义字符
echo -e "string containing escape sequences"
echo -e "1\t2\t3"
echo "1\t2\t3"
# reset = 0, black = 30, red = 31, green = 32, yellow = 33, blue = 34, magenta = 35, cyan = 36, and white = 37.
echo -e "\e[1;31m This is red text \e[0m"
# For a colored background, reset = 0, black = 40, red = 41, green = 42, yellow = 43, blue = 44, magenta = 45, cyan = 46, and white=47
echo -e "\e[1;42m Green Background \e[0m"
-n
参数取消末尾换行符号(\n
)。
echo -n a;echo b
-e
参数会解释引号(双引号和单引号)里面的特殊字符(比如换行符 \n
)。
echo -e "Hello\nWorld"
查看命令的来源。
- 内置命令(builtin)
- 别名(alias)
- 全局函数(function)
- 外部程序(file)
查看一个命令的所有定义。
type -a echo
echo is a shell builtin
echo is /bin/echo
返回命令的类型:别名(alias),关键词(keyword),函数(function),内置命令(builtin)和文件(file)。
type -t echo
type -t if
type -t node
type -t killportpid
type -t ll
当前目录,等价于 ~+
。
currd=$(pwd)
currd=`pwd`
echo ~+
查看历史命令记录。
history | less
!no
!!
当前登录用户名,一般和 $USER
相同,另外还有 $HOSTNAME
表示当前机器在网络中主机名。
whoami
echo $USER
echo $HOSTNAME
if test1; then
do sth;
elif test2; then
do sth;
else
do sth;
fi
如果 if
块中有多条命令,那么最后一个命令的执行状态(0~255之间的值)被返回给 $?
。
其中测试条件有三种语法,其中缩写形式 [ expression ]
更加常用,最新的 [[ expression ]]
支持字符串正则匹配。
常见的有文件测试、字符串比较、整数比较、数字比较,还可以进行逻辑组合条件。
test expressione
[ expression ]
[[ expression ]] # 支持 string =~ regex 匹配,另外支持路径模糊匹配
格式为:
# 经典版本
for word [in words]; do
commands;
done
# c 语言版本
for ((inital; condition; after)); do
commands;
done
# 等价于while 版本
(( inital ))
while (condition); do
commands;
after
done
例子:
for i in {A..D}; do echo $i; done
for i in *.js; do echo "$i"; done # 失败,会打印 *.js
for i in *.js; do
if [[ -e "$i" ]] # 判断是否有该文件
echo "$i"
fi
done
for i in $(echo *); do echo $i; done
for i in *; do echo $i; done
for var in "$@"; do echo $var; done
arr=(a 123 def) # 定义一个数组
for var in "${arr[@]}"; do echo $var; done; # 输出三个参数
for var in "${arr[*]}"; do echo $var; done; # 输出一个参数
语法为:
while commands; do commands; done
until commands; do commands; done # 与 while 判断条件相反而已
可以使用 break
跳出循环,continue
开始下一轮循环。
num=
while [[ $num != 'bye' ]]; do
read -p '请输入指令:' num
echo $num
done
while true; do
...
done
count=1
until [[ "$count" -gt 5 ]]; do
echo "$count"
count=$((count + 1))
done
echo "Finished."
类似 switch..case
,不过这里没有 switch
关键字。
case value in
pattern1) command;;
pattern2) command;;
*) defaultCommand;;
esac
getopts [option[:]] [DESCPRITION] VARIABLE
- option:表示为某个脚本可以使用的选项
- ":" 冒号如果某个选项(option)后面出现了冒号(":"),则表示这个选项后面可以接参数(即一段描述信息DESCPRITION)
- VARIABLE:表示将某个选项保存在变量VARIABLE中
getopts 是linux系统中的一个内置变量,一般用在循环中。每当执行循环时,getopts都会检查下一个命令选项,如果这些选项出现 在option中,则表示是合法选项,否则不是合法选项。并将这些合法选项保存在VARIABLE这个变量中。
getopts 还包含两个内置变量,及 OPTARG
和 OPTIND
- OPTARG 就是将选项后面的参数(或者描述信息DESCPRITION)保存在此变量当中。
- OPTIND 这个表示命令行的下一个选项或参数的索引(文件名不算选项或参数)。
while getopts ":a:bc:" opt
第一个冒号表示忽略错误;字符后面的冒号表示该选项必须有自己的参数。
$OPTARG
存储相应选项的参数,如下例中的 11、5;$OPTIND
总是存储原始$*中下一个要处理的选项(不是参数,而是选项,此处指的是a,b,c这三个选项,而不是那些数字,当然数字也是会占有位置的)位置。- optind初值为1,遇到"x",选项不带参数,optind+=1;遇到"x:",带参数的选项,optarg=argv[optind+1],optind+=2;
举例:
[root@hdc_1 software]# vim getopts.sh
#!/bin/bash
echo $*
while getopts ":a:bc:" opt
do
case $opt in
a)
echo $OPTARG $OPTIND;;
b)
echo "b $OPTIND";;
c)
echo "c $OPTIND";;
?)
echo "error"
exit 1;;
esac
done
执行:sh getopts.sh -a 11 -b -c 5
结果:
-a 11 -b -c 5
11 3
b 4
c 6
解释:
第一行输出echo $* 第二行,optind初值为1,选项-a的参数为11,下一个要处理的选项-b位置为3(即OPTIND=3),所以输出:11 3; 第三行,然后-b要处理的下一个选项-c位置为4,所以输出:b 4; 第四行,再者-c有参数,所以下一个要处理的位置+2(即为6,照着所有参数也数的出来下一个参数即为6,因为如果有下一个参数那么一定是在参数值5之后的),所以输出:c 6; 注:选项参数的格式必须是 -d val,而不能是中间没有空格的-dval 【如-d 10 不能是-d10】 getopts是对脚本参数的校验