局域网内跨平台传输文件、文字 | Dukto

在日常生活和实际工作中经常需要涉及到局域网内多设备传输文件,此前尝试过飞鸽传书,发现Mac平台体验并不好,也不够可靠;使用NAS等网络存储设备可以解决,但不能随时随地都带这个NAS,此时通过一款可跨平台传输文件的工具在网内分享文件就可极大提升效率。

使用Dukto可以在局域网内的 Mac 之间、Win之间、Android之间,以及跨平台之间传输文件、文字、文件夹。

https://imagehost-cdn.frytea.com/images/2020/10/30/20201030112556e831cefc342c413c.png

实测速度还是不错的,比较稳定,网内设备一下就能发现。

作者已经停止更新,但个人感觉也没有什么需要更新的了。

下载地址贴在这里:

参考文献

iTerms 常用快捷键

  • 切换 tab: ⌘+← , ⌘+→ , ⌘+{ , ⌘+} , ⌘+数字 直接定位到该 tab;
  • 新建 tab: ⌘+t;
  • 顺序切换 pane: ⌘+[ , ⌘+] ;
  • 按方向切换 pane: ⌘+Option+方向键 ;
  • 切分屏幕: ⌘+d 水平切分, ⌘+Shift+d 垂直切分;
  • 智能查找,支持正则查找: ⌘+f 。
  • 多个Tab、窗口执行同一个命令: ⌘Command + ⇧Shift + I

参考文献

Python执行或远程执行shell命令

最近想要实现通过脚本循环再 Linux 下运行 shell 命令,经过探索发现使用 Python 语言有几种解决方案,在此简单记录。

方案一:脚本本地执行命令

在 Python 中有两个库都可以实现运行 shell 命令的效果:

import subprocess
import os

使用方法也很简单:

# subprocess 使用方法
subprocess.call("ls") # 执行ls命令

# os 使用方法
# 使用system模块执行linux命令时,如果执行的命令没有返回值res的值是256
# 如果执行的命令有返回值且成功执行,返回值是0
res = os.system("ls")
# popen模块执行linux命令。返回值是类文件对象,获取结果要采用read()或者readlines()
val = os.popen('ls').read() # 执行结果包含在val中

方案二:脚本远程执行命令

在 Python 中有一个库可以实现 SSH 客户端及 SFTP 的功能。

#!/usr/bin/python
import paramiko

使用方法大致如下:

# 连接方法
def ssh_connect( _host, _username, _password ):
    try:
        _ssh_fd = paramiko.SSHClient()
        _ssh_fd.set_missing_host_key_policy( paramiko.AutoAddPolicy() )
        _ssh_fd.connect( _host, username = _username, password = _password )
    except Exception, e:
        print( 'ssh %s@%s: %s' % (_username, _host, e) )
        exit()
    return _ssh_fd

# 运行命令
def ssh_exec_cmd( _ssh_fd, _cmd ):
    return _ssh_fd.exec_command( _cmd )

# 关闭SSH
def ssh_close( _ssh_fd ):
    _ssh_fd.close()

方案三:使用 SecureCRT 脚本

该方法参见此前的博文:SecureCRT 下 Python 脚本编写

参考文献

终端抓包神器 | tcpdump参数解析及使用

本文整理转自:tcpdump参数解析及使用详解

tcpdump介绍

tcpdump 是一个运行在命令行下的抓包工具。它允许用户拦截和显示发送或收到过网络连接到该计算机的TCP/IP和其他数据包。tcpdump 适用于大多数的类Unix系统操作系统(如linux,BSD等)。类Unix系统的 tcpdump 需要使用libpcap这个捕捉数据的库就像 windows下的WinPcap。

tcpdump命令格式

Tcpdump的大概形式如下:

tcpdump –i eth0 ’port 1111‘ -X -c 3
  • X 告诉 tcpdump 命令,需要把协议头和包内容都原原本本的显示出来(tcpdump会以16进制和ASCII的形式显示),这在进行协议分析时是绝对的利器。

tcpdump 采用命令行方式,它的命令格式为:

tcpdump [ -adeflnNOpqStvx ] [ -c 数量 ] [ -F 文件名 ]
[ -i 网络接口 ] [ -r 文件名] [ -s snaplen ]
[ -T 类型 ] [ -w 文件名 ] [表达式 ]

tcpdump 参数

-a:将网络地址和广播地址转变成名字;

-d:将匹配信息包的代码以人们能够理解的汇编格式给出;

-dd:将匹配信息包的代码以c语言程序段的格式给出;

-ddd:将匹配信息包的代码以十进制的形式给出;

-e:在输出行打印出数据链路层的头部信息,包括源mac和目的mac,以及网络层的协议;

-f:将外部的Internet地址以数字的形式打印出来;

-l:使标准输出变为缓冲行形式;

-n:指定将每个监听到数据包中的域名转换成IP地址后显示,不把网络地址转换成名字;

-nn:指定将每个监听到的数据包中的域名转换成IP、端口从应用名称转换成端口号后显示

-t:在输出的每一行不打印时间戳;

-v:输出一个稍微详细的信息,例如在ip包中可以包括ttl和服务类型的信息;

-vv:输出详细的报文信息;

-c:在收到指定的包的数目后,tcpdump就会停止;

-F:从指定的文件中读取表达式,忽略其它的表达式;

-i:指定监听的网络接口;

-p:将网卡设置为非混杂模式,不能与host或broadcast一起使用

-r:从指定的文件中读取包(这些包一般通过-w选项产生);

-w:直接将包写入文件中,并不分析和打印出来;

-s:snaplen snaplen表示从一个包中截取的字节数。0表示包不截断,抓完整的数据包。默认的话 tcpdump 只显示部分数据包,默认68字节。

-T:将监听到的包直接解释为指定的类型的报文,常见的类型有rpc (远程过程调用)和snmp(简单网络管理协议;)

-X:告诉tcpdump命令,需要把协议头和包内容都原原本本的显示出来(tcpdump会以16进制和ASCII的形式显示),这在进行协议分析时是绝对的利器。

参考文献

SecureCRT下Python脚本编写

本文主要内容转自:SecureCRT中python脚本编写学习指南

SecureCRT 支持 VB、JavaScript、Python 等多种脚本语言。

一、使用 python 语言实现 SecureCRT 中的 Dialog 功能

# $language = "Python"
# $interface = "1.0"

#crt.Dialog.FileOpenDialog([title,[buttonLabel,[defaultFilename,[filter]]]])
#弹出一个对话框,用于选择单个文件;如果选择了具体文件则返回该文件的绝对路径,如果选择了弹窗的“取消”,则返回空。
filePath =  crt.Dialog.FileOpenDialog("please open a file","open","a.log","(*.log)|*.log")
#filePath =  crt.Dialog.FileOpenDialog("","","a.log","")
#crt.Dialog.MessageBox(message, [title, [icon|buttons]]) 警告、按钮类型弹出一个消息框,可以定义按钮,使用按钮和文本消息来实现和用户的简单对话;
crt.Dialog.MessageBox(filePath,"",64|0)
crt.Dialog.MessageBox("会话已断开","session",64|2)
crt.Dialog.MessageBox("确认是否退出","session",32|1)
crt.Dialog.MessageBox("确认是否退出","session",32|3)
crt.Dialog.MessageBox("是否继续安装","session",32|4)
crt.Dialog.MessageBox("此会话已打开","session",48|5)
crt.Dialog.MessageBox("无法连接此窗口","session",16|6)

#crt.Dialog.Prompt(message [, title [,default [,isPassword ]]])
#弹出一个输入框,用户可以填写文字,比如填写文件名,填写路径,填写IP地址等,运行结果如果点击'ok',返回输入的字符串,否则返回"" 
password = crt.Dialog.Prompt("password","session","admin",False)
crt.Dialog.MessageBox(password,"password",64|0)
password = crt.Dialog.Prompt("password","session","",True)
crt.Dialog.MessageBox(password,"password",64|0)

二、使用 python 语言实现 SecureCRT 中的 Screen 功能

# $language = "Python"
# $interface = "1.0"

# CurrentColumn返回当前光标的列坐标。
curCol =  crt.Screen.CurrentColumn
crt.Dialog.MessageBox(str(curCol))

# CurrentRow返回当前光标的行坐标。
curRow = crt.Screen.CurrentRow
crt.Dialog.MessageBox(str(curRow))

# Columns 返回当前屏幕的最大列宽
cols = crt.Screen.Columns
crt.Dialog.MessageBox(str(cols))

# Rows 返回当前屏幕的最大行宽
rows = crt.Screen.Rows
crt.Dialog.MessageBox(str(rows))

#IgnoreEscape 定义当使用WaitForString、WaitForStrings和ReadString这三个方法时是否获取Escape字符(特殊字符如回车)默认是会获取的
crt.Screen.IgnoreEscape = False
crt.Dialog.MessageBox(crt.Screen.ReadString(["\03"],5)) #获取ctrl+c

crt.Screen.IgnoreEscape = True
crt.Dialog.MessageBox(crt.Screen.ReadString(["\03"],2)) #不获取ctrl+c

# MatchIndex 定义当使用WaitForStrings和ReadString这三个方法时会根据参数的位置 获取返回值,从1开始计算,如果没有一个匹配则返回0.
outPut = crt.Screen.ReadString(["error","warning","#"],10)
index = crt.Screen.MatchIndex
if (index == 0):
    crt.Dialog.MessageBox("Timed out!")
elif (index == 1):
    crt.Dialog.MessageBox("Found 'error'")
elif (index == 2):
    crt.Dialog.MessageBox("Found 'warning'")
elif (index == 3):
    crt.Dialog.MessageBox("Found '#'")

# Synchronous 设置屏幕的同步属性。若设置为false,则在脚本中使用WaitForString、WaitForStrings、ReadString函数时可能存在丢失一部分数据的现象,设置为true后可能会存在屏幕卡顿的情况,默认为false
crt.Screen.Synchronous = True
crt.Screen.Send("\r\n")
crt.Screen.ReadString("#")
crt.Screen.Send("\r\n")
crt.Screen.WaitForString("#")
crt.Screen.Send("\r\n")
crt.Screen.WaitForStrings(["#",">"])
crt.Screen.Send("conf t\r\n") 

# 方法
# Clear()清屏功能
# crt.Screen.Clear()

# get()按照坐标取出一个矩形框内的屏幕上的字符(即从某行某列开始到其它行其它列),不包含字符串中的回车换行符,所以这个多用于获取无格式的光标处字符串或某小段特定区域字符串。
out = crt.Screen.Get(row1, col1, row2, col2)
crt.Dialog.MessageBox(out)

# get2()解释按照坐标取出一个矩形框内的屏幕上的字符(即从某行某列开始到其它行其它列),包含字符串中的回车换行符,所以这个多用于获取大段带格式的字符串。
crt.Screen.Get2(row1, col1, row2, col2)

# IgnoreCase 使用全局参数设置控制在使用WaitForString、WaitForStrings和ReadString这三个函数时是否对大小写敏感,默认为false大小写字符串都会检查,设置为true时则不会检测大小写。
crt.Screen.IgnoreCase = True
crt.Screen.Send("show memory\r\n")
crt.Screen.WaitForString("more")
crt.Screen.Send("\r\n")
crt.Screen.WaitForStrings("more","#")
crt.Screen.Send("\r\n")
crt.Screen.ReadString("more","#")

# Send() 向远端设备或者屏幕发送字符串,当向屏幕发送字符串时需要指定第二个参数为Ture
crt.Screen.Send("show version\r\n")
crt.Screen.Send("\r\nhello,world!\r\n",True)
crt.Screen.IgnoreCase = True
while (crt.Screen.WaitForString("more",10)):    
    crt.Screen.Send("\r\n")

# SendKeys()向当前窗口发送按键,包含组合按键,比如可以发送类似"CTRL+ALT+C"等这样的组合键,这样写即可:crt.screen.sendkeys("^%c");这个功能需要语言本身支持,目前只有VBS和JS脚本可以使用。

# SendSpecial()可以发送特殊控制码,这个控制码是Crt内置的功能,具体可以包含的有Menu、Telnet、VT functions功能列表中提供的所有功能,
crt.Screen.SendSpecial("vT_HOLD_SCREEN")

# WaitForCursor()等待光标移动,当移动时返回值为true,当有超时时间参数且超时时返回false,否则会一直等待光标移动。利用这个功能可以用来判断一个命令的输出是否结束,
crt.Screen.WaitForCursor(5)
crt.Screen.Send("\r\nhello,world!\r\n",True)
if ( crt.Screen.WaitForCursor(5)):
    crt.Screen.Send("show version\r\n")

# WaitForKey()检测有键盘按键时返回true,当有超时时间参数且超时时返回false,否则会一直等待按键
if (crt.Screen.WaitForKey(5)):
    crt.Screen.Send("show version\r\n")

# WaitForString()一般用于发送命令后等待某字符串
# crt.Screen.WaitForString(string,[timeout],[bCaseInsensitive])
crt.Screen.WaitForString("#",10)

# WaitForStrings()与WaitForString是同样的功能,可以等待多个字符串
outPut = crt.Screen.WaitForStrings(["error","warning","#"],10)
index = crt.Screen.MatchIndex
if (index == 0):
    crt.Dialog.MessageBox("Timed out!")
elif (index == 1):
    crt.Dialog.MessageBox("Found 'error'")
elif (index == 2):
    crt.Dialog.MessageBox("Found 'warning'")
elif (index == 3):
    crt.Dialog.MessageBox("Found '#'")

# ReadString()与WaitForStrings功能类似,都是等待某几个字符出现,不同的是它还会读取字符串之前出现的所有字符。
crt.Screen.ReadString([string1,string2..],[timeout],[bCaseInsensitive])        
1. string,必选参数,等待的字符串,最少有一个,可以是特殊字符比如:\r\n;
2. timeout,可选参数,超时时间,当检测不到对应字符串时会返回false,没有此参数时会一直等待;
3. bCaseInsensitive,可选参数,大小写不敏感,默认值是false,表示将检测字符串的大小写,当为true时不检测大小写。

三、实例

1. 实例一,循环运行命令

# $language = "python"
# $interface = "1.0"

# This automatically generated script may need to be
# edited in order to work correctly.

import time

start_time = time.time()
end_time = time.time()

def Main():
    while True:
        end_time = time.time()
        crt.Screen.Synchronous = False
        crt.Screen.Send("?")
        crt.Screen.Send("\r\n")
        crt.Screen.Send("\r\n")
        time.sleep(1)
    running_time = end_time - start_time
    msg = "会话已断开\n" + \
            "running ms : " + str(running_time) + "\n" + \
            "start ms   : " + str(start_time) + "\n" + \
            "ent ms     : " + str(end_time) + "\n"
    crt.Dialog.MessageBox(msg,"session",64|2)
Main()

参考文献

Make参数

-b -m

这两个参数的作用是忽略和其它版本make的兼容性。

-B –always-make

认为所有的目标都需要更新(重编译)。

-C –directory=

指定读取makefile的目录。如果有多个“-C”参数,make的解释是后面的路径以前面的作为相对路径,并以最后的目录作为被指定目录。如:“make –C ~hchen/test –C prog”等价于“make –C ~hchen/test/prog”。

—debug[=]

输出make的调试信息。它有几种不同的级别可供选择,如果没有参数,那就是输出最简单的调试信息。下面是的取值:a —— 也就是all,输出所有的调试信息。(会非常的多)b —— 也就是basic,只输出简单的调试信息。即输出不需要重编译的目标。v —— 也就是verbose,在b选项的级别之上。输出的信息包括哪个makefile被解析,不需要被重编译的依赖文件(或是依赖目标)等。i —— 也就是implicit,输出所以的隐含规则。j —— 也就是jobs,输出执行规则中命令的详细信息,如命令的PID、返回码等。m —— 也就是makefile,输出make读取makefile,更新makefile,执行makefile的信息。

-d相当于 –debug=a。

-e –environment-overrides

指明环境变量的值覆盖makefile中定义的变量的值。

-f= –file= –makefile=

指定需要执行的makefile。

-h –help

显示帮助信息。

-i –ignore-errors

在执行时忽略所有的错误。

-I –include-dir=

指定一个被包含makefile的搜索目标。可以使用多个“-I”参数来指定多个目录。

-j [] –jobs[=]

指同时运行命令的个数。如果没有这个参数,make运行命令时能运行多少就运行多少。如果有一个以上的“-j”参数,那么仅最后一个“-j”才是有效的。(注意这个参数在MS-DOS中是无用的)

-k –keep-going

出错也不停止运行。如果生成一个目标失败了,那么依赖于其上的目标就不会被执行了。

-l –load-average[=“—max-load[=]

指定make运行命令的负载。

-n –just-print –dry-run –recon

仅输出执行过程中的命令序列,但并不执行。

-o –old-file= –assume-old=

不重新生成的指定的,即使这个目标的依赖文件新于它。

-p –print-data-base 输出makefile中的所有数据,包括所有的规则和变量。这个参数会让一个简单的makefile都会输出一堆信息。如果你只是想输出信息而不想执行makefile,你可以使用“make -qp”命令。如果你想查看执行makefile前的预设变量和规则,你可以使用“make –p –f /dev/null”。这个参数输出的信息会包含着你的makefile文件的文件名和行号,所以,用这个参数来调试你的makefile会是很有用的,特别是当你的环境变量很复杂的时候。

-q –question

不运行命令,也不输出。仅仅是检查所指定的目标是否需要更新。如果是0则说明要更新,如果是2则说明有错误发生。

-r –no-builtin-rules

禁止make使用任何隐含规则。

-R –no-builtin-variabes

禁止make使用任何作用于变量上的隐含规则。

-s –silent –quiet

在命令运行时不输出命令的输出。

-S –no-keep-going –stop

取消“-k”选项的作用。因为有些时候,make的选项是从环境变量“MAKEFLAGS”中继承下来的。所以你可以在命令行中使用这个参数来让环境变量中的“-k”选项失效。

-t –touch

相当于UNIX的touch命令,只是把目标的修改日期变成最新的,也就是阻止生成目标的命令运行。

-v –version

输出make程序的版本、版权等关于make的信息。

-w –print-directory

输出运行makefile之前和之后的信息。这个参数对于跟踪嵌套式调用make时很有用。

–no-print-directory

禁止 -w 选项。

-W –what-if= –new-file= –assume-file=

假定目标需要更新,如果和“-n”选项使用,那么这个参数会输出该目标更新时的运行动作。如果没有“-n”那么就像运行UNIX的“touch”命令一样,使得的修改时间为当前时间。

–warn-undefined-variables

只要make发现有未定义的变量,那么就输出警告信息。

参考文献

Makefile实例:批量编译多个目标

gist: https://gist.github.com/songtianlun/8984626fd80cd20b7c2e71f95caaf8d1

# Batch Single C file MakeFile

# 指定CPU架构 Architecture -> ARCH
ARCH ?= 
CC = $(ARCH)gcc
SUFFIX = .c
CFLAGS += -Wall -g
LD = 

CUR_SOURCE = $(wildcard *$(SUFFIX))
CUR_TARGETS = $(patsubst %$(SUFFIX), %, $(CUR_SOURCE))

all:$(CUR_TARGETS)

# %:%.c 是一个表示与目标相同 文件的模式变量 
$(CUR_TARGETS):%:%$(SUFFIX)
    $(CC) $< $(CFLAGS) -o $@ $(LD)

# 指定伪目标
.PHONY:clean all
    clean:
        -rm -rf $(TARGETS)

参考文献

Makefile中部分函数的使用

foreach

一、作用

循环处理文件列表。

二、格式

$(foreach var text commond)

var:局部变量

text:文件列表,空格隔开,每一次取一个值赋值为变量var

commond:对var变量进行操作(一般会使用var变量,不然没意义),每次操作结果都会以空格隔开,最后返回空格隔开的列表。

wildcard

功能是展开成一列所有符合由其参数描述的文 件名,文件间以空格间隔。你可以像下面所示使用这个命令:

SOURCES= $(wildcard *.c)

这行会产生一个所有以 .c 结尾的文件的列表,然后存入变量 SOURCES 里。当然你不需要一定要把结果存入一个变量。

notdir

把展开的文件的路径去掉,只显示文件名而不包含其路径信息,例如:

FILES =$(notdir $(SOURCES))

这行的作用是把上面以 .c 结尾的文件的文件列表中附带的路径去掉,只显示符合条件的文件名。

patsubst

( patten substitude, 匹配替换的缩写)函数。它需要3个参数:第一个是一个需要匹配的式样,第二个表示用什么来替换它,第三个是一个需要被处理的由空格分隔的字列。例如,处理那个经过上面定义后的变量,

OBJS = $(patsubst %.c,%.o,$(SOURCES))

这行将处理所有在 SOURCES 列个中的字(一列文件名),如果它的 结尾是 .c ,就用 .o 把 .c 取代。注意这里的 % 符号将匹配一个或多个字符,而它每次所匹配的字串叫做一个‘柄’(stem) 。在第二个参数里, % 被解读成用第一参数所匹配的那个柄。

参考文献

Makefile基础语法

Makefile 是描述文件依赖关系的说明,由若干个规则组成,每个 规则 的格式如下:

目标:依赖关系
<tab键> 命令

其中:

  • 目标 是指 make 最终要创造的产物,也是 make 执行的动作名称,例如 clean ;
  • 依赖关系 是指编译目标体需要依赖的一个或多个文件列表;
  • 命令 是指为了从依赖文件创造目标文件所需执行的命令。

make 执行的动作也是一个目标,为避免该目标和文件目标冲突,可以使用以下格式将动作指定伪目标:

.PHONY: clean
clean:
        rm *.o temp

在使用时,在具有 Makefile 文件的项目目录下通过如下命令运行:

$ make [target]

其中的参数 target 是指要处理的目标名,不指定则默认为 make all 。除了 Makefile ,还可将文件命名为 GNUmakefile, makefile ,命令执行时按照 GNUmakefile,Makefile, makefile 的顺序搜索 Makefile 文件。

预定义变量

为使命令编写更快捷,免去无意义的重复操作,有一些预定义变量可以用于简化 Makefile 。

$@    # 规则目标对应的文件名
$*    # 不包含扩展名的目标文件名称
$+    # 所有的依赖文件,用空格分开,可能包含重复
$%    # 如果目标是归档成员,则该变量标识目标的归档成员名称
$<    # 规则中第一个依赖文件名
$^    # 规则中所有依赖的列表,空格分隔
$?    # 规则中日期新于目标的所有依赖文件的列表,空格分隔
$(@D) # 目标文件的目录部分
$(@F) # 目标文件的文件名部分

Make/Makefile 简介

Make 工具可用于在 Unix-like 和 Microsoft Windows 系统上,根据 Makrfile 文件指定的目标及步骤,自动编译构建、更新目标文件。

  • 类Unix

Makefile起源于类Unix系统,在此类环境中仍然是主要的软件构建机制。

  • Microsoft Windows

Windows通过其nmake实用程序支持各种makefile文件。可以在Windows的Cygwin环境或Mingw中执行类似Unix的标准makefile 。

参考文献