linux shell 脚本攻略

linux shell 脚本攻略

[TOC]

1.基本概念与特征

基础

  • 双引号: 引号内可以引用变量,与php相同,如: echo "${hello} world"
  • 使用转义字符:echo -e '1\t2', 输出会包含tab符号
  • pgrep 根据进程名字查找进程
  • 查看正在运行进程的环境变量: cat /proc/pid/environ | tr '\0' '\n', environ 文件以'\0' 作为分隔符
  • 字符串长度: ${#PATH}
  • 查看当前使用的bash: echo $0 或者 echo $SHELL
  • root用户UID为0:echo $UID
  • bash 提示符设置环境变量: PS1
  • 参数个数: $#
  • 参数列表: $*或者 $@
    • $@: 解析成 "2" "$3",解析成多个字符,这个比较常用
    • $*: 解析成 "2c$3", 最好不用,单个字符
  • 取参数列表的某个几个值: *:1:2}, 只获取前两个参数
  • 命令本身,脚本本身: $0

数学计算

  • 整数简单计算: let, (()) , [], expr
  • 复杂计算,浮点数计算 bc 命令

let

no1=1
no2=2
let result=no1+no2
let no1++
let no1--
let no1+=6
result=$((no1+50))
result=$[ $no1 + 5 ]
result=$[ no1 + no2 ]

浮点数计算

  • scale 只对除法会生效,其他运算如果要设置精度,除以1.0
echo "scale=2; 100*9.8111/1.0" | bc
  • 进制转换
echo "obase=10;ibase=2;1100101" | bc
echo "obase=8;16" | bc
echo "obase=2;18" | bc
echo "sqrt(100)" | bc
echo "10^2" | bc

重定向

常用重定向

ls * > ls.txt # 相当于 ls * 1> ls.txt
ls _ * 2> stderr.txt 1>stdout.txt # 相当于 ls _ * &> all.txt

tee

获取标准输入,重定向到文件和stdout,会过滤stderr

echo "haha" | tee -a stderr.txt stdout.txt - # 两个文件都是以追加的方式写入

文件重定向到命令

cmd < file

重定向脚本内部的文本

cat << EOL > log.txt
a
b
c
d
EOL

文件操作

  • 读取文件
exec 3
  • 写入文件
exec 4>output_file.txt
cat "test line" >&4 # 相当于 cat "test line " > output_file.txt
exec 5>>output_file.txt
cat "haha" >&5

数组

普通数组(切片)

var_array=(1 2 3 four five )
inx=3
echo ${var_array[1]}
echo ${var_array[${inx}]}
# 所有的元素
echo ${var_array[*]}
# 数组长度
echo ${#var_array[*]}
# 切片
echo ${var_array[*]:2}
echo ${var_array[*]:2:2}  # ${var_array[*]:start:size} 
world="1234 56"
echo ${world:2:3}  # 34
## 切片负数操作
echo ${world:(-2)} #56

#  打印单个字符
line="hello world"
for word in $line;
do
    for((i=0;i<${#word};i++))
        do
            echo ${word:i:2}
        done;
done


# 字符串替换
word=0123456789 
echo ${word/23/xx}

关联数组

条件: bash 4.0+

declare -A map
map=([lmq]=cdz [1]=one)
echo ${map[lmq]} ${map[1]}
echo ${!map[*]} # 打印索引  key
echo ${map[*]}  # 打印值  value

alias

  • alias vi='vim' # vi 执行的是vim
  • 逆别名: \vi # ==> 执行的是 vi 命令

日期操作

获取日期字符创

  • date ==> Sun Aug 6 10:10:07 CST 2017
  • 显示指定格式: date "+ the date: %Y-%m-%d the time:%H:%M:%S"

时间字符串转化成其他格式

  • 获取时间戳:date --date "Sun Aug 6 10:10:07 CST 2017" +%s
  • 周几: date --date "Sun Aug 6 10:10:07 CST 2017" +%A

调试

两种方式:

  • 显示命令:
    • 显示命令: set -x or bash -x
    • 禁止显示: set +x or bash +x
    • 读取时显示输入: set -v or bash -v
    • 读取时禁止显示输入: set +v or bash +v
  • 设置环境变量 "_DEBUG", 脚本中判断"_DEBUG"变量,打印输出信息

函数

特点:

  • 可以递归
  • 可以export func
  • 函数返回值:$?
    • $? 相当于 exit code, 只能返回整型,无法接受其他复杂的数据类型

获取前一个命令的输出

三种方式:

  • 管道: ls | cat -n > out.txt
  • 子shell: cmd_output=cmd_output
    • $() 是在子shell中进行操作,不会影响父shell的环境,
    • "$()" 在获取子shell中的文本时,一定要加上双引号,否则会子shell会自动删除 '\n', 双引号保留 '\n'
  • 反引用: output=ls | cat -n; echo $output

IFS

一般IFS与for结合使用,IFS(interval field separator)定义分隔符,for 迭代处理

#!/bin/bash
#Desc: Illustration of IFS
line="root:x:0:0:root:/root:/bin/bash" 
oldIFS=$IFS;
IFS=":"
count=0
for item in $line;
do
     [ $count -eq 0 ]  && user=$item;
     [ $count -eq 6 ]  && shell=$item;
    let count++
done;
IFS=$oldIFS
echo $user\'s shell is $shell;

循环

更多参考:https://billie66.github.io/TLCL/book/zh/chap34.html

for 循环

  • demo
IFS=" ";
for var in "hello" "lmq";
do
    echo $var;
done;
# hello lmq 迭代失败
for var in "hello lmq";
do
    echo $var;
done;
str="hello lmq"
# hello\nlmq
for var in $str;
do
    echo $var;
done;
array=(hello lmq)
for var in ${array[@]};
do
    echo $var;
done;
  • for序列
for i in {0..2};
do
    echo $i
done
for i in {a..z};
do
    echo $i
done
for i in {A..C};
do
    echo $i
done
  • for C语言格式
for ((i=0;i<10;i++))
{
    echo $i
}

while 循环

while condition
do
    cmds;
done

until 循环

x=0
until [ $x -eq 9 ];
do 
    let x++;
    echo $x;
done

逻辑判断

更多参考:http://blog.csdn.net/ithomer/article/details/6836382

if...elif...else

if condition;
then
    cmds;
elif condition;
then
    cmds;
else
    cmds;
fi

逻辑运算符||与&&

  • [ condition ] && cmd; # condition 为true 执行cmd
  • [ condition ] || cmd; # condition 为false 执行cmd

算术比较

  • [ $var -ne 0]
  • [ $var -ge 0 -a $var1 -ge 2] # 逻辑与
  • [ $var -ge 0 -o $var1 -ge 2] # 逻辑或

字符串比较

单中括号比较字符串偶尔会出错,推荐使用双中括号

  • [[ $str1 == $str2 ]]
  • [[ -n $str1 ]] 字符串是否非空
  • [[ -z $str1 ]] 字符串是否为空

2.常用命令

cat

  • 合并多个输入: echo "this is test" | cat - stdout.txt stderr.txt >> all.txt
  • 压缩空行:
    • cat -s file
    • cat file | tr -s '\n' 将多个\n压缩成单个\n
  • 制表符显示为 ^I: cat -T file.py
    • vim 配置 set expandtab 关闭tab功能
  • 行号:cat -n file

find

  • find ./ -name "*.txt"
  • find ./ -iname "case.sh"
  • 或条件搜索: find ./ -name "*.txt" -o -name "*.sh"
  • 匹配路径搜索: find ./ -name "*.bin" -path "*build*"
  • 正则表达式:
    • find ./ -iregex ".*\(\.session\|\.txt\)"
    • find ./ -iregex ".*t[xs]t"
  • 否定: find . ! -name "*.txt"
  • 只查找当前目录, 注意 参数-mindepth与参数-maxdepth 尽可能在所有的参数前面:
    • find . -maxdepth 1 -type f
    • find . -mindepth 2 -maxdepth 3 -name "*.py"
  • 查找不同类型的文件: find . -maxdepth 1 -type d
    • find . -type fd
    • find . -type fdlcbsp s:socket p:fifo b:block
  • 根据文件时间进行搜索:
    • 访问时间-atime(单位:天,指的是差值,上一次访问与当前时间的差值,差值越大,时间越早): 用户最近一次访问时间;文件的 Access time,atime 是在读取文件或者执行文件时更改的.
      • find . -type f -atime -1 小于1天内被访问过的文件
    • 修改时间-mtime(单位:天): 文件内容最后一次修改的时间; 文件的 Modified time,mtime 是在写入文件时随文件内容的更改而更改的
      • find . -type f -mtime 1 昨天修改的文件
    • 变化时间-ctime(单位:天):文件元数据(metadata, 权限,所有权)最后一次修改的时间; 在写入文件、更改所有者、权限或链接设置时随 Inode 的内容更改而更改的。
    • amin (单位:分)
      • find . -type -amin +7 7分钟之前访问的文件
    • mmin
    • cmin
    • anewer
    • cnewer
    • mnewer
    • newer file 最新的文件
  • 根据文件大小搜索:
    • find . -type f -size +2k 大于两K的文件
    • find . -maxdepth 1 -type d -exec ls -dl {} \; 目录不能根据大小排序,都是4k
  • 删除找到的文件:find . -type f -name "*.swp" -delete
  • 基于文件权限查找:
    • find . -type f -perm 644
    • find . -type f -name "*.php" ! -perm 644 找出没有可读权限的php文件
    • find . -user cdz 根据用户查找
  • 找到后执行命令:
    • find . -type f -perm 644 -exec ls -l {} \; > /Users/cdz/tmp/all.txt 注意\; 分号代表exec结束,后面可以添加其他操作
    • find . -type f -perm 644 -exec ls -l {} \;
    • find . -type f -perm 644 -ok ls -l {} \; 询问是否要执行。y执行,直接回车不执行
    • find . -name "sub" -prune -o -type f 排除sub目录
    • find . \( -name "sub" -o -name "sub1" \) -prune -o -type f 排除两个目录

ls

  • 显示访问时间:ll --time=atime
    • 根据访问时间排序: ll --time=atime -rt 最新访问的在最底部
  • 显示最近更新文件内容的时间: ll
    • 根据最新的文件修改时间排序: ll -rt

xargs

命令行接受参数的两种形式:

  • 以标准输入的形式接受数据,即管道
  • 以命令行参数的形式接受数据, 即xargs
  • ls *.txt | cat 输出的是匹配到的文件,如stdout.txt, stderr.txt
  • ls *.txt | xargs cat 输出的stdout.txt和stderr.txt的文件内容
  • 多行转单行: ls *.txt | xargs
  • 单行划分成多行: ls *.txt | xargs -n 2, 假设有:s1.txt stdout.txt, stderr.txt, 输出:
s1.txt stderr.txt
stdout.txt
  • 使用分隔符:
    • echo "1:2:3:4" | xargs -d ':' | xargs 分出的数据中包含一个换行符,不懂为什么,再使用xargs 去除
    • echo "stderr.txt:stdout.txt" | xargs -d : | xargs cat
  • 参数分组执行: ls *.txt | xargs -n 2 cat, 每次调用cat 输出两个文件的内容,第一次输出 s1.txt和stderr.txt文件内容,第二次输出 stdout.txt 文件内容
  • 参数二次加工,比如字符串格式化, 类似于find -exec : echo "stderr.txt:stdout.txt" | xargs -d : | xargs -n 1 | xargs -I placeholder echo "hello placeholder"
    • xargs -n 限制命令执行几次,顺便出去换行
  • find与xargs:
    • 错误: find . type f -name "*.txt" | xargs rm -f 如果文件中含空格文件,会错误删除,xargs的IFS分割符默认是空格和换行。
    • 正确:find . type f -name "*.txt" -print0 | xargs -0 rm -f
  • 统计代码文件行数:find . -type f -name "*.py" -print0 | xargs -0 wc -l

tr

原理: tr set1 set2 , 从标准输入获取数据,根据set1 set
2 映射规则转换成新数据

  • 小写转化成大写: echo "hello world" | tr "a-z" "A-Z" # HELLO WORLD
  • set2 元素比较少时,末尾补齐:echo "hello world" | tr "a-z" "A-O" # 结果HELLO OOOLD
  • set1 元素比较少时,一set1为准,set2多出的部分,不转换:echo "hello world" | tr "a-o" "A-Z" # HELLO wOrLD
  • 删除字符串: echo "hello world" | tr -d 'a-e'
  • 缩减字符串: echo "hello wwwwwwworld" | tr -s ' w' # hello world
  • 字符串替换: echo "hello world" | tr 'w' 'W'
  • 删除不在补集中的字符串: echo "hello 1 ww 2 world" | tr -d -c "1-3"
  • 删除重复的字符:tr -s '\n'

检验 md5sum和shasum

  • md5 & shaxsum
# md5sum
➜  ~ md5sum *.txt > all.md5
➜  ~ md5sum -c all.md5 
a.txt: OK
b.txt: OK
stderr.txt: OK
stdout.txt: OK
# sha1
➜  ~ sha1sum -c all.sha1 
a.txt: OK
b.txt: OK
stderr.txt: OK
stdout.txt: OK
  • md5deep & shaxdeep 需要额外安装
    • 使用find 结合使用: find . -type f -print0 | xargs -0 md5sum >> all.md5

临时文件

temp_file="/tmp/var.$$"
echo ${temp_file}

分割文件 split & csplit

#todo

获取文件名和扩展名

原理,使用 %%,%, ##,# 删除字符:

  • %%: 从右边开始删除到%%位置,贪婪模式
  • % 非贪婪模式
  • ##, #%相反,原理相同
file="test.backup.jpg"
echo file name: ${file%.*}
echo file name: ${file%%.*}
echo suffix name: ${file#*.}
echo suffix name: ${file##*.}

# 输出
file name: test.backup
file name: test
suffix name: backup.jpg
suffix name: jpg

自动化交互

#!/bin/bash
#Filename: interactive.sh
read -p "Enter number:" no ;
read -p "Enter name:" name
echo You have entered $no, $name;%

3.文件相关

生成任意文件大小

  • dd if=/dev/zero of=junk.data bs=1M count=3: 生成3M的junk.data文件

comm 文本文件的交集与差集

  • 对比两个文件:comm a.txt b.txt, 第一列: 只在a文件出现的行,第二列只在b文件出现的行,第三列在ab文件中出现的行
  • 只看a文件出现的行: comm a.txt b.txt -1
  • 只看b文件出现的行: comm a.txt b.txt -2

文件权限、所有权和黏置位

目录权限说明

  • r: 具有读取目录结构的权限,ls 可以读取文件夹中的列表
  • w: 可以在目录内执行写操作,比如创建文件,删除,修改文件名
  • x:能否进入目录,如果要有读取该目录内代码的文件,必须要有x权限,设置web服务器时,要注意。

权限修改

  • chown -R user.group filename
  • chmod u=rwx g=rw o=r finename
  • setuid 只能针对linux可执行的二进制文件,不能用于脚本

touch

  • 修改访问时间:touch -a junk.data
  • 修改更新时间:touch -c junk.data
  • 指定时间修改:touch -d time_str junk.data, 默认修改mtime

超链接

  • 格式: ln -s /usr/local/bin/python2.7 /usr/bin/python2.7
  • 必须全部是绝对路径

head 与tail

  • tail -n +6 从第六行开始打印
  • head -n -6 打印到倒数第六行
  • tail -s 3 -f file, 3秒查询一次

只列出目录

  • 最好使用: ls -Fl | grep "/$", 不包含.和..
  • ls -l | grep "^d"
  • ls -dl */, 不包含.和.., 末尾多加一个斜杠
  • find . -maxdepth 1 -type d -print, 包含.

wc 统计字符数

  • wc -l file
  • cat file | wc -w
  • echo "haha" | wc -c # 长度为5
  • wc file 统计行数,单词数,字数
  • wc file -L 打印最长行的长度

tree

  • tree beautyme-crawler
  • tree . -P "*.sh" 只列出叶子是.sh的文件,目录但是不包含.sh的文件也会显示
  • tree . -I "*.sh" -P 的逆过程,显示非*.sh 文件
  • tree beautyme-crawler -H beautyme-crawler -o out.html 浏览器打开out.html可以通过out.html查看所有的文件

4.文本处理

正则表达式

pattern 解释
. 大部分字符,不包含特殊字符,比如 \n, 真正的任意字符 [\S\s]
? 匹配之前[0, 1]
+ 匹配之前[1, ∞]
* 匹配之前[0, ∞]
9[^10] 匹配93,95,9a, 不匹配 91,92
` ` 匹配两边任意一个, Oct (1st 2nd)
() 创建一个用于匹配的子串,如ma(tri)? 匹配max或matrix
\b 单词边界, \bcool\b匹配cool,不匹配coolant
\B 非单词边界, cool\B 匹配coolant,不匹配cool
\w 单个单词字符,字母,数字与_, 不匹配空白符(回车,空格, &,等其他特殊字符)
\W 单个非单词字符

通配符与正则表达式区别

http://blog.csdn.net/huiguixian/article/details/6284834

  • ls *.md5
  • ls [ab].md5
  • ls [^b].md5
  • ls [a]*.md5
  • ls ?.md5

grep

  • 只显示匹配到的部分,-o:grep -o "http://101.68.80.186.*?>" server.log | grep -o ".*?[^>]"
  • 统计匹配到的字符串的行数,不是匹配出现的次数:grep -c "101.68.80.186" server.log 相当于 grep "101.68.80.186" server.log | wc -l
  • 统计出现的次数: grep -o "101.68.80.186" server.log | wc -l
  • 输出所在的行数: grep -on "101.68.80.186" server.log
  • 如果匹配多个文本,查找pattern在哪个文件中: grep -l "101.68.80.186" serve*.log 得到的结果是文件名,假设是server.log,则代表"101.68.80.186"在server.log中能找到
  • -L-l相反
  • 递归:
    • grep "function()" . -R -n,软连接也搜索
    • grep "function()" . -r -n, 排除软连接,如果命令行中提供了软连接,也会进行搜索
  • 忽略大小写:grep -i "error" server.log
  • 多个正则表达式:grep -in -e "error" -e "warn" server.log
  • pattern_file: grep -f pattern_file server.log
  • 包含文件:grep "wechat" . -r --include *.py
  • 排除文件:
    • --exclude: grep "wechat" . -r --include *.py --exclude "start_wechat_article.py"
    • --exclude-from file
  • 与xargs -0配合使用: grep -lZ "test" file | xargs -0 rm
  • 静默输出,返回值在:$?, 为0代表匹配到
  • 打印匹配到的前后几行
    • seq 10 | grep 5 -A 3 , 之后
    • seq 10 | grep 5 -B 3 , 之前
    • seq 10 | grep 5 -C 3 , 前后三行

cut 按列截取数据

  • cut -f 1 -d ':' a.md5 指定分隔符
  • cut -f 2,3 filename: 截取2,3列
  • cut --complement -f 1 filename取反,显示除了第一列之外的所有列
  • 根据长度切割:
    • cut -c1-5 a.md5, 截取前5个
    • cut -c-5 a.md5,截取前5个
    • cut -c5- a.md5,截取第5个到行尾
    • cut -c2 a.md5,截取第二个字符
    • cut -c1-5,10-19 a.md5 --output-delimiter='|',截取多个列,指定输出定界符

sed

  • sed 's/60/xx/g' a.md5 > newa.md5, 替换并保存到新文件
  • sed -i 's/60/xx/g' a.md5,更新到原文件
  • sed -i.bak 's/60/xx/g' a.md5,更新原文件,并生成a.md5.bak备份原文件
  • echo 'this this this this' | sed 's/this/new/4g' # this this this new 修改第几个出现的位置,下标从1开始
    • echo 'this this this this' | sed 's:this:new:4g' : 作为定界符
    • echo 'this this this this' | sed 's|this|new|4g' | 作为定界符
  • sed '/^$/d' a.md5,删除空行
  • echo this is a example | sed 's/\w\+/[&]/g',使用已经匹配的字符串标记 &, 注意正则的符号前面需要\
  • 正则表达式中的子分组同样适用: \1, \2

eg

  • mac下替换字符串(mac -i必须指定后缀) find . -name "settings.py" -exec sed -i.bak 's/proxy.abuyun.com/http-pro.abuyun.com/g' {} \;
    • 删除备份文件:find . -name "settings.py.bak" -exec rm -fr {} \;

awk

docs: https://coolshell.cn/articles/9070.html

原理: awk -F : 'BEGIN{print "begin block"} PATTERN { execute cmds per line } END{print "end block" }' a.md5

  • awk -F : 'BEGIN{print "begin block"} NR<3 {print "number of fields: "NF " commemt: " $2} END{print "end block" }' a.md5, -F 指定分隔符
  • awk -F : 'BEGIN{print "begin block", v1} NR<3 {print "number of fields: "NF " commemt: " $2, v1} END{print "end block "}' v1="hello" a.md5, 传递变量,注意在BEGIN语句块中v1无效, 不懂为什么。
  • seq 10 | awk '{getline;print}' getline 获取,具体参考docs
  • awk 'BEGIN{ "date" | getline date; print date; }'
  • echo | awk '{"grep root /etc/passwd"| getline cmdout; print cmdout}',通过getline 将外部的shell命令的输出读入变量 cmdout,
  • seq 10 | awk 'NR==1, NR==3' 打印1到3行
  • seq 10 | awk '/1/, /3/' 打印start_pattern与end_pattern之间的行
  • seq 10 | awk '/[1-3]/, /4/' pattern 支持正则,但是支持的样式有限,有哪些限制未知,最好避开这个问题,不能使用\d,用[[:digit:]]替代
  • awk 'NR<=3' filename 模拟head命令

tac

  • echo "hello\nworld" | tac # world\nhello 逆序形式打印行

5.网路

wget

  • wget url1 url2
  • wget -t 5 -O filename -o wget.log url -t 重试五次, -O 指定文件名, -o指定日志文件
  • wget -c url 下载中断续传

curl

  • curl url > index.html 默认是将结果输出到终端
  • curl -O url1 url2 路径中必须包含文件名
  • curl -o filename url 指定文件名
  • curl --progress https://www.taobao.com > taobao.html 显示下载进度
  • curl -c https://example.com 断点续传
  • curl -I https://www.taobao.com 只下查看部信息
  • curl --referer "http://www.baidu.com" --cookie "user=baidu;pass=bitch" --user-agent "chrome" -H "Host: www.baidu.com" -H "Accept-Language: en" https://www.taobao.com
  • curl -u user[:pass] https://www.taobao.com
  • curl -d "key1=val1&key2=val2" https://post.example.com

6.综合使用的例子

tar

  • tar -cvvf md5.tar a.md5 b.md5/ tar -cvf md5.tar a.md5 b.md5 归档文件,vv 与v,相当于 ls -lls 的区别
  • tar -rvf md5.tar a.md5.bak 追加文件
  • tar -tvvf map_poi-v1.0.0.tar.gz 查看归档文件
  • tar -df md5.tar a.md5 对比归档文件
  • tar -uvvf md5.tar a.md5 更新归档文件
  • tar -f md5.tar --delete a.md5.bak 删除归档文件
  • tar -xvvf md5.tar a.md5 -C path_extract_dir 提取指定文件,到指定目录
  • tar -cf all.tar.gz --exclude "*.tar.gz" * 归档排除指定模式的文件,注意双引号
  • tar -cf - a.md5 b.md5 | tar -tf - tar与stdin,stdout

gzip gunzip

gzip只能压缩单文件,与tar归档后,再组合使用。

  • gzip -9 test.img 最高压缩比例压缩文件,压缩后删除源文件。 -9 耗时
  • gunzip test.img.gz 解压
  • zcat test.txt.gz 直接打印gz压缩文件
  • tar -cavvf archive.tar.gz file1 file2 根据后缀名判断压缩格式
  • cat iter.sh| gzip -c > iter.sh.gz 压缩后不删除源文件, -c 输出到stdout

bzip2 bunzip2

压缩比率比gzip更高,用法同gzip

  • bzip2 -9 -k test.img 保留文件

lzma unlzma

压缩比率更高,用法同bzip2

  • tar --lzma -cvvf all.md5.lzma *.md5.* 创建
  • tar --lzma -tvvf all.md5.lzma 查看

zip,unzip

注意与gzip的区别

  • zip -r map_poi.zip map_poi 一定要 -r ,不然目录不会递归压缩
  • unzip -o map_poi.zip 解压缩不询问
  • zip map_poi.zip -u zip.txt 增加或者更新文件
  • zip -d map_poi.zip zip.txt 删除文件
  • unzip -l map_poi.zip 列出文件

base64

  • base64 a.md5 > a.md5.64 编码
  • cat a.md5 | base64 > a.md5.64 编码
  • base64 -d < a.md5.64 解码
  • cat a.md5.64 | base64 -d 解码

7. 网络进阶

ifconfig & iwconfig(无线配置)

  • ifconfig wlan0 192.168.0.80 netmask 255.255.252.0 设置ip地址
  • ifconfig eth0 hw ether 18:65:90:cc:39:49 设置mac地址,可以进行硬件地址欺骗
  • echo "nameserver 8.8.8.8" | sudo tee -a /etc/resolv.conf 设置dns
  • route add default gw 192.168.0.1 wlan0 设置网关
  • iwlist scan 搜索网络

host & nslookup

  • host baidu.com
  • nslookup baidu.com 推荐使用这个命令
  • 设置dns,直接修改 /etc/hosts 文件

ping

  • ping baidu.com -c 2
    • rtt min/avg/max/mdev = 1.709/1.752/1.795/0.043 ms rtt(Round Trip Time) 往返时间, mdev 代表平均偏差
    • -c 发送两个
    • 失败 $? 不为0

fping

  • fping -a -u -g 192.168.135.1/24 -g 生成ip地址列表, -a show system alive, -u unreachable

ssh

  • ssh -p 34185 cdz@hostname "cat >> ~/.ssh/authorized_keys" < ~/.ssh/id_rsa.pub 添加免登陆的公钥。本地stout 传输给远端的 stdin
  • ssh cdz@host 'cmd1;cmd2;' 命令根据使用情况决定使用单引号,还是双引号
  • echo "cmd1;cmd2" | ssh cdz@host 可以通过使用管道的形式传命令
  • echo "text" | cdz@host 'cat >> list' 本地数据重定向到远程stdin

du

  • du -sh dir 显示整个目录占用的空间大小
  • du -ah dir 递归显示整个子目录
  • du -ch *.txt 显示匹配的文件占用空间,最后一行输出当前文件夹的total大小
  • du -hs py 统计整个文件夹大小
  • du --exclude "junk.data" * -ch 排除文件
  • du -x /dev/sda1 对于挂载点,必须使用-x避免深入遍历
  • du -ak py | sort -nrk 1 | head 目录中最大的十个文件或目录
  • find py -type f -exec du -k {} \; | sort -nrk 1 | head 最大的十个文件

/usr/bin/time & time

shell 默认内建有个time命令,系统有个/usr/bin/time命令,第二个命令更强大,能获取的信息更多,支持通过制定的format输出

  • /usr/bin/time -f "cmd: %C wall time: %E cpu time(user + system): %P exit code: %x " ls 1> cmd_output.txt
  • time ls
  • /usr/bin/time ls

8.系统信息查看

who & w & users

  • w - Show who is logged on and what they are doing.
  • who - show who is logged on
  • users print the user names of users currently logged in to
    the current host
  • users | tr ' ' '\n' | uniq, 多个终端统一用户,也会出现多个

uptime

查看系统启动了多长时间

last & lastba

last查看系统登录日志信息, lastb 查看系统用户登录的失败信息,root用户才能有权限查看

  • last | head 查看最近的十条登录信息
  • last user | head 获取某个用户会话

watch

默认定时2两秒执行某个命令,观察输出

  • watch -n 5 -d 'ls -l' 五秒执行一次,-d强调差异

ps

  • ps -C Xvfb 查看特定进程名的进程信息
  • ps -C Xvfb -o pid= 获取pid, 用处不大,一般很难定位进程名
  • ps -eo pid,command | grep start_presslogic | grep -v grep 定制输出列
  • ps -ef | grep "start_presslogic|PID" | grep -v grep 显示父进程
  • ps -eo pid,command e | grep start_presslogic | grep -v grep

kill

常用的信号:

  • SIGHUP 1 对进程或终端进行挂起检测
  • SIGNINT 2 ctrl + c 信号
  • SIGKILL 9 强制杀死进程
  • SIGTERM 15 默认终止进程
  • SIGTSTP 20 CTRL + Z 信号

使用:

  • kill -9 12333
  • kill -s SIGKILL 12333

which & whereis & file & whatis

  • which ls 查找命令位置
  • whereis ls 命令位置和源码所在的位置
  • file 判断文件类型
  • whatis 查看简要功能信息

cpu 信息

cat /proc/cpuinfo

内存信息

cat /proc/meminfo

分区信息

cat /proc/partitions

/proc/pid 正在执行程序的一些信息

├── attr
│   ├── current
│   ├── exec
│   ├── fscreate
│   ├── keycreate
│   ├── prev
│   └── sockcreate
├── autogroup
├── auxv
├── cgroup
├── clear_refs
├── cmdline
├── comm
├── coredump_filter
├── cpuset
├── cwd -> [Error reading symbolic link information]
├── environ
├── exe -> [Error reading symbolic link information]
├── fd [error opening dir]
├── fdinfo [error opening dir]
├── io
├── limits
├── loginuid
├── maps
├── mem
├── mountinfo
├── mounts
├── mountstats
├── net
│   ├── arp
│   ├── bonding
│   │   └── bond0
│   ├── connector
│   ├── dev
│   ├── dev_mcast
│   ├── icmp
│   ├── igmp
│   ├── ip_mr_cache
│   ├── ip_mr_vif
│   ├── mcfilter
│   ├── netfilter
│   │   ├── nf_log
│   │   └── nf_queue
│   ├── netlink
│   ├── netstat
│   ├── packet
│   ├── protocols
│   ├── psched
│   ├── ptype
│   ├── raw
│   ├── route
│   ├── rt_acct
│   ├── rt_cache
│   ├── snmp
│   ├── sockstat
│   ├── softnet_stat
│   ├── stat
│   │   ├── arp_cache
│   │   └── rt_cache
│   ├── tcp
│   ├── udp
│   ├── udplite
│   ├── unix
│   ├── vlan
│   │   └── config
│   ├── wireless
│   └── xfrm_stat
├── ns [error opening dir]
├── numa_maps
├── oom_adj
├── oom_score
├── oom_score_adj
├── pagemap
├── personality
├── root -> [Error reading symbolic link information]
├── sched
├── schedstat
├── sessionid
├── smaps
├── stack
├── stat
├── statm
├── status
├── syscall
├── task
│   └── 1989
│       ├── attr
│       │   ├── current
│       │   ├── exec
│       │   ├── fscreate
│       │   ├── keycreate
│       │   ├── prev
│       │   └── sockcreate
│       ├── auxv
│       ├── cgroup
│       ├── clear_refs
│       ├── cmdline
│       ├── comm
│       ├── cpuset
│       ├── cwd -> [Error reading symbolic link information]
│       ├── environ
│       ├── exe -> [Error reading symbolic link information]
│       ├── fd [error opening dir]
│       ├── fdinfo [error opening dir]
│       ├── io
│       ├── limits
│       ├── loginuid
│       ├── maps
│       ├── mem
│       ├── mountinfo
│       ├── mounts
│       ├── ns [error opening dir]
│       ├── numa_maps
│       ├── oom_adj
│       ├── oom_score
│       ├── oom_score_adj
│       ├── pagemap
│       ├── personality
│       ├── root -> [Error reading symbolic link information]
│       ├── sched
│       ├── schedstat
│       ├── sessionid
│       ├── smaps
│       ├── stack
│       ├── stat
│       ├── statm
│       ├── status
│       ├── syscall
│       └── wchan
└── wchan

你可能感兴趣的:(linux shell 脚本攻略)