Bash备忘录

BASH SHELL cheat sheet 记录一些 bash shell 脚本的奇技淫巧,都是从实际使用中 google 的。bash 各 Linux 发行版都自带方便好用特别是文本处理、一些运维之类的小脚本,但有些语法繁琐不好记容易忘整理一下方便查找。 trap trap 命令 用于指定在接收到信号后将要采取的动作,常见的用途是在脚本程序被中断时完成清理工作。当 shell 接收到 sigspec 指定的信号时,arg 参数(命令)将会被读取,并被执行。例如: trap "exit 1" HUP INT PIPE QUIT TERM 表示当 shell 收到HUP,INT,PIPE,QUIT,TERM这几个信号时,当前执行的程序会读取参数"exit 1",并将它作为命令执行。 如果要忽略某个信号就参数使用单引号就可以'' trap '' signals 如果启动的时候忽略了信号比如使用了nohup,trap 命令是无效的。具体信号可使用man 7 signal或者kill -l查阅 $*、$@、$# 直接上例子看,如下脚本test.sh echo 参数总个数 \$#: $# echo 第0个参数 \$0: $0 for a in $(seq 1 $#); do eval b=\$$a echo 第"$a"个参数 \$"$a": $b done echo -e "\nUsing \"\$#\":" echo "$#" echo -e "\nUsing \$#:" echo $# echo -e "\nUsing \"\$*\":" for a in "$*"; do echo $a; done echo -e "\nUsing \$*:" for a in $*; do echo $a; done echo -e "\nUsing \"\$@\":" for a in "$@"; do echo $a; done echo -e "\nUsing \$@:" for a in $@; do echo $a; done 然后运行此脚本,注意最后3 4用了双引号...

January 20, 2021 · 2 min · 415 words · Fython

TCP连接和各状态浅析

TCP连接和各状态浅析 TCP协议中三次握手连接和四次挥手断开和其中的状态变化 TCP(Transmission Control Protocol)协议在OSI模型中属于传输层的协议(第4层)也是最常用的互联网协议,与UDP相比它是一种可靠的传输协议,建立和断开连接中一共有11种可能发生的状态(states)。 Linux系统中可以用ss -nat命令查看所有TCP连接情况如果是旧的系统没有此命令可以使用netstat代替只是输出格式不一致,统计当前所有TCP状态可以加管道实现 ss -nat | awk 'NR>1 { d[$1]++ } END { for (i in d) print i, d[i] }' 建立连接(三次握手) TCP是面向连接的所以传输双方在传输前要建立一条连接后才能通信,建立连接后TCP协议提供全双⼯(就是可以同时发送和接收不影响)的通信服务。建立连接的过程我们给它取了个生动的名字叫“三次握手”,因为从发起到建立连接一共有三个步骤也就是双方会发三个包,先看下面的图 首先客户端发送SYN(Synchronous)包到服务端告诉服务器开始建立连接,包里面会包含一个随机数(j)序列号(Sequence Number),此时客户端进入SYC-SENT状态。当然最初服务器是处于LISTEN状态监听某一个端口,本文图片以绿底黑框的都代表TCP状态。 服务端收到SYN发送应答SYN-ACK(Acknowledgement)携带确认号码(Acknowledge Number)为收到的序列号+1也就是j+1,加上一个自己的SYC序列号随机数(k),服务端把状态置为SYN-RECEIVED 客户端收到SYN-ACK包并发送确认号码k+1,此时客户端的状态为ESTABLISHED,服务器收到ACK后状态也变为ESTABLISHED 以下是wireshake抓包后TCP连接的三次握手,这里序列号码j和k都为0。 TCP A (port 65525) TCP B (port 443) LISTEN (Start) 1. SYN-SENT --> <SEQ=0><CTL=SYN> --> SYN-RECEIVE 2. ESTABLISHED <-- <SEQ=0><ACK=1><CTL=SYN,ACK> <-- SYN-RECEIVE 3. ESTABLISHED --> <SEQ=1><ACK=1><CTL=ACK> --< ESTABLISHED 断开连接(四次挥手) 断开连接称为“挥手”一共有四步每一方向占两步,由于TCP是全双工的所以关闭连接需要双方都完成关闭(close)才算结束,其中会涉及状态也就比握手多。客户端和服务端都可以发起挥手动作,先发送FIN包的动作叫主动关闭(active close)然后另一方回应ACK包叫执行被动关闭(passive colse),双方各完成一次主动和被动关闭一共四次。 客户端数据传输完毕发起断开连接(主动关闭),发送FIN包携带一个序列号(x)到服务端并更新自己的状态为FIN-WAIT-1 服务端收到FIN包返回ACK包(被动关闭),应答ACK确认序号为x+1,服务端此时的状态为CLOSE-WAIT。另一边客户端收到ACK更新状态为FIN-WAIT-2 服务端准备执行断开连接(主动关闭),此时服务端的状态还是CLOSE-WAIT,发送FIN包携带序列号(y)到客户端更新服务端状态为LAST-ACK,客户端收到FIN包后状态变为TIME-WAIT。 客户端收到FIN应答ACK(被动关闭)携带确认序号为y+1,服务端收到ACK立即关闭连接状态变为CLOSED 因为客户端最后不知道服务端有没有收到ACK包,所以默认等待两倍的MSL(Maximum Segment Lifetime),Linux上MSL一般为60s,等待120s使服务器如果没有收到ACK也能重传FIN包,最后把自己的状态置为CLOSED在此之前的MSL时间中一直是TIME-WAIT状态 看一个现实中的例子ssh连接退出...

February 13, 2020 · 1 min · 157 words · Fython

使用 Core dump 解密加密的sh脚本

使用 Core dump 解密加密的脚本 之前遇到网上的集成的shell脚本有点问题想手动修改下,发现脚本是加密的,网上找了好久发现有gzexe、shc加密方法都尝试了一遍,可惜解密都不成功,最后用了一个粗暴的办法就是任何程序总要加载到内存运行的吧,那就直接中断coredump查看内存里的内容,以下是具体方法。 root用户执行如下命令 ulimit -c unlimited echo "/core_dump/%e-%p-%t.core" > /proc/sys/kernel/core_pattern mkdir /core_dump 以上第一句是设置内核coredump大小,这里设置不限制。第二句是设置coredump存储位置和格式,%e代表可执行程序名,%p代表pid, %t代表生成时间。然后去执行脚本如xxx.sh ./xxx.sh 6 start & (sleep 0.01 && kill -SIGSEGV $!) 之后会输出类似[1]+ Segmentation fault (core dumped)...的提示,然后查看/core_dump文件夹下,就会有dump出来的文件了,直接vim打开查看会有一些乱码手动处理一下就可以了。 如果在core_dump文件夹下没有dump出来的文件,可使用如下命令测试然后查看是否有文件生成。 sleep 15 & killall -SIGSEGV sleep 正常情况下core_dump文件夹下会有以sleep开头的文件。

October 16, 2019 · 1 min · 40 words · Fython

Systemd 中的timer单元

Systemd 中的 timer 单元 上一篇讲了 systemd 中的 service 单元,这次记录一下 timer 单元。timer 必须依赖 service 单元来配置,可以用来做替代 crontab 的选择。 timer 单元以.timer结尾,中间包含[Timer]块如下面所示是 Ubuntu 下的apt-daily.timer,该目录下也存在一个apt-daily.service服务文件配合一起使用。 [Unit] Description=Daily apt activities [Timer] OnCalendar=*-*-* 6,18:00 RandomizedDelaySec=12h AccuracySec=1h Persistent=true [Install] WantedBy=timers.target 上面的[Timer]块代表每天上午 6 点和下午 6 点都运行 apt 脚本,具体[Timer]块可配置以下参数 单调定时器(Monotonic timer) Option Description OnActiveSec= 相对计时器开始后多少时间执行,格式如 2h、2s、2w、2d OnBootSec= 相对系统启动后多少时间执行 OnStartupSec= 相对 systemd 启动多少时间后执行 OnUnitActiveSec= 每隔多少时间再次运行一次 OnUnitInactiveSec= 服务在最后一次停止后,隔多久再执行一次 可以两个参数一起使用,如下每周开机 15 分钟后执行 foo [Unit] Description=Run foo weekly and on boot [Timer] OnBootSec=15min OnUnitActiveSec=1w [Install] WantedBy=timers....

August 16, 2018 · 1 min · 210 words · Fython

Systemd中Service单元介绍

Systemd中Service单元介绍 Systemd是一个系统管理守护进程、工具和库的集合,用于取代System V初始进程,集中管理和配置类UNIX系统,可见它非常的强大。 Systemd分为多个单元(unit)如服务(.service),挂载点(.mount),套接口(.socket)和设备(.device)等,这里记录使用最多的服务(service)文件的编写。用户自定义的一般存放在/etc/systemd/sytem/文件夹下,还有另外的文件夹类debian系列的如下。 Directory Description /lib/systemd/system/ 系统自带的或者程序自带安装的单元存放在此 /etc/systemd/system/ 用户自定义的,此文件夹优先级最高,可以覆盖上面文件夹的内容 下面是系统安装openssh-server后,在/lib/systemd/system/ssh.service下的服务。 [Unit] Description=OpenBSD Secure Shell server After=network.target auditd.service ConditionPathExists=!/etc/ssh/sshd_not_to_be_run [Service] EnvironmentFile=-/etc/default/ssh ExecStart=/usr/sbin/sshd -D $SSHD_OPTS ExecReload=/bin/kill -HUP $MAINPID KillMode=process Restart=on-failure RestartPreventExitStatus=255 Type=notify [Install] WantedBy=multi-user.target Alias=sshd.service 如上所示一般每个Unit都有各个块(section)组成,由[]包裹就是块名。下面的就是配置,直到另一个块开始为止。 [Unit] section [Unit]一般是第一个块文件配置,配置各种元数据(metadata)和其他单元的关系 Option Description Description= 这个单元的描述字符串 Documentation= 文档链接 Requires= 运行这个单元所需要的依赖单元,否则启动失败 Wants= 和上面Requires相似,但是非强限制。如果列出在此的单元没有启动,本单元也还是能启动持续运行 BindsTo= 和上面Requires相似,区别是列出在此的单元终止了,本单元也会停止 Before= 在此列出的单元,只有在本单元启动后才会启动。但不是依赖关系,如需依赖配置上述Requires命令 After= 在启动本单元之前,先要启动在此列出的单元。但不是依赖关系,如需依赖配置上述Requires命令 Conflicts= 在此列出的单元,不能和本单元同时运行,和Requires相反 OnFailure= 在此列出的单元将会在本单元失败后激活 还有很多的如Condition...和Assert...配置详情可以查看手册man 5 systemd.unit [Install] section [Install]一般是最后一个块文件配置,这个是可选项,也就是说可以不配置。只有在开机启动激活(enable)时触发。 Option Description WantedBy= 指定该单元如何开机启动(enable),依赖在此列出的单元,有点类似[Unit]块中的Wants,不同的是它会创建软链接到.wants文件夹,如上sshd如果被enable,该单元会创建一个软链接到/etc/systemd/system/multi-user.target.wants文件夹下,如果文件夹不存在则创建文件夹再软链接。 RequiredBy= 和上面WantedBy类似,但如果在此列出的单元没有激活,本单元会激活失败,同样在.requires文件夹下创建软链接。 Alias= 设置改单元的别名,可以给systemctl使用,例如上面sshd的开机启动可以使用 systemctl enable ssh....

July 8, 2018 · 2 min · 315 words · Fython