Linux Shell
2019-08-21
PS: Shell 编程时总是不能区分什么是 Shell 语法,什么是系统命令。
基础
x=abc
echo hello world
echo 'Just output $x'
echo "The value of x: $x"
echo ${x:?变量未设置}
echo ${x:+变量已设置}
echo ${x:-默认值}
变量
Shell 就是标准的弱类型,所有的数据都是按照字符串的形式存储,然后根据上下文决定如何处理。
x='hello world' # 等于号两边不能有空格
local x='hello world' # 本地作用域,函数体中使用
echo $a
echo ${a}
unset a
readonly a # 将变量设置成只读,不能修改,不能 unset
readonly b=1
# 没有提供方法取消 readonly 属性,但是我看到 SO 上有提供非常规方法来做这件事情
字符串变量
单引号不支持变量和转义(也就是说字符串中不能出现单引号)!
x="hello world"
echo $x
echo ${#x}
echo ${x/world/markjour} # 字符串替换
# 子字符串/字符串切片
echo ${x::5} # hello
echo ${x:7:8} # world
echo ${x::4} # hell
echo ${x::-4} # hello w
特殊变量
$0
$1
...
$n
# 所有参数
$*
$@
$# # 参数个数
$$ # 进程号
$! # 后台进程号
$? # 上一个命令的退出状态
$- # himBHs 当前 Shell 的选项
数组
arr=(zhao qian sun li)
arr[4]=zhou
arr[5]=wu
arr[6]=zheng
arr[7]=wang
echo ${arr[0]} # zhao
echo ${arr[@]} # zhao qian sun li zhao wu zheng wang
# 获取数组元素个数
echo ${#arr} # 4 定义时的长度,后来新加的不算,也就是说这个值定义变量的时候就定了
echo ${#arr[@]} # 8
条件
if condition:
then
:
else:
:
fi
循环
for var in list:
do
:
done
数学计算
test
逻辑
数学比较
字符串比较
文件相关
bcdfgkpurwxse
白菜豆腐干,靠谱如我,羞涩
最常用的:
-e 检查路径是否存在
-d 检查是否为目录
-f 检查是否为文件
-r 检查文件是否可读
-w 检查文件是否可写
-x 检查文件是否可执行
-s 检查文件是否为空
参考资料与拓展阅读
Linux 开发工具 图像处理 ImageMagick 乱码问题
2019-06-22
为什么 convert 和 montage 命令中使用的汉字都没能正确渲染在图片中去呢?
或许,可以将本文中的中文替换成 non-ascii 字符,或者 Unicode 字符。
或许,也可将 ImageMagick 替换成其他不支持中文的库。
参考了实在是太多文档,都没来得及记下来,只是从 Shell 的历史纪录中翻出来这些命令,做一个记录。
结论
字体问题,必须选择包含中文字形的字体,使用完整的字体名称,比如:Noto-Sans-Mono-CJK-SC-Regular。
开发工具 Linux 终端
2019-06-22
整理一下关于终端的种种概念。
开发工具 Linux 终端 xterm 软件配置
2019-06-20
其实我没有怎么用过这个终端模拟器,用的多的还是 GNOME Terminal。
但这个灵活的 X11 终端模拟器,它的名字还是经常能在一些地方碰到的,比如 XShell、PuTTY 的配置中。
除了 xterm 之外,什么 Linux Console、rxvt、vt100、vt220、vt320 之类的,关于终端,可以说的太多。以后如果有空,对这个仔细了解之后再专门写一篇博客说这个吧!
开发工具 Linux 终端
2019-06-19
- 通过 ASCII 字符或者色块,加上颜色转换实现
- 通过终端的图形支持实现
理论上,可以看图之后,也可以看视频,甚至做更多复杂的事情。
Linux unzip 乱码问题
2019-05-06
一、问题提出
使用info-zip.org 的 unzip类 解压zip压缩包,如果压缩包中有中文文件名,那么解压这些文件出来时文件名是乱码的。
二、分析
参考这篇文章 让 Unzip 正确解压其中包含中文文件名的 Winzip 压缩包链接失效 (注:疑似转载链接),原因是 unzip 试图将 zip 文件中用 oem(ibm-dos) codepage 编码的文件名转换成自己的内部编码。可惜 unzip 只能转换极少数几种 codepage,中文的 cp936 不在其列。
开发工具 Linux 图像处理 ImageMagick
2019-05-05
ImageMagick 是 Linux 下的一个常用的图像处理工具,核心命令是 convert, identify 等。
开发工具 Ubuntu Linux
2019-04-26
Ubuntu 19.04 与 4/19 发布,生命周期 9 个月。我提前两个月就定着日程在等,总是克制不住追新的冲动,哈哈。
好像主要就是:
- 内核升级到 5.0(4.x 升级到 5.0 其实没有什么大变化,主要是老人家高兴)
- GNOME 3.32,之前是 3.30
do-release-upgrade
由于审计过程中意外中断,导致出现了一些问题,这里做个记录。
声明:这些问题,是非正常升级流程出现的,不是说是 Ubuntu 的问题。
Linux
2019-04-04
以我本地系统(Ubuntu)上的 supervisord 为例。
ps -ef | grep supervisord / pgrep supervisord
sudo cat /proc/1553/maps
sudo gdb attach 1553
- gdb 中导出指定区域内存
dump memory /tmp/1553-heap.mem 0x564a7e667000 0x564a7eb25000
- 显示内存数据
strings -n 10 /tmp/1553-heap.mem
ASCII 格式的展示,过滤掉长度少于 10 的行。
关于 /proc/pid/maps 文件的格式
内存映射(mmap):
- 文件映射,将整个文件或文件的一部分映射到内存中
- 匿名映射,创建一个全为 0 的内存空间
这里的 maps 文件就是内存映射的一个情况。
- 内核操作集:proc_pid_maps_op,导出函数:show_map(没接触过内核开发)
- 可以
sudo head /proc/self/maps 试试。当前进程的内存映射信息表,软链接。
- Linux 内存管理单元数据结构:
vm_area_struct
$ sudo head /proc/1553/maps
564a7d858000-564a7d8a5000 r--p 00000000 08:01 3018208 /usr/bin/python2.7
564a7d8a5000-564a7da56000 r-xp 0004d000 08:01 3018208 /usr/bin/python2.7
564a7da56000-564a7db65000 r--p 001fe000 08:01 3018208 /usr/bin/python2.7
564a7db66000-564a7db68000 r--p 0030d000 08:01 3018208 /usr/bin/python2.7
564a7db68000-564a7dbde000 rw-p 0030f000 08:01 3018208 /usr/bin/python2.7
564a7dbde000-564a7dc02000 rw-p 00000000 00:00 0
564a7e667000-564a7eb25000 rw-p 00000000 00:00 0 [heap]
7fe8e4308000-7fe8e4448000 rw-p 00000000 00:00 0
7fe8e4448000-7fe8e444c000 r--p 00000000 08:01 1840428 /lib/x86_64-linux-gnu/libexpat.so.1.6.8
7fe8e444c000-7fe8e446d000 r-xp 00004000 08:01 1840428 /lib/x86_64-linux-gnu/libexpat.so.1.6.8
- 第一列:address 地址。[vm_start, vm_end),即起始地址-结束地址。
- 第二列:perms 权限。vm_flags,前三位分别是
r/w/x,不必说,第四位有两种值:p 或 s,分别表示私有 private 或共享 shared。
- 第三列:offset 偏移。vm_pgoff,如果是从文件映射到内存,那么偏移值表示从这个文件的指定位置开始,否则就会是
00000000
我猜,可能比较多的是用在拓展库之类的方面。
- 第四列:dev 设备。主设备号:次设备号,同样适用于从文件映射到内存的情况,表示文件所存放的设备。
- vm_file->f_dentry->d_inode->i_sb->s_dev
- 第五列:inode FS索引节点。同样适用于从文件映射到内存的情况,表示文件所存放的 “块”(或者叫 “区域” 吧)。
- vm_file->f_dentry->d_inode->i_ino
- 0 表示不关联,dev 字段也应该为
00000000
- 第六列:pathname 文件名
- 文件名
- 这段虚拟内存在进程中的角色,常见的:
[heap] 堆
[stack] 栈,主线程(main process)
[stack:1001] 栈,线程 ID 我还没见到过这样的情况
[vdso]
[vvar]
[vsyscall]
- 匿名映射
其他
- 据说,主线程申请内存(malloc)会显示
[heap],子线程申请则是匿名映射。
- 子线程的栈空间动态分配,匿名。这就是我没看到一例类似
[stack:1001] 情况的原因么?
-
从 maps 文件记录上看,增加一个子线程,在 maps 文件中就增加了两条记录,分别是子线程的栈空间和栈保护页的记录。默认情况下,pthread为子线程预留的栈空间大小为1MB,栈保护页为4KB(这主要跟页大小相关)。
#!/usr/bin/env python
import re
maps_file = open('/proc/self/maps', 'r')
mem_file = open('/proc/self/mem', 'r', 0)
for line in maps_file.readlines(): # for each mapped region
m = re.match(r'([0-9A-Fa-f]+)-([0-9A-Fa-f]+) ([-r])', line)
if m.group(3) == 'r': # if this is a readable region
start = int(m.group(1), 16)
end = int(m.group(2), 16)
mem_file.seek(start) # seek to region start
chunk = mem_file.read(end - start) # read region contents
print chunk, # dump contents to standard output
maps_file.close()
mem_file.close()
sudo awk -n -F '[- ]' '/\[heap\]/ {h="0x"$2-"0x"$1+1;printf("%d bytes (%.2f MB)\n",h,h/1024/1024)}' /proc/1553/maps
python -c "import sys;a,b=sys.argv[1].split('-');ai=int('0x'+a,16);bi=int('0x'+b,16);x=(bi-ai+1);y=x/(1024*1024);print('%d Bytes (%.2f MB)'%(x,y));" 55854b0f5000-55855a372000
参考资料或拓展阅读
- colin.guru,Dumping Ram From Running Linux Processes
- StackOverflow,How to identify STACK and HEAP segments in /proc/$PID/maps file?
- StackOverflow,How do I read from /proc/$pid/mem under Linux?
- CSDN,linux proc maps文件分析
开发工具 Linux 终端 tmux
2019-03-21
从今天开始,打开 TeamViewer 就这样了。


商业用途
检测为商业用途
该软件似乎适用于商业环境。请注意:免费版仅供个人使用。
您的会话将在5分钟后终止。请登录我们的网站以获得更多信息。
商业用途
超时后连接将被阻断。
您的许可证对您与伙伴的最大会话时间有所限制,立即重新连接时将被阻断。请稍后再试或升级您的许可证。
与该伙伴的连接在07:33之前都将保持阻断。
我不喜欢下那些破解版软件,对原开发者来说,就是偷东西,总觉得有亏于人。
另一方面也不放心其安全性。
但是,这价格真心用不起。

新方案
需求
远程访问公司的工作机器
备选方案
不管什么方案,从两个内网机器想要实现通信,只能有一个双方都能连接的外网主机进行中转。
我对自己家的公网 IP 很久以前就绝望了,我打电话给电信要求分配公网 IP,之后他们说给我开了,然后我要求进入光猫最高权限,进去设置端口转发规则,不行。。。那要公网 IP 有捷豹用啊!
所以:
- 要么别个给免费的全套远程桌面访问解决方案(一般有些限制),比如行云管家
- 要么给免费的数据转发(一般也有些带宽之类的限制),或许附带专用软件。
只要能流畅使用终端,都可以接受。
在研究方案的过程中,发现了另一个好的选择:tmate.io。
tmate.io
这是 tmux 的分支。
tmux 我用过好一阵子,也很容易上手。

使用方法:
# 创建远程连接
tmate -S /tmp/tmate.sock new-session -d
# 显示 SSH 连接命令
tmate -S /tmp/tmate.sock display -p '#{tmate_ssh}'
思路
创建定时任务,定时检查并建立 tmate 连接,然后将 ssh 命令输出到文件里面。
文件位于我的坚果云文件同步目录 $HOME/Documents/Mine/,这样我在任何地方都能通过 SSH 访问公司的电脑。
/etc/cron.d/tmate
SHELL=/usr/bin/zsh
* * * * * markjour [ -f $HOME/Documents/Mine/tmate.now ] && $HOME/Documents/Mine/tmate.sh && rm $HOME/Documents/Mine/tmate.now
~/Documents/Mine/tmate.sh
#!/usr/bin/zsh
tmate -S /tmp/tmate.sock kill-session
tmate -S /tmp/tmate.sock new-session -d
sleep 3
tmate -S /tmp/tmate.sock display -p '#{tmate_ssh}' > ~/Documents/Mine/tmate.conn
我在家只需要在同步目录下创建一个名为 tmate.now 的文件,一会儿就能用上 ssh 了。