Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
linux commannd 大全

Commands

nohup

如果你正在运行一个进程,而且你觉得在退出帐户时该进程还不会结束,那么可以使用 nohup 命令。该命令可以在你退出帐户/关闭终端之后继续运行相应的进程。

nohup command > myout.file 2>&1 &

useradd

增加用户。

# 增加用户
useradd -d /home/work work

# 创建密码
passwd work

nc

瑞士军刀,接收文件利器。

接收机器:nc -l 9995 > testfile2
发送机器:nc 10.10.10.10 9995 < part-00000,其中 ip 为接收机器IP

strings

在对象文件或二进制文件中查找可打印的字符串。

strings /bin/ls | grep -i libc

bc

执行一些高级的数学计算,支持浮点数。

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

basename

获取文件名称,不包含路径。

PROGNAME="$(basename "$0")"

dirname

获取目录名称。

export SCRIPT_DIR="$(cd $(dirname $0); pwd)"
readonly JOBDIR=$(pwd)
readonly PROJDIR=$(cd $(dirname $0)/../; pwd);

RANDOM

通过 $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

打印数字序列。

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 是一个非常好用的工具,尤其善于处理和环境变量相关的事务。

envsubst < original_file > destination_file

source source.txt && envsubst < tpl.txt > env_sub_txt_2

read

read -p var 读取用户输入赋值给变量 var,-p 参数提示文字。

read -p 'input a name: ' n

crontab

通过 crontab 命令,我们可以在固定的间隔时间执行指定的系统指令或 shell script 脚本。时间间隔的单位可以是分钟、小时、日、月、周及以上的任意组合,这个命令非常适合周期性的日志分析或数据备份等工作。

crontab [-u user] file crontab [-u user] [ -e | -l | -r ]

uname

查看操作系统内核版本。

uname -a
cat /etc/issue

uptime

系统已经运行了多久了。

show how long system has been runnin

shopt

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.

chsh/chpass/chfn

add or change user database information

bash

开启子 shell。

ex(vim)

vim - Vi IMproved, a programmer's text editor。

提供非可视化模式。

ed

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/

exit

退出当前 shell。

gcc

GNU C Compiler.

make

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 压缩文件。gunzip 解压缩文件。

gzip foo.txt
gunzip foo.txt.gz

bzip2/bunzip2

类似 gzip,但是使用了不同的压缩算法,牺牲压缩速度,获取更高的压缩质量。

bzip2 foo.txt
bunzip2 foo.txt.bz2

tar

打包/解包。

tar -czvf abc.tar.gz *
tar -xzvf abc.tar.gz *

find playground -name 'file-A' -exec tar rf playground.tar '{}' '+'

zip/unzip

压缩成和解压缩 .zip 文件包, Windows 用户也可以用。

Linux 下优先使用 gzip,其次 bzip2,最后才 zip。

zip -r playground.zip playground
unzip ../playground.zip

rsync

检测两个文件夹的不同,并自动同步。

rsync options source destination

alias backup='sudo rsync -av --delete /etc /home /usr/local /media/BigDisk/backup'

touch

创建文件或者修改文件修改时间(mtime)。

> newfile
touch newfile.md abc.js
touch {1..10}.js

fdisk

创建分区使用 fdisk 命令,它是一个很低级的分区命令。

sudo umount /dev/sdb1
sudo fdisk /dev/sdb

mkfs

格式化某个分区使用 mkfs 命令。

sudo mkfs -t ext4 /dev/sdb1
sudo mkfs -t vfat /dev/sdb1

fsck

修复磁盘分区使用 fsck 命令。

sudo fsck /dev/sdb1

mount/unmount

输入 mount 可以查看挂载的设备,以及挂载到的文件系统树。

mount
mount -t iso9660 /dev/sdc /mnt/cdrom
unmount /dev/sdc

dd

使用 dd 可以快速移动拷贝数据。

dd if=input_file of=output_file [bs=block_size [count=blocks]]

md5sum

使用 md5sum 计算校验码。

md5sum image.iso

ping

检测连接某个主机的网络是否通畅。

$ ping 10.232.232.com
$ ping qq.com

traceroute

显示到某个主机的所有路由跳转。

$ 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  * * *

ifconfig

查看本机 ip 可以使用 ifconfig(最新版可以使用 ip)。

主要查看 eth0 中的 inet 地址,另外 lo 地址为本机回文地址(127.0.0.1)。

apt-get

Debian 系(例如 Ubuntu)安装软件。

apt-get update
apt-get install package_name

apt-get remove package_name

netstat

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

上传文件。

一个自动化 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"

lftp

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

wget

下载网络资源。

  • -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"

curl

构造 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.

ssh

Secure Shell(安全外壳协议) 的缩写,远程安全登录。

ssh root@10.1.1.1
ssh root@10.1.1.1 commands

scp

scp 为 secure copy 缩写,远程安全拷贝。

$ scp remote-sys:document.txt .
$ scp bob@remote-sys:document.txt .

sftp

sftp 为 secure ftp 缩写。

lsof

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

rz,sz 是 Linux/Unix 同 Windows 进行 ZModem 文件传输的命令行工具。优点就是不用再开一个 sftp 工具登录上去上传下载文件。

sz 将选定的文件发送(send)到本地机器。

rz 运行该命令会弹出一个文件选择窗口(receive),从本地选择文件上传到 Linux 服务器

locate

从数据库快速检索文件名称。

find

递归遍历文件层次结构,查找符合条件的文件和目录,默认采用先序遍历,可以通过 -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 个半小时有访问的文件。

-name

根据文件名称来过滤文件,支持如下 globbing 字符:[]?*

find . -type f -name "[s-t]*.md" -print

-regex

根据正则表达式来过滤文件,这里的正则表达式比 -name 支持的 globbing 要更加强大。

find . -regex "\./*[0-9]+\.png"

-type

根据文件类型来过滤文件,文件类型如下:

  • b: 块设备文件
  • c: 字符设备文件
  • d: 目录
  • f: 普通文件
  • l: 符号链接文件
  • p: FIFO
  • s: socket
find . -type f -name "[s-t]*.md" -exec cat {} \;
find ~ -type f | wc -l
find ~ -type f -name "*.JPG" -size +1M | wc -l

-size

根据文件大小来过滤文件,大小单元如下:

  • 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

-empty

查找空文件。

find . -empty

-delete

类似 -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

-path

根据路径查找文件。

find . -path "*wysiwyg*"

-atime

在过去 n 时间内被读取过的文件。

find . -name "*.log.*" -atime +7d | xargs rm

-ctime

在过去 n 时间内文件数据元(例如权限等)修改过的文件。

-mtime

在过去 n 时间内被修改过的文件。

find . -type f -mtime +7d -name "*.log" -exec mv {} /tmp/old_logs \;

-amin

最近 n 分钟有被访问过的文件。

-cmin

最近 n 分钟文件数据元(例如权限等)修改过的文件。

-mmin

最近 n 分钟有被修改过的文件。

-print

打印出找到的路径(默认行为)。

find . -type f -name "[s-t]*.md" -print

-depth

遍历目录深度,类似的还有 maxdepthmindepth 选项。

find . -type f -depth 1 -name "[s-t]*.md" -exec cat {} \;

-newer

查看比 file 更新的文件。

find playground -type f -newer playground/timestamp

-exec

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 '{}' ';'

-ok

类似 exec,不过执行 command 前需要询问,需要输入 y 后才继续执行。

find . -type f -name file.txt -ok cat {} \;

xargs

find 经常和 xargs 联合使用,不过 xargs 一次执行的数量会有限制,这个需要注意。

find ~ -type f -name 'foo*' -print | xargs ls -l

operators

( 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

测试条件,需要重点介绍。

test expression

# 等价于
[ expression ]

xargs

接收 pipe 数据流当做下一个命令的参数,需要重点介绍。

find ~ -type f -name 'foo*' -print | xargs ls -l

exec

find ~ -type f -name 'foo*' -exec ls -l '{}' ';'

awk

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)

流程控制

可以使用 BEGINEND 来进行流程控制。

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

yum

Redhat 系(例如 CentOS)安装软件。 性能指标从提供单一值升级到支持系统、网络、浏览器多维度下的指标分析,提高指标的置信度和可解释性,提高对业务的指导意义。

yum install package_name
yum erase package_name

brew

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(别名:ex)

使用 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

使用 nano 编辑某个文件。

code

使用默认编辑器编辑某个文件。

open

打开某个目录,或者编辑某个文件。

source

执行某个文件,并重新读取最新的配置内容,这样无需重启终端,等价于 .

source ~/.bashrc
. ~/.bashrc

重启 shell 也会生效。

let

可以使用 let 进行基本整数计算。

no1=4; no2=5

# 注意 = 和 + 后旁边不能有空格
let r=no1+no2
let no1++
let no1--
let no1+=6
let no1-=6

expr

计算表达式。

# 使用 expr 表达式
r=`expr $no1 + 4`
r=$(expr $no1 + 4)

export

设置环境变量,并导出,让子 shell 可用。

可以使用 export 单独设置环境变量,例如添加一个程序搜索路径(注意使用分号 colon 连接)。

PATH=$PATH:$HOME/xyz/bin
export PATH

export NPM_TOKEN=XXXX-XXXX-XXXX

这样当前 shell 的所有子进程都能读取该环境变量了。

ps

显示所有进程使用 ps aux(注意没有前缀 -),其中 a 显示所有用户进程,u 显示进展关联的用户,x 显示所有进程(不管有没有受控终端),由于信息较多,一般联合 grep 使用。

top

ps 只能显示某个时间快照的情况,使用 top 可以实时显示进程情况。

jobs

使用 jobs 可以查看所有后台进程,后台进程可以通过 command & 来实现。

fg/bg

fg %1 将 jobs 中 ID 为 1 的后台进程提取到前台。对应的,bg %1 将 jobs 中 ID 为 1 的从前台隐藏到后台。

kill

如果想结束某个进程,使用 kill 命令,格式为 kill -signal PID...,可以使用 kill -l 查看所有信号。

kill -l
kill -15 1212 # 默认信号(TERM)
kill -9 1212  # 强制结束(KILL),不等待资源处理,最后一根救命稻草

shutdown

重启和关机

sudo shutdown -h now   # 关机 halt
sudo shutdown -r now   # 重启 reboot

id

使用 id 显示当前用户以及所在的组。

chmod

修改用户权限使用 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

另外可以使用 umask 来设置默认权限,如果该位标识为 1,说明要删除该权限。

umask  # 显示默认权限 0022,说明要默认移除组、其他人写入的权限

su

使用 su 来使用一个新的账号登录,su -l user,其中 user 可以省略,默认为超管账户,另外,-l 也可以简写为 -,因此切换到超管登录直接输入 sudo su - 就可以了,此时提示符号变为 #

该命令会开启一个新的 shell。

sudo su -l root
sudo su -

sudo

使用 sudosu 类似,不过更加受到控制,可以授权给某个用户以超管执行某些特定的命令(使用 sudo -l 查看哪些命令授权了),此时输入的是用户自己的密码,而不是超管的密码。

最后,sudo 不会开启一个新的 shell,也不会加载新用户的环境变量,而 su 会。

passwd

使用 passwd [user] 来修改密码

passwd

chown

使用 chown 来更改文件或目录的用户(mac 下修改某些文件经常提示需要输入密码,此时可以使用 chown 将当前用户授权给要修改的文件),使用 chgrp 来更改文件或目录的组。

chown -R . user       # 递归修改当前目录 owner 为 user
chown -R . user:group # 递归修改当前目录 owner 为 user,组为 group
sudo chown /etc/hosts yourname  # 修改 /ect/hosts 当前用户,这样不用每次提示输入密码了

chgrp

使用 chgrp 来更改文件或目录的组。

clear

清除屏幕,等价于快捷键 control + L

printenv

printenv 打印所有环境变量(使用 env 命令一样的)。

$ printenv | less
$ printenv SHELL
$ env

env

打印所有环境变量。

set

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

使用 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 可以搜索任意输入文件,返回匹配一个或者多个模式的所有行。

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 模式)
  • fgrepgrepegrep 都要快,因为它只能处理固定模式
  • 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

-c

显示总共有多少行被匹配到了,而不是显示被匹配到的内容,注意如果同时使用 -cv 选项是显示有多少行没有被匹配到。

-i

大小写不敏感,默认大小写敏感。

ls /bin /usr/bin | sort | uniq | grep -i zip  # -i 忽略大小写

-e

指定匹配模式,可以指定多个,他们之间是或关系(其中某个满足就返回那一行)。

grep -e bar -e foo abc.txt

-n

显示行号。

grep -n -e bar -e foo abc.txt

-w

被匹配的文本只能是单词,而不能是单词中的某一部分。

-v

忽略模式匹配到的本条命令所在行。

ls /bin /usr/bin | sort | uniq | grep -v zip  # -v 忽略本条命令行
grep -v -e bar -e foo abc.txt

-l

如果有多个文件匹配,只显示匹配的文件名。

grep -l 'Move_history' *.c

--color

将匹配到的内容以颜色高亮显示。

grep -n --color 'root' /etc/passwd

-A n

After,显示匹配到的字符串所在的行及其后 n 行。

-B n

Before,显示匹配到的字符串所在的行及其前 n 行。

-C n

Context,显示匹配到的字符串所在的行及其前后各 n 行。

wc

使用 wc 可以统计行数(-l,lines),单词数(-w,words),字节数(-c,chars)。

ls /bin /usr/bin | sort | uniq | wc -l  # 统计代码行

注意,wc -l userswc -l < users 有细微的差别,第一个命令知道数据来源来自 users 文件,第二个由于使用了重定向,wc 消费的数据来源不知道了。

sort

排序。

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

去重,当重复的行不相邻时,uniq 命令是不起作用的,因此需要先排序,经常需要跟 sort 命令一起使用。

sort names | uniq -d   # 列出重复字段
echo -e "abc\nabc\ndef" | uniq
ls /bin /usr/bin | sort | uniq | wc -l  # 统计代码行

cut

移除每行选中的部分。

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

paste

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 -

join

relational database operator

comm

行对行比较两个排序好的文件。

Compare Two Sorted Files Line by Line

diff

比较两个文件。

Compare Files Line by Line

diff file1.txt file2.txt
diff -c file1.txt file2.txt
diff -u file1.txt file2.txt

patch

给某个文件打 diff 补丁。

Apply a diff to an Original.

diff -Naur old_file new_file > diff_file
patch < diff_file

tr

删除特定字符。

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

sed 是流式编辑(stream editor)的缩写,常用于文本替换和文本搜索,这个命令也是可以单独出书的命令,相比比较复杂。

sed 命令的作用依据第一个字母决定,这里主要将 sed 替换文本的功能。

s - 替换文本

例如 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

p - 打印文本

sed -n '1,5p' distros.txt      # 打印 1 到 5 行
sed -n '/SUSE/p' distros.txt   # 正则,过滤匹配 SUSE 的行
sed -n '/SUSE/!p' distros.txt  # 正则否定,过滤不匹配 SUSE 的行

其中 -n 参数设置不打印所有行。

d - 删除行

默认将删除后的内容显示出来,源文件不会变。

sed '5d'
sed '1,2d' intro
sed '/UNIX/d' intro

aspell

语法校验工具,检查错别字。

aspell check textfile

nl

显示行号(cat -n),或者 (less -N)。

nl distros.txt | head

fold

Wrap Each Line to a Specified Length

echo "The quick brown fox jumped over the lazy dog." | fold -w 12

fmt

fmt -w 50 fmt-info.txt | head

pr

Format Text for Printing

pr -l 15 -w 65 distros.txt
ls /usr/bin | pr -3 -w 65 | head

pgrep

pgrep 为 "Process-ID Global Regular Expressions Print" 的缩写。

用于根据名称查找当前正在运行的进程,并将与选择条件匹配的进程ID列出到stdout(屏幕)。

$ pgrep chrome
$ pgrep nginx
$ pgrep mysql

19226
19508

printf

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

groff

A document formatting system

lpr

The lpr program can be used to send files to the printer.

ls /usr/bin | pr -3 | lpr

a2ps

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

lpstat

Display Print System Status

lpstat -a
lpstat -s

lpq

Display Printer Queue Status

lpq

ls *.txt | pr -3 | lp
lpq

cancel

Cancel Print Jobs

cancel 603
lpq

cat

从某个输入读取内容输出到标准输出中(屏幕)。

如果某个电影文件分成一百份,可以使用 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 创建别名,输入 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 # 取消别名

unalias

取消别名,见 alias

man

查看某个命令文档,例如 man bashman ls

help command
man command
info command
whatis fdisk   # 显示一行精简命令
apropos fdisk
command --help # 部分自定义命令

info

更高级的带超链接的教程,例如 info bashinfo ls,可以选择菜单进入或者输入 n 查看下一页。

help

获取某个命令帮助,例如 help cd,某些命令可以通过 --help 获取使用帮助。

whatis

模糊搜索带有某个字符的所有命令,每个给出一行精简提示,例如 whatis ls

apropos

模糊搜索带有某个字符的命令,使用 apropos(关于、至于的意思) 命令,例如 apropos ls

which

使用 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`

ln

创建符号链接或者硬链接,默认创建硬链接(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

删除文件及目录 rm(危险操作,谨慎操作)。

# -r --recursive,remove files&directories recursively
# -f --force,Ignore nonexistent files and do not prompt.

rm file1 file2
rm -rf dir1  # 递归,强制删除所有文件

rmdir

删除目录,等价于 rm -r dir1

cp

拷贝文件和目录,如果目标是文件且目标文件存在的话,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

移动或者重命名文件,如果目标是文件且目标文件存在的话,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

mkdir

# -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

使用 less 可以无干扰(全屏)查看文件内容,其中快捷方式如下,使用 -N 可以显示行号。

# 空格 下一页
# G 跳转末尾
# 1G 跳转第1行
# NG 跳转第N行
# /pattern 搜索内容,按 n 跳转下一个匹配
# q 退出
less -N abc.js

more

显示文件内容,一屏显示不下,需要按回车逐行显示。

tail

使用 head 或者 tail 可以查看头部或者尾部多少行,另外可以使用 tail -f error.log 可以实时跟踪输出。

head -n 5 error.log
tail -n 5 error.log
tail -f error.log

head

参见 tail

file

确定文件/目录类型,可以查看文件编码(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

字符编码转码。

iconv -f UTF-8 -t UTF-8 test.txt
iconv -f ascii -t utf8 file2.txt > another.txt

ls

列出文件和目录。

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

跳转目录。

cd ~  # 跳转当前用户主目录(home)
cd ~user_name # 跳转到某个用户的主目录(home)
cd -  # 跳转到上一个目录(previous,同时打印出当前跳转路径)
cd /  # 跳转到系统根目录(root)
cd .  # 跳转当前目录
cd .. # 跳转上层目录

pushd/popd

将目录压入堆栈 pushd(push directory) 和推出堆栈 popd(pop directory),这两个都是 csh 功能。

function publishPackage() {
  pushd packages/$1
  npm publish
  popd
}

publishPackage angular;

cal

显示日历。

cal # 今天
cal -d 2019-02 # 指定某个月份(不同版本可能不支持)
cal -y 2020 # 指定某年

date

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))  # 获取间隔的秒数

sleep

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 可以更改终端功能,如移动或更改光标,更改文本属性,清除终端屏幕的特定区域等。

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                             # 退出时清理终端,恢复光标显示

df

查看磁盘剩余空间。

-h --human-readable,人性化显示

df -h

du

查看磁盘使用统计。

--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

free

查看磁盘剩余内存。

-h, --human,人性化显示

free -h

echo

# 空格会合并成一个空格
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 参数取消末尾换行符号(\n)。

echo -n a;echo b

-e 参数

-e 参数会解释引号(双引号和单引号)里面的特殊字符(比如换行符 \n)。

echo -e "Hello\nWorld"

type

查看命令的来源。

  • 内置命令(builtin)
  • 别名(alias)
  • 全局函数(function)
  • 外部程序(file)

-a 参数

查看一个命令的所有定义。

type -a echo
echo is a shell builtin
echo is /bin/echo

-t 参数

返回命令的类型:别名(alias),关键词(keyword),函数(function),内置命令(builtin)和文件(file)。

type -t echo
type -t if
type -t node
type -t killportpid
type -t ll

pwd

当前目录,等价于 ~+

currd=$(pwd)
currd=`pwd`
echo ~+

history

查看历史命令记录。

history | less
!no
!!

whoami

当前登录用户名,一般和 $USER 相同,另外还有 $HOSTNAME 表示当前机器在网络中主机名。

whoami
echo $USER
echo $HOSTNAME

if

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

格式为:

# 经典版本
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

语法为:

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

until

count=1
until [[ "$count" -gt 5 ]]; do
  echo "$count"
  count=$((count + 1))
done
echo "Finished."

case

类似 switch..case,不过这里没有 switch 关键字。

case value in
    pattern1) command;;
    pattern2) command;;
    *) defaultCommand;;
esac

getopts

getopts [option[:]] [DESCPRITION] VARIABLE
  • option:表示为某个脚本可以使用的选项
  • ":" 冒号如果某个选项(option)后面出现了冒号(":"),则表示这个选项后面可以接参数(即一段描述信息DESCPRITION)
  • VARIABLE:表示将某个选项保存在变量VARIABLE中

getopts 是linux系统中的一个内置变量,一般用在循环中。每当执行循环时,getopts都会检查下一个命令选项,如果这些选项出现 在option中,则表示是合法选项,否则不是合法选项。并将这些合法选项保存在VARIABLE这个变量中。

getopts 还包含两个内置变量,及 OPTARGOPTIND

  • 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是对脚本参数的校验

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment