文档整理总结

工作中之后我参考了公司的文件管理方法,再借鉴了图书馆管理图书的方法,创建了一套自己的方法,非常简单但行之有效,我已经稳定使用了5年,再也不为文件混乱而焦虑了。

我的方法如下:

一、文件/文件夹前面加数字前缀实现排序。

毕业后我进入的第一家500强外企,我发现他们的公共盘上的文件夹前面都有一个数字前缀,如

  • 01_HR
  • 02_admin
  • 03_Fin
  • 04_Engg
  • 05_Sales

开始觉得多此一举,后来才发现真是绝绝子啊,

第一、有了这个前缀,文件夹就不再是按首字母顺序排了,而是你的编号来排,这样就可以人为固定文件夹的顺序,比如HR虽然首字母比Engg要低,但前面加上01 就可以让自己排在第一了,这样方便管理,也不会因为插入新的文件夹而打乱顺序了。每个部门只要记住自己部门文件夹所在位置,每次进去时就不用找半天了。

第二、这个前缀长度是固定的,所有的文件夹视觉上非常整齐而统一,不因为因为文件夹名字长短不一而产生混乱感。

于是我也应用在自己的文件管理上,所有文件夹都进行编号,经常使用的文件夹编号排在前面,不经常使用的排在最后面,再也不会被首字母打乱了。

img

这样是不是整齐很多了?

我没有采用下划线的方法隔开前缀,因为在中文输入法状态下输入下划线不方便,所以我用了空格隔开,大家也可以按照自己的偏好用小数点、连字符、字母作为分隔符。

二、文件加时间后缀。

我以前没这个习惯,不同版本的文件重新改个备注名就完事,但版本一多,时间一久,就分不清谁是谁了。

后来我发现公司的windchill系统上下载的文件,都会自动加一个时间后缀(上传的时间),如:

  • project_checklist_20220523

这样的好处是下载下来永远不会乱,系统会自动按照时间顺序排列,而你也知道这个文件是什么时候创建的,方便识别和追溯。

后来我在自己创建文件时,也加上时间后缀,发给别人修改后传回来,我又会加上最新的时间后缀,这样永远知道哪个版本是最新的,这是个很好的习惯,大家一定要保持。

发给客户的文件如果都加上一个时间后缀,会显得专业很多。

三、不要嵌套太多子文件夹,两层最好,最多三层。

大家想象一下,在图书馆里找书是不是很方便,不需要翻箱倒柜?图书馆的图书分类虽然也很详尽,比如有5个大类,22个小类,小类下面还有分类,但所有图书都是展示在书架上的,而不会在大书架里嵌套小书架,你要找什么图书一眼扫过去就能找到,就算是冷门的图书你也有机会看到,不会忘记它的存在。图书和书架所在的区域固定好了是不会乱跑的,上一次放在哪里,你下一次又回到熟悉的地方去找就能很快找到。

电脑里的文件可以分门别类,但也不要嵌套太多层子文件夹,很多人由于文件越来越多,分类越来越细致,会嵌套N多层子文件夹,我曾经嵌套就过七层文件夹,找文件时要一层一层进去,非常麻烦,后来我改成了以两层文件夹为主的结构后,效率大大提高。

所有文件夹,甭管它属于哪个大分类,全部都在最外层。

比如,之前我的“学习资料”文件夹里,有下面这么多个子文件,是为了分门别类用的,这样分得太细:

  • Excel学习
  • PPT学习
  • VBA学习
  • 电子书
  • 英语学习
  • 工作相关

每个子文件夹里的又会有自己的子文件夹,如:

学习资料\工作相关\MiniTab教程\MiniTab使用教学\XXXX.PPT

如果要打开这个PPT,要进入四层文件夹才能找到,非常低效

正确的做法是取消这些嵌套文件夹,直接把所有子文件夹放到外面来,然后用数字前缀归类。

例如:

img

前缀的第一个数字是大类,例如:

  • 01前缀表示工作相关的学习
  • 02前缀表示VBA编程学习
  • 03前缀表示英语学习
  • 04前缀表示电子书

也可以按照A、B、C、D字母排,看自己的喜好。

这些编号自己心里清楚就好,下次要添加新的资料,参考和它同属一类的文件夹进行编号即可,它们就可以自动放在一起了。

前缀的第二个的数字来实现大类里的内部排序,如果你想要谁排在前面就修改它的序号即可。

这里会有一个问题,系统默认是folder和folder排列一起,file和文件file排列一起,单个file不会参与folder的排序,这样有单个file时,排序就会混乱,怎么办呢?

这里有一个小技巧,就是给单独的file建立一个folder,里面只装这个file,让它强制参与folder的排序就OK了。

比如上面的04文件夹,如“小米生态链战地笔记”,其实原本是一个pdf文件,我也给它建了一个文件夹,这样就可以整整齐齐排在文件夹序列里了。

通过这种敞开式的方法,所有文件夹都是在最外层,一目了然,位置也是固定的,找起来也非常方便。

后期要维护的话,手动修改前缀就可以调整排序,如果要大规模调整的话可以借助文件批量命名软件(如renmaer)来修改。

但是如果文件越来越多怎么办,这个列表岂不是越来越长? 不用担心,每个大文件夹里只放近期用得着的文件,如果只是收集的资料,暂时不会用到,就要移到“参考资料&素材“或者”存档资料“里去,这部分内容我下面会说。

四、全盘文件大分类

为了避免频繁建立N多新文件夹,我们需要给所有文件夹进行分类,分类的方法有很多,有的人是按照文件类型排序,如视频、音频、图片、电子书、教程,但这样分仍然会很乱,比如你自己手机拍的照片和网上下载的图片,都放在图片文件夹里吗?显然不是,我建议按照用途来分,同一个用途下,不管是什么类型的文件都可以放在一起,这样符合人的直觉。

我的文件只分以下八大类,而且全部都在C盘根目录下:

img

不要担心和C盘的系统文件有干扰,因为有数字编号,这些文件始终是排在最前面的。

为什么在C盘根目录? 因为我电脑不分区,只有一个C盘,大部分公司的电脑也不分区的,都2202年了,电脑就别再分区了吧,现在的windows系统就算是重装文件也不会丢失。

如果还不明白,看看这个问题下所有的回答:

01 工作目录

所有正在处理或者待处理的工作都在这个文件下,包括公司的工作,个人的私活,生活杂事,比如计算房贷,制定个人计划、打官司、帮别人写资料等等等等。

这样的好处是一点去就可以看到所有的待办事项,避免遗忘,可以统一处理,不需要在多个文件夹里反复横跳。

这里面只有一层子文件夹,也用01….02….来给文件夹编号分类,我还会在文件前加上创建时间,这样就很容易知道是哪一天开始处理的,时间久了就有紧迫感。

比如

img

这里的文件迟早会越堆越多,这个列表就会变得很长,越积越多我们心里也会有压力,就会督促我们及时处理,这时候我们要及时把已经处理完的文件移动到 “08 存档资料”里。

记住,始终要把工作目录里的文件夹控制在一定数量,做完的马上移走。

02 学习资料

放一些学习教程,如职场技能学习,英语学习、法律学习等等,同样也只建立一层子文件夹,参考上述第二点。

img

03 参考资料&素材

这里放一些“01 工作目录”文件夹可能需要用到参考资料和素材,这是你从事工作的原材料。比如网上下载的模板、表格、图片、视频、字体,以及一些技术资料、标准规范、法律文件等等。比如设计师和视频创作者一定会下载大量的图片、视频等素材,这些资料就放在这里,而不要放在图片、视频文件夹里。

注意区分参考资料和学习资料的区别,前者是指你不会去专门去学习,只是有需要时可能查阅的资料,后者是你会认认真真学习的资料。

比如汽车行业标准《IATF16949:2016质量管理体系汽车生产件及相关服务件组织应用ISO9001:2015的特别要求》,既可以放在“02 学习资料”里,也可以放在“03 参考资料&素材”里。如果你打算全文好好学习一遍,那就放在“02 学习资料”,而你不打算学习,只是存档下来备查,就放在“03 参考资料&素材”。

04 视频

放一些电影、美剧等影视资料,是用来娱乐的,因为这些文件体积比较大,而且会经常看,所以专门建个文件夹。

这里的视频不包括自己手机拍摄的视频,也不包括学习教程的视频,纯粹只是为了娱乐而看的视频。

自己手机拍的视频要放在“05 相册”里,学习教程的视频放在“02 学习资料”里。

这个文件夹里就不需要按照美剧、电影等类别建立子文件夹了,而是直接把所有剧集放在最外层,方便查找。

05 相册

自己手机拍摄的图片、视频放在这里面,但不包括网上下载的图片,这些图片应该放在“03 参考资料&素材”里。

自己手机拍摄的图片非常多,有几百甚至上千张,要按年和月份建立文件夹。

我现在是按年建立第一层文件夹,如

  • 2019年
  • 2020年
  • 2021年
  • 2022年

然后里面再按拍摄的日期+主题建立子文件,比如

  • 20190518 贵州旅游
  • 20191220 公司年会

而不是散乱地铺开,不然每次打开这个文件夹的速度让你怀疑人生。

我最近考虑把外面的年文件夹取消,减少层级,让里面的子文件夹一目了然。

06 软件工具

这里不是软件的安装目录,而是放一些大型软件的安装包,如office, ProE等等,免得重装时要去下载,以及一些绿色的软件,比如字幕转换助手、Renamer(批量改名工具),everything(迅速查找文件工具),Sketchup(快速建模软件),Minitab(统计软件)等等。

不要放很容易找到的软件,比如微信PC版,QQ,Chrome浏览器等等,需要的时候直接去官网下载最新版即可。

07 个人重要资料

这里放一些身份证复印件、户口本复印件、毕业证复印件、四六级复印件、房产证复印件、银行卡复印件、保险合同、劳动合同(如有电子版)、offer,体检报告、个人简历等等。

这些资料最好集中存放,找的时候方便,也建议在云端保存,随时随地都能找到。

08 存档资料

用于存放暂时不会用到,但以后说不定有用的文件,例如如“01 工作文件”中已经完成的工作,以及“02 学习资料”里已经学习完资料,或者存着备用,暂时不会学习的资料。

在这里建以下两个文件夹

  • 01 存档-工作文件
  • 02 存档-学习资料

记得前面要加上“存档“避免和工作目录的文件混淆

但不是什么文件都往里扔,要分情况:

一、如果已经完全失去保存的价值的文件,就断舍离,直接删了,不要有收藏癖,比如一套教程学完,觉得一般般,以后也不会看了,就直接删了。

二、如果稍微还有一点价值的文件,如果工作邮件、报表,怕以后还会需要,就存档。

五、桌面建立“临时”文件夹

很多人习惯把桌面当做临时存放文件的地方,时间久了会让桌面铺满文件,非常乱。

不妨在桌面建立一个”临时“文件夹,把暂时不知道放哪里的文件先放进去,这样可以让桌面保持清爽干净。

比如你在写资料,网上查的资料有些是压缩包或者pdf,必须要下载下来才能看到,你可以先下到“临时”文件夹里,用完即删,就算不删暂时先放着以后有时间再处理,这样就不会把乱七八糟的资料堆满桌面。

l

编号 类型 备注
01 无人机
02 博客
03 office
04 git
05 docker
06 java
07 macos
08 nas
09 shell
10 sql
11 ubuntu
12 正则
13 算法
14 终端
15 设计模式
16 整理
17 博客配置
18 photoshop
l

word技巧

正则替换

  1. 替换汉字之间的空格
1
2
查找:([!^1-^127]) ([!^1-^127])
替换:\1\2
  1. 删除英文字母和非英文字母之间的半角空格
1
2
3
4
5
【查找】:([A-Za-z])(^32@)([!A-Za-z])

【替换】:\1\3

注:使用通配符
  1. 删除非英文字母和英文字母之间的半角空格
1
2
3
4
5
【查找】:([!A-Za-z])(^32@)([A-Za-z])

【替换】:\1\3

注:使用通配符
  1. 删除中文字符(含符号)之间的单个半角空格
1
2
3
4
5
6
7
【查找】:

([一-龥,、。?!…;:——‘’“”……()【】《》·~@#%&—])(^32@)([一-龥,、。?!…;:——‘’“”……()【】《》·~@#%&—])

【替换】:\1\3

注:使用通配符
  1. 删除非数字与数字之间的单个半角空格

    1
    2
    3
    4
    5
    【查找】:([!0-9])(^32@)([0-9])

    【替换】:\1\3

    注:使用通配符
  2. 删除数字与非数字之间的单个半角空格

    1
    2
    3
    【查找】:([0-9])(^32@)([!0-9])

    【替换】:\1\3
  3. 删除多余空白行|段首空格|段尾空格

    1
    2
    3
    4
    5
    1、删除段首空格:^p^p,替换为:^p,全部替换;
    2、删除段首空格:(^13)(^32@),替换为:\1,全部替换;
    3、删除段尾空格:(^32@)(^13),替换为:\2,全部替换;

    注:使用通配符
  4. 匹配中文

  • 方法一

在word中匹配中文可以用[一-龥],其中龥(读yu),要用微软拼音才能输入,用紫光等其它拼音找不到这个字。如果用“颌”匹配不完全的。捕获用英文括号括起来,引用从左到右依次用\1, \2, …… 以此类推

word中排除字符和php不同,而是使用英文感叹号!,例如[!一-龥]匹配所有非中文字符。
word匹配多个字符也和php不同,使用的是@,例如[一-龥]@匹配0个或多个连续中文字符。

  • 方法二

匹配中文字符的正则表达式“[\u4e00-\u9fa5]”与
匹配双字节字符(包括汉字在内) “ [^\x00-\xff]”,该如何在MS Word中(变通)使用?

“实践是检验真理的唯一标准”的这句话呢? 为啥不能动动手呢?!
刚才试了一下,完全可以用,只要稍稍改动一下即可.
[\u4e00-\u9fa5]与[^\x00-\xff] 分别改为 [!\u4e00-\u9fa5]与[!\x00-\xff].

另有说法:用这个就可以了[!^1-^127]

WORD中的字符串限定

“<”表示字符串的开头,“>”表示字符串的结尾,“<祖国>”实际上表示对查找的内容进行严格的限制,或者也可以设置为“<祖国”,但“祖国>”则不允许使用。

通配符


任意单个字符:“?”可以代表任意单个字符,输入几个“?”就代表几个未知字符。如:输入“? 国”就可以找到诸如“中国”、“美国”、“德国”等字符;输入“???国”可以找到“孟加拉国”等字符。

img

任意多个字符: “*”可以代表任意多个字符。如:输入“*国”就可以找到“中国”、“美国”、 “孟加拉国”等字符。

指定字符之一: “[]”框内的字符可以是指定要查找的字符之一,如:输入“[中美]国”就可以找到“中国”、“美国”。 又如:输入“th[iu]g”,就可查找到“thigh”和“thug”。 输入“[学硕博]士”,查找到的将会是学士、士、硕士、博士。

img

指定范围内的任意单个字符: “[x-x]”可以指定某一范围内的任意单个字符,如:输入“[a-c]mend”的话,Word查找工具就可以找到“amend”、“bmend”、“cmend”等字符内容。

排除指定范、排除指定范围内的任意单个字符: “[!x-x]”可以用来排除指定范围内的任意单个字符,如:输入“[!a-c]”的话,word程序就可以找到“good”、“see”、“these”等目标字符,而所有包含字符a、b、c之类的内容都不会在查找结果中出现。

指定前一字符的个数:“{n}”可以用来指定要查找的字符中包含前一字符的个数,如:输入“cho{1} se”就是说包含1个前一字符“o”,可以找到“chose”,输入“cho{2}se”就是说包含2个前一字符“o”,可以找到, “choose”。

指定前一字符、指定前一字符数范围:“{x,x}”可以用指定要查找字符中前一字符数范围,如:输入“cho{1,2}”,则说明包含前一字符“o”数目范围是1-2个,则可以找到“chose”、“choose”。

img

一个以上的前一字符: “@”可以用来指定要查找字符中包含一个以上的前一字符,如:输入“cho@se”,就可以找到, “chose”、“choose”等字符。

指定起始字符串:“<”可以用来指定要查找字符中的起始字符串,如:输入“<ag”,就说明要查找的字符的起始字符为“ag”,可以找到 “ago”、“agree”、“again”等字符。输入“<te”的话,可能查到“ten”、“tea”等。

指定结尾字符串: “>”可以用来指定要查找字符中的结尾字符串,如:输入“er>”,就说明要查找的字符的结尾字符为“er”,可以找到 “ver”、“her”、“lover”等等。输入“en>”, 就说明要查找到以“en”结尾的所有目标对象,可能找到“ten”、“pen”、“men”;输入“up>”,就说明要查找到以“up”结尾的所有目标对象,例如会找到“setup”、“cup”等等。

经典案例

相关的正则表达式

^&:用于替换框,表示引用查找框的全部内容;

^11:手动换行符,等于通配符模式下的^l;

^13:换行符,等于通配符模式下、只能在替换框使用的^p;

^32:半角空格;

^?:任意单字符,等于通配符模式下的?(比较:*表示任意字符);

^#:任意单数字,等于通配符模式下的[0-9];

^$:任意单字母,等于通配符模式下的[a-zA-Z];

^w:换行符以外的所有空白区域;

^c:用于替换框,表示剪贴板上的内容;

[字符1字符2]:字符1或字符2;

[m-n]:序列m-n中的任意1个字符;

[!m-n]:序列m-n之外的任意1个字符;

[!字符1字符2]:字符1字符2之外的任意1个字符;

[^1-^127]:表示任一西文字符;

[!^1-^127]:表示任一中文字符;

{n}:n个前1字符或前1表达式;

{n,}:n个以上前1字符或表达式({1,}等于@,表示1个以上前1字符或表达式);

{n,m}:n到m个前一字符或前一表达式;

\通配符:引用通配符本身;

( ):表达式引导符,用于查找框,是为了在替换框中,用\n的形式来引用;

\n:与( )呼应,在替换框中使用,表示引用查找框中第n个表达式的内容;

<:句首引导符;

>:句尾引导符;

@:表示一个以上字符;

将查找对象设置格式:定位到替换框/设置格式/替换;

运用实例

准备:粘贴网页内容时,最好是选择性粘贴-无格式文本,以清除各种混乱格式。

1.清除空行:不选使用通配符;查找^p^p,替换为^p

2.清除空白区域:不选使用通配符;查找^w,替换为空值

3.删除特定行:使用通配符;查找^13特定内容^13,替换为^p

4.将数字中的句号替换为小数点:查找([0-9]{1,})。([0-9]{1,}),替换为\1.\2([0-9]{1,}表示1位及以上数字,\1和\2引用查找中的第1、2对括号内的表达式)

5.清除多余的换行符:

语法——勾选使用通配符。查找:([..,,、 ])^13@,替换为:\1

说明——[..,,、 ]为非句尾分隔符,\1引用第1对括号内的表达式[..,,、 ]。

6.清除重复内容:

准备——查找^p,全部替换为^p^p;全选文档或Ctrl+Home定位到文首。

语法——勾选使用通配符:

查找:(<[!^13]^13)()\1,替换为:\1\2(其中[!^13]*也可用[!^13]@或 [!^13]{1,} 来代替) ;

或:查找(^13[!^13]@^13){2,},替换为\1;

或:查找(*^13){2,},替换为\1;

7.将不在行首的选项另起一行:

语法——勾选使用通配符。查找:!^13[..、 ];替换为:^p\1.

8.将不在行首的题号另起一行:

语法——勾选使用通配符。查找:!^13[..、 ];替换为:^p\1.

9.将不连续题号重新编号:

在Word中,Ctrl+F9>>输入与代码SEQ A>>选中域>>剪切

>>Ctrl+H>>查找[0-9]@[. 、:.],替换为^c>>F9更新域

word页码

分页符作用:重置开始页码

插入->页码->判断是否链接到上一页

word单页横向

页面开始位置插入2个分页符,再设置该页横向

插入黑色实心方块

  1. 打开需要操作的WORD文档,选中相关小方框,点击插入选项卡的“符号”,并选择“其他符号”。

  1. 在Wingdings2中找到并点击选择全黑的小方块,然后点击插入即可。

  1. 返回主文档,发现WORD中把小空格方框填黑操作完成。

批量修改图片大小

  1. 方法一

打开VBA编辑器(也可直接按【Alt+F11】快捷键),新建模块,然后将下面的代码复制粘贴到窗口中。

1
2
3
4
5
6
7
8
9
10
Sub FormatPics()
Dim Shap As InlineShape
For Each Shap In ActiveDocument.InlineShapes '嵌入式插入的图片
If Shap.Type = wdInlineShapePicture Then
Shap.LockAspectRatio = msoFalse '不锁定纵横比
Shap.Width = CentimetersToPoints(10) '宽20CM
Shap.Height = CentimetersToPoints(7) '高7CM
End If
Next
End Sub

然后保存宏,关闭窗口。再运行宏即可批量调整图片大小。

  1. 方法二

F4(mac版CMD+Y),重复操作,图片数量不多的时候,批量修改

  1. 方法三

doc版本才能用,设置选择“选择多个对象”,并且需要将图片都改成“非嵌入”的图片。(不实用)

批量修改图片居中

1
查找替换窗口,查找框,输入:^g,替换框,格式:段落选择为居中(也可直接替换为”图片内容“样式)

批量图片后加回车

1
查找替换窗口,查找框,输入:^g,替换框,输入:^&^p

批量图片形状悬浮转嵌入

添加宏

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Sub 形状悬浮转嵌入()
Dim i As Integer
Dim sp As Shape
Dim allConv As Long

allConv = MsgBox("转换所有形状(如文本框、矩形)[是]" & vbCrLf & "仅转换图形[否]" & vbCrLf _
& "退出程序[取消]", vbInformation + vbYesNoCancel + vbDefaultButton2, "被转换类型")

If allConv = vbNo Then
For Each sp In ActiveDocument.Shapes
If sp.Type = msoPicture Then
sp.ConvertToInlineShape
i = i + 1
End If
Next
ElseIf allConv = vbYes Then
For Each sp In ActiveDocument.Shapes
sp.ConvertToInlineShape
i = i + 1
Next
Else
Exit Sub
End If

MsgBox Format(i, "完成,共转换了0个形状")
End Sub

批量改英文数字为times new roman

  1. 选择 编辑→替换 界面。在“查找内容”文本框中输入”[0-9a-zA-Z]”,表示查找所有数字及大小写字母。选择 高级→使用通配符,表示输入的查找内容为通配符,而不是普通文本。
  2. 选中“替换为”文本框。选择 高级→格式→字体→西文字体,修改为 Times New Roman。
l

将Roon引入我的听音系统的一些经验

系统迁移

我对之前的听音系统还是比较满意的,我并不是发烧友,当系统的音质能达到一定程度,剩下的就是音乐欣赏的事情了。
这个系统我用了很多年,也没打算做什么调整。
试用了Roon后,我比较喜欢它的和音乐管理,关联,搜索,流媒体音乐深度集成等特性,就购买了帐号,正式将Roon引入了我的听音系统,并归一化了所有的终端。

我之前听音系统的网络拓扑

我之前的听音系统终端并没有归一,音频的流动主要以DLNA为主,因为解码器的Bridge卡作为Render,内部通过I2S输入解码板,效果非常好,我又不想折腾各种USB,同轴,光纤的连接,线材不菲且完全不在我的知识范围内。

群晖NAS作为Media Server, 解码器,Mac软件,智能音箱作为Render,电脑、手机和Pad的软件作为Browser和Controller

img

引入Roon后听音系统网络拓扑

Roon的帐号挺贵的,加上我对原来的硬件还算满意,所以想最大限度的利用,思想就是用Roon Core管理音乐,同时将Roon的RAAT协议都转为DLNA,复用现有的设备。 电脑、手机、平板的客户端都统一到Roon Remote。

感谢philippe开发的SqueezeBox桥接到Upnp的软件squeeze2upnp,使得我复用原有DLNA系统的想法成为了可能,而且他对待用户的反馈是否友好,耐心解答并能很快做出修改。

img

安装Roon

  1. 在这个网站下载群晖NAS的套件 : https://roononnas.org/de/synology-2/
  2. 在共享文件夹中创建一个名字叫”RoonServer”的共享目录
    强烈建议使用SSD安装Roon,因为Roon服务器的随机访问速度很关键,我的NAS没有SSD安装槽位,只能通过USB 3.0的盒子接入SATA3固态硬盘。
    如果接入外置存储,将外置存储的名字改为RoonServer

img

  1. 选择手动安装套件,安装过程比较长

img

手机,PC, MAC, Pad的客户端可以参考官网安装:
https://roonlabs.com/downloads

以Windows为例,在PC上启动Roon,就回发现群晖NAS的Core,连接就可以使用

img

如何为Roon增加DLNA输出

Roon本身不支持输出,但是支持Squeezebox设备(就是LMS(Logitech Media Server)体系)

下图就是在Roon设置中打开对squeezbox的支持。

img

打开SqueezeBox设置

接下来的思路就是做一个桥,将Roon使用Squeezebox协议输出的音频转成DLNA的协议

使用这个软件实现:Squeeze2upnp,他的目的就是将DLNA设备变成SqueezeBox设备

img

软件github地址:https://github.com/philippe44/LMS-to-uPnP
里面有下载地址和提供支持的论坛地址

安装

安装非常简单,从github网址给出的下载网站下载最新的安装包解压即可。

!!!重要,需要安装1.49.8之后的版本,这之前的版本不支持Huawei Sound,我和作者squeeze2upnp的作者philippe反馈后并提供日志后,他经过修改,新出了版本用于支持Huawei Sound

安装包解压后有一个Bin目录,所有平台的可执行文件都在里面。

1
2
3
4
5
ls ./Bin
cc32160mt.dll libmad-0.dll libopusfile-0.dll pthreadBC2.dll squeeze2upnp-armv5te-static squeeze2upnp-bsd-x64-static squeeze2upnp-ppc-static squeeze2upnp-x86 ssleay32.dll
libeay32.dll libogg-0.dll libsoxr.dll squeeze2upnp-aarch64 squeeze2upnp-armv6hf squeeze2upnp-osx-multi squeeze2upnp-sparc squeeze2upnp-x86-64
libfaad2.dll libogg.dll libvorbis.dll squeeze2upnp-aarch64-static squeeze2upnp-armv6hf-static squeeze2upnp-osx-multi-static squeeze2upnp-sparc-static squeeze2upnp-x86-64-static
libFLAC.dll libopus-0.dll libvorbisfile.dll squeeze2upnp-armv5te squeeze2upnp-bsd-x64 squeeze2upnp-ppc squeeze2upnp-win.exe squeeze2upnp-x86-static

尽管Squeeze2upnp是LMS的一个插件,但是他并不依赖LMS,可以独立运行。解压后在Bin目录下后缀为_static的可执行程序都是独立执行程序

Squeeze2upnp支持Windows, OSX, or Linux x86/64, ARM and OSX

可以从可执行的程序名中看出哪个可执行程序对应什么平台。

例如树莓派,你可以选择 : squeeze2upnp-armv6hf-static
例如群晖X86 NAS, 你可以选择 : squeeze2upnp-x86-64-static

对于Linux,对应你平台的执行文件需要增加可执行属性,例如

1
chomd a+x squeeze2upnp-x86-64-static

以下描述以都以群晖NAS为例,其他的平台将命令中的可执行程序替换为对应平台的执行程序即可。

DLNA设备发现

对于第一次使用,或者希望重新创建一个配置文件,需要执行以下命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
./Bin/squeeze2upnp-x86-64-static -i config.xml
[22:18:38.897023] main:1756 Starting squeeze2upnp version: v1.49.6 (Feb 13 2021 @ 14:45:36)
[22:18:38.904985] main:1764

!!!!!!!!!!!!!!!!!! ERROR LOADING CONFIG FILE !!!!!!!!!!!!!!!!!!!!!

[22:18:38.943266] Start:1518 Binding to 192.168.1.100:49152 (http:0)
[22:18:39.363148] AddMRDevice:1405 [0xc41840]: adding renderer (HUAWEI Sound-0286)
[22:18:39.363354] AddMRDevice:1418 [0xc41840]: cannot get mac HUAWEI Sound-0286, creating fake fcceaf23
[22:18:39.371278] MasterHandler:1036 [0xc41840]: subscribe success
[22:18:39.395668] AddMRDevice:1405 [0xc43a58]: adding renderer (LIVINGROOM)
[22:18:39.395813] AddMRDevice:1418 [0xc43a58]: cannot get mac LIVINGROOM, creating fake 13a64ae6
[22:18:39.428824] MasterHandler:1036 [0xc43a58]: subscribe success
[22:19:00.344578] Stop:1540 stopping squeezelite devices ...
[22:19:00.344673] Stop:1544 terminate update thread ...
[22:19:00.344770] Stop:1549 terminate main thread ...
[22:19:00.344824] Stop:1553 stopping UPnP devices ...

等程序执行完,就会生成一个基础配置文件(config.xml,这个名字可以按照你的指定更换),里面包括默认配置和发现的你的局域网的DLNA设备。
注:你的DLNA Render设备需要打开才能被发现并生成配置。

其中…段是针对你所有设备的通用配置

每个发现的设备都有一个…段,你可以在段中设置和common中相同的参数,这个参数会针对这个设备覆盖common参数。

以我的设备为例,生成的设备配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<device>
<udn>uuid:b8aabe2db4df5481eb8b4f4cf3f302eac9a1539192127404166af840a41a0945</udn>
<name>HUAWEI Sound-0286</name>
<friendly_name>HUAWEI Sound-0286</friendly_name>
<mac>bb:bb:23:af:ce:fc</mac>
<enabled>1</enabled>
</device>
<device>
<udn>uuid:9166ce01-e4b5-4d56-8a1a-6a031b3b416b</udn>
<name>LIVINGROOM</name>
<friendly_name>LIVINGROOM</friendly_name>
<mac>bb:bb:e6:4a:a6:13</mac>
<enabled>1</enabled>
</device>

其中LIVINGROOM是我客厅的PS Audio PWD解码器,而HUAWEI Sound-0286则是卧室的Huawei智能音箱

接下来要对config.xml做一些简单的配置修改。例如, 在”common”段设置了设备最大支持48Khz采样率, 但是如果你的设备的最大采样率是192Khz,你可以在”device”段进行覆盖:

1
2
3
4
5
6
7
8
9
10
<common>
...
<sample_rate>48000</sample_rate>
...
</common>
<device>
...
<sample_rate>192000</sample_rate>
...
</device>

尽管根据测试华为智能音箱支持24bit/192Khz,但是华为给出的规格是24bit/96Khz,所以建议还是把Huawei Sound的采样率设置为96Khz

每个被发现的设备的”enable”属性都是1,表示会为这个设备生成一个桥设备,在Roon设置里面的音频设备列表展现, 如果你不想在Roon中使用这个设备,就将enable设置为0.

“device”段里面有一个有个属性是DLNA Render的标识,类似:

1
<mac>bb:bb:e6:4a:a6:13</mac>

这是这个设备的标识,后续发现设备时,设备mac地址和这个段相同,就不会添加新的设备,并使用这个”device”设置的属性进行处理。

!!!!!!最重要的一点: 将roon_mode属性设置为1,否则Roon下可能不工作

1
<roon_mode>1</roon_mode>

!!!!! **另外重要的一点,需要在Huawei Sound的”device”段中增加以下属性,否则会不能播放下一首,或者播放进度条不走

1
<accept_nexturi>1</accept_nexturi>

后续有新设备发现,squeeze2upnp会为新设备增加一个device段到配置文件。如果你不想自动增加新设备(可能会造成问题),可以将”common”段的”enabled”属性设置为0

运行

测试运行:

1
squeeze2upnp-x86-64-static -x config.xml

调试信息会输出在终端

正式运行

1
./Bin/squeeze2upnp-x86-64-static -z -x config.xml

要用-z参数在后台运行,否则即使使用Linux在后台运行,会占用一个CPU核的全部资源

然后需要开机启动就将上诉命令加入到/etc/rc.local 中即可

Roon配置

在Roon的“设置”->”音频”中启用桥设备,并给其命名,例如命名为Huawei Sound

img
打开SqueezeBox设置

对设备进行一些简单配置

img
打开SqueezeBox设置

在右下角的设备选择那里选择需要播放的设备,例如Huawei Sound音箱

img

打开SqueezeBox设置

然后打开设备的DSP选项

img

打开SqueezeBox设置

将Huawei Sound高于96k码率的音乐和DSD音乐进行转换

img

打开SqueezeBox设置

最终效果

这下,就可以在Roon系统中使用Huawei智能音箱了

img

打开SqueezeBox设置

使用docker运行squeeze2upnp

上面的squeeze2upnp安装过程依赖命令行,有点复杂,我简单做了一个docker镜像,在群晖上可以通过docker套件的界面来部署squeeze2upnp

首先需要在群晖上安装官方的docker套件:

img

Docker套件

打开Docker套件界面搜索镜像hjianhao/hjianhao-squeeze2upnp

img

搜索镜像

搜索到镜像后下载,并在映像界面启动容器

img

启动容器

选择高级设置

img

高级设置

在NAS上创建一个保存配置文件(config.xml)的目录,并挂接到容器的/config目录

img挂载配置目录

因为squeezeupnp涉及范围端口的使用,所以使用host网络

img

配置网络

应用后,一路“下一步”即可启动容器。

img

创建容器

第一次容器虽然启动了,但是功能是失效的,从上面的说明可以看到此时还没有配置文件(config.xml), 点击“详情”按钮弹出容器信息窗口,从“日志”标签中可以看到,加载配置文件失败

img

启动失败日志

此时我们进入“终端”标签,执行/squeeze2upnp/find.sh,用于发现DLNA Render设备,并生成配置文件

img

发现设备

执行完成后,使用“Ctrl+D”退出并停止容器运行。此时在你挂载的配置文件目录中就会有”Config.xml”配置文件。

img

配置文件

然后配置按前面对配置文件的描述修改配置文件,再重启容器即可。重启容器前最好将自动重启勾上

img

配置文件

启动成功后,只有一行日志

img

配置文件

通过桥连接解码器

除了上面提到的通过squeeze2upnp转换用DLNA连接解码器外,还有其他的连接解码器的方式:

  1. 也可以通过RAAT接入Roon Ready的解码器(前提是解码器支持Roon Ready)

img

这种方式比较简单,只要你的解码器支持Roon Ready且解码器和Roon core在同一个局域网网段,就可以相互发现,不用配置。因为简单且我的解码器不支持Roon Ready就不在这里赘述了

  1. Roon Core通过USB输出接入解码器,包括直接接入到解码器的USB输入,或者通过解码器界面转换为同轴和光纤输入解码器

img

  1. Roon Core通过RAAT协议接入Roon Bridge,然后Roon Bridge接入解码器,接入方式和上面说的Roon Core类似

img

这里主要介绍第三种,因为Bridge可以:

  1. 让Roon Core和解码器的位置摆放更为灵活,只要Bridge接近解码器即可。
  2. Bridge使用树莓派这种低功耗设备可以比Core更容易避免干扰,同时电源也更好处理。
  3. 多个Bridge可以让Roon接入和控制多个房间的音响设备。

因为我个人的主音响系统以DLNA为主,因为我的解码器出声最好的就是DLNA接入,其他数字接入都稍微差一些。所以树莓派做Bridge一个是做对比测试,另一个方面是作为我一个房间耳放的接入。这样我就可以用Roon控制在我的耳放上播放音乐。

树莓派做Roon Bridge是性价比非常高的Roon Bridge设备,功耗低,价格低,USB输出较好,I2S数字音频卡多,电源好处理。

在树莓派上装Roon Bridge

如果树莓派专用于Roon Bridge,则最好安装volumio,moode,RoPieee这类已经预先集成了Bridge软件的,比较简单。

因为我的树莓派还需要跑其他的软件,所以我是预装了系统再手工安装Roon Bridge。也比较简单

官方有Linux安装指导:https://help.roonlabs.com/portal/en/kb/articles/linux-install

要选对架构,对于树莓派4,如果是32位系统,用armv7hf, 我用的系统是64位的,所以使用armv8,安装只有下面三个指令

1
2
3
$ curl -O http://download.roonlabs.com/builds/roonbridge-installer-linuxarmv8.sh
$ chmod +x roonbridge-installer-linuxarmv8.sh
$ sudo ./roonbridge-installer-linuxarmv8.sh

取消安装在执行脚本加上参数uninstall,如:

1
sudo ./roonbridge-installer-linuxarmv8.sh uninstall

安装完成后会有安装结果提示,看是否安装成功。

重要提示: 安装完成后,可能会出现在Roon的关于里面可以看到桥,但是在音频里面看不到输出设备,应该是树莓派没有启动音频设备,需要修改config.txt文件,将dtparam=audio=on这一行的注释弃掉(删除前面的#号)

除了USB输出外,也可以给树莓派添加I2S音频扩展卡,通过同轴/平衡/光纤输出到解码器。

如果选用的是兼容HiFiBerry系列的显卡,可以参考:
https://www.hifiberry.com/docs/software/configuring-linux-3-18-x/

以我买的带平衡和光纤输出的兼容HiFiBerry Digi+的扩展版为例,修改/boot/config.txt

  1. 注释掉dtparam=audio=on
  2. 添加dtoverlay=hifiberry-dac

重启树莓派即可。然后用aplay指令可以看到I2S声卡

1
2
3
4
5
aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: sndrpihifiberry [snd_rpi_hifiberry_digi], device 0: HifiBerry Digi HiFi wm8804-spdif-0 [HifiBerry Digi HiFi wm8804-spdif-0]
Subdevices: 1/1
Subdevice #0: subdevice #0

通过VPN实现远程ROON

打通WAN连接服务器

  1. 首先要像运营商(如电信宽带)申请公网IP。
  2. 申请一个免费域名,同时将域名设置动态映射。这个每家域名提供商具体不一样,根据指导去配。
  3. 公网IP一般是动态的,会变化的,使用DDNS来做动态映射,以下以梅林固件的路由器为例:

img

服务器选择不同域名提供商,然后输入用户名等参数

搭建VPN服务器

以威联通QVPN为例

  1. 安装QVPN套件

  2. 启动L2TP/IPSec服务器

    其中10.2.0.0是VPN虚拟机局域网的网段

  3. 在路由器做端口映射,将以下端口流量导向NAS
    UDP:500
    UDP:4500
    UDP:1701

img

端口映射

远程机器连接VPN服务器

a. 用户名和密码是你创建VPN服务器的NAS用户用户名和密码
b. 共享密钥是第2步设置的预共享密钥

  1. 进行连接

img

在Windows上创建VPN连接

连接后会增加一个虚拟网卡

1
2
3
4
5
6
7
PPP 适配器 myhome:

连接特定的 DNS 后缀 . . . . . . . :
本地链接 IPv6 地址. . . . . . . . : fe80::ecdd:7a2a:228e:9b30%51
IPv4 地址 . . . . . . . . . . . . : 10.2.0.1
子网掩码 . . . . . . . . . . . . : 255.255.255.255
默认网关. . . . . . . . . . . . . : 0.0.0.0

同时你也可以访问NAS所在局域网的地址
例如

1
ping 192.168.1.100

此时你的Windows和NAS已经处在一个虚拟局域网下,启动远程计算机上的Roon就可以连接NAS上跑的Core了。

此时你看到Roon Core的IP地址是刚才建立的VPN的网段(Core机器上也有一个虚拟网卡)

img

同时也可以发现远程Windows机器上连接的音频设备用于播放

img

l

WSL2 中访问宿主机 Windows 的代理

最近疫情期间很多事情都得用代理连到学校内网去做,但是 WSL2 因为是通过虚拟机的方式实现,网络不再像 WSL1 一样与 Windows 共享,变成了一个新的网段,所以想使用宿主机的代理就比较麻烦了。

WSL 中获取宿主机 IP

WSL 每次启动的时候都会有不同的 IP 地址,所以并不能直接用静态的方式来设置代理。WSL2 会把 IP 写在 /etc/resolv.conf 中,因此可以用下面指令获得宿主机 IP 。

1
cat /etc/resolv.conf | grep nameserver | awk '{ print $2 }'

WSL2 自己的 IP 可以用下面指令得到。

1
hostname -I | awk '{print $1}'

设置代理

有了宿主机 IP 之后,就可以通过设置环境变量的方式设置代理了。这里端口需要自己填写,而且别忘了代理软件中设置允许来自局域网的连接

1
2
export http_proxy='http://<Windows IP>:<Port>' 
export https_proxy='http://<Windows IP>:<Port>'

这种设置方式每次重启终端都得重新设置一遍,而且 IP 还得自己手打,还是挺麻烦的,这种时候就得靠脚本了!

第 4 行 <PORT> 记得换成自己宿主机代理的端口!!!!!!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#!/bin/sh 
hostip=$(cat /etc/resolv.conf | grep nameserver | awk '{ print $2 }') wslip=$(hostname -I | awk '{print $1}')
port=<PORT>

PROXY_HTTP="http://${hostip}:${port}"
set_proxy(){
export http_proxy="${PROXY_HTTP}"
export HTTP_PROXY="${PROXY_HTTP}"
export https_proxy="${PROXY_HTTP}"
export HTTPS_proxy="${PROXY_HTTP}"
}

unset_proxy(){
unset http_proxy
unset HTTP_PROXY
unset https_proxy
unset HTTPS_PROXY
}

test_setting(){
echo "Host ip:" ${hostip}
echo "WSL ip:" ${wslip}
echo "Current proxy:" $https_proxy
}

if [ "$1" = "set" ]
then
set_proxy

elif [ "$1" = "unset" ]
then
unset_proxy

elif [ "$1" = "test" ]
then
test_setting
else
echo "Unsupported arguments."
fi

第 4 行 <PORT> 记得换成自己宿主机代理的端口!!!!!!

如果希望 git 也能通过代理,可以分别在 set_proxyunset_proxy 函数中加上如下命令

1
2
3
4
5
6
// 添加代理
git config --global http.proxy "${PROXY_HTTP}"
git config --global https.proxy "${PROXY_HTTP}"
// 移除代理
git config --global --unset http.proxy
git config --global --unset https.proxy

之后运行 . ./proxy.sh set 就可以自动设置代理了。unset 可以取消代理,test 可以查看代理状态,能够用来检查环境变量是否被正确修改。

运行的时候不要忘记之前的 .,或者使用 source ./proxy.sh set,只有这样才能够修改环境变量

直接运行例如 ./proxy.sh set 或者 sh proxy.sh set,这样会是运行在一个子 shell 中,对当前 shell 没有效果

另外可以在 ~/.bashrc 中选择性的加上下面两句话,记得将里面的路径修改成你放这个脚本的路径

1
alias proxy="source /path/to/proxy.sh" . /path/to/proxy.sh set 

第一句话可以为这个脚本设置别名 proxy,这样在任何路径下都可以通过 proxy 命令使用这个脚本了,之后在任何路径下,都可以随时都可以通过输入 proxy unset 来暂时取消代理。

第二句话就是在每次 shell 启动的时候运行该脚本实现自动设置代理,这样以后不用额外操作就默认设置好代理啦~

防火墙设置

如果前面完成后已经可以正常使用了,那么下面就不用管了。如果你代理已经设置正确了,尤其是已经允许来自局域网的访问,但是依旧无法正常访问,代理的软件的确也没收到请求,那么很可能是被 Windows 的防火墙给拦截了。

可以先尝试 ping 宿主机 ip 和 telnet 代理的端口,检查是否连通。如果无法连通,则多半是防火墙的问题。

img

可以尝试在控制面板的防火墙面板左侧“允许应用或功能通过防火墙”,即上述界面中,打上勾允许代理软件通过防火墙。

或者可以尝试在高级设置中,入站规则中新建一个相关规则,如果你不是很了解,可以允许任何程序的任何协议,远程 IP 为 172.16.0.0/12192.168.0.0/16 的入站请求。

l

linux 中为 cp 和 mv 命令添加进度条

GNU cpGNU mv 工具用于复制和移动文件和目录在GNU / Linux的操作系统。这两个应用程序中缺少的一个功能是它们不显示任何进度条。如果你复制一个大文件或目录,你真的不知道复制过程需要多长时间才能完成,或者复制的数据百分比。你不会看到当前正在复制哪个文件,或者已经复制了多少文件。感谢Advanced Copy,一个补丁Gnu Coreutils,我们现在可以在 Linux 中添加进度条cpmv命令,并在复制和/或移动大文件和目录时显示进度条。

Advanced Copy 是GNU cpGNU mv序的 mod 。它添加了一个进度条,并提供有关复制或移动文件和文件夹时发生的情况的一些信息。不仅是进度条,它还显示数据传输速率、估计剩余时间和当前正在复制的文件名。

安装高级复制补丁以在 Linux 中向 cp 和 mv 命令添加进度条

cp 和 mv 命令是GNU coreutils. 所以你需要GNU coreutils这里下载最新的。

1
2
3
4
5
6
7
8
> wget http://ftp.gnu.org/gnu/coreutils/coreutils-9.0.tar.xz
> tar xvJf coreutils-9.0.tar.xz
> cd coreutils-9.0/
> wget https://raw.githubusercontent.com/jarun/advcpmv/master/advcpmv-0.9-9.0.patch
> patch -p1 -i advcpmv-0.9-9.0.patch
> export FORCE_UNSAFE_CONFIGURE=1
> ./configure
> make

现在两个新的补丁的二进制文件即cpmv将在中创建coreutils-9.0/src的文件夹。只需将它们复制到你的 $PATH 中,如下所示:

1
2
$ cp ./src/cp /usr/local/bin/cpg
$ cp ./src/mv /usr/local/bin/mvg

cpgmvg命令有现在进度条的功能。每当你在复制或移动文件和目录时需要进度条时,只需添加-g如下标志:

1
$ cpg -g ../coreutils-9.0.tar.xz ./

或使用--progress-bar标志:

1
$ cpg --progress-bar ../coreutils-9.0.tar.xz ./

示例输出:

1
2
3
4
[root@rumenz.com ~]# cpg -g nifi-1.14.0-bin.tar.gz test/
Copying at 119.3 MiB/s (about 0h 0m 7s remaining)
nifi-1.14.0-bin.tar.gz 959.5 MiB / 1.3 GiB
[============================================> ] 71.0 %

在复制过程结束时,你将看到复制了多少文件、复制文件所用的时间以及每秒的数据传输速率。

1
1 files (  1.3 GiB) copied in 25.5 seconds ( 53.0 MiB/s).

要递归复制目录及其子目录,只需添加-R标志:

1
$ cpg -gR directory1/ directory2/

同样,要使用mv命令移动文件,请运行:

1
$ mvg -g nifi-1.14.0-bin.tar.gz test/

或者,使用--progress-bar标志:

1
$ mvg --progress-bar nifi-1.14.0-bin.tar.gz test/

要使用mv命令移动目录,请使用:

1
$ mvg -g directory1/ directory2/

你还可以创建别名。编辑~/.bashrc文件:

在最后添加以下几行:

1
2
alias cp='/usr/local/bin/cpg -gR'
alias mv='/usr/local/bin/mvg -g'

现在运行以下命令使更改生效:

1
$ source ~/.bashrc

从现在开始,你可以只使用没有(或)标志的cpmv命令。-g --progress-bar请注意,原始程序不会被覆盖。你仍然可以随时通过/usr/bin/cp 或 呼叫他们 /usr/bin/mv

如果你经常复制或移动大量大文件和目录,推荐向cpmv命令添加进度条功能。

l

zsh必备插件

首先是 oh-my-zsh 自带的 alias 插件,这些东西能让你在终端少打很多字:

1. git

定义了有关 git 的 alias。常用的有

  • gaa = git add –all
  • gcmsg = git commit -m
  • ga = git add
  • gst = git status
  • gp = git push

2. tmux

定义了有关 tmux 的 alias。常用的有

  • tl = tmux list-sessions
  • tkss = tmux kill-session -t
  • ta = tmux attach -t
  • ts = tmux new-session -s

然后是 oh-my-zsh 自带的,一些提供实用命令的插件。

1. extract

提供一个 extract 命令,以及它的别名 x。功能是:一!键!解!压!你知道tar的四种写法吗?我也不知道,所以我装了这个。从今以后 tar, gz, zip, rar 全部使用 extract 命令解压,再也不用天天查 cheatsheet 啦!

2. rand-quote

提供一条 quote 命令,显示随机名言。和fortune的作用差不多,但是我感觉fortune上面大多是冷笑话,还是quote的内容比较有意思。

当然这种东西很少有人会主动去按的。所以你可以在你的zshrc里面的最后一行加上quote,实现每次打开shell显示一条名言的效果~

再进一步,安装一个cowsay,把quote | cowsay放到zshrc的最后一行。于是每次打开终端你就可以看到一头牛对你说:

imgimg

3. themes

提供一条 theme 命令,用来随时手动切换主题。在想要尝试各种主题的时候很实用,不需要一直改 zshrc 然后重载。

4. gitignore

提供一条 gi 命令,用来查询 gitignore 模板。比如你新建了一个 python 项目,就可以用

1
gi python > .gitignore 

来生成一份 gitignore 文件。

5. cp

提供一个 cpv 命令,这个命令使用 rsync 实现带进度条的复制功能。

6. zsh_reload

提供一个 src 命令,重载 zsh。对于经常折腾 zshrc 的我,这条命令非常实用。

7. git-open

提供一个 git-open 命令,在浏览器中打开当前所在 git 项目的远程仓库地址。

8. z

提供一个 z 命令,在常用目录之间跳转。类似 autojump,但是不需要额外安装软件。


接着是 oh-my-zsh 自带的,其他一些功能强大的实用工具。

1. vi-mode

vim输入模式,非常强大,不用多说。

2. per-directory-history

开启之后在一个目录下只能查询到这个目录下的历史命令。按 Ctrl+g 开启/关闭。对我来说很实用,但是不一定所有人都喜欢,可以考虑一下自己是否真的需要。

3. command-not-found

当你输入一条不存在的命令时,会自动查询这条命令可以如何获得。

4. safe-paste

像我这样的懒人,经常会从网上复制各种脚本。但是复制的命令有可能并不就是我要的,可能还需要改一改。但是往往我复制了几行脚本,粘贴到 zsh 里,就发现它直接运行了。这真是非常危险。

这个插件的功能就是:当你往 zsh 粘贴脚本时,它不会被立刻运行。给了我这种懒人修改别人脚本的机会。

5. colored-man-pages

给你带颜色的 man 命令。

6. sudo

apt 忘了加 sudo?开启这个插件,双击 Esc,zsh 会把上一条命令加上 sudo 给你。

一般人会在 zsh 中绑定 history-search-backward 与 histor-search-forward 两个功能。

1
2
bindkey '^P' history-search-backward
bindkey '^N' history-search-forward

这样子,就可以在输入一个命令,比如 git 之后,按 Ctrl-P 与 Ctrl-N 在以 git为前缀的历史记录中浏览,非常方便。

但是这个做法有一个问题,就是这个功能只考虑输入的第一个单词。也就是说,如果之前输入了 git status, git commit, git push 等等命令,那么我输入 “git s” 再 Ctrl-P,并不会锁定到 “git status”, 而是会在所有以 git 开头的历史命令中循环。

这个插件的功能就是实现了一对更好用的 history-search-backward 与 histor-search-forward ,解决了上面所说的问题。开启之后,需要绑定按键:

1
2
bindkey '^P' history-substring-search-up
bindkey '^N' history-substring-search-down

这样子就可以以自己输入的所有内容为前缀,进行历史查找了。


然后下面是需要单独安装的:

1. zplug

zsh 的插件管理器,类似 vim 的 vundle,把你需要的所有插件写到 zshrc 里,然后运行 zplug install 就可以安装这些插件。就像这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
if [[ -f ~/.zplug/init.zsh ]] {
source ~/.zplug/init.zsh

zplug "zsh-users/zsh-syntax-highlighting"
zplug "zsh-users/zsh-autosuggestions"
zplug "supercrabtree/k"
zplug "denisidoro/navi"
zplug "MichaelAquilina/zsh-you-should-use"
zplug "changyuheng/zsh-interactive-cd"
zplug "SleepyBag/zsh-confer"

zplug "Powerlevel9k/powerlevel9k", from:github, as:theme, if:"[[ $ZSH_THEME_STYLE == 9k ]]"
zplug "denysdovhan/spaceship-prompt", use:spaceship.zsh-theme, from:github, as:theme, if:"[[ $ZSH_THEME_STYLE == spaceship ]]"
zplug "caiogondim/bullet-train.zsh", use:bullet-train.zsh-theme, from:github, as:theme, if:"[[ $ZSH_THEME_STYLE == bullet ]]"
zplug "skylerlee/zeta-zsh-theme", from:github, as:theme, if:"[[ $ZSH_THEME_STYLE == zeta ]]"

if ! zplug check --verbose; then
echo 'Run "zplug install" to install'
fi
# Then, source plugins and add commands to $PATH
zplug load
}

这个工具不仅可以用来装 zsh 插件,事实上它可以用来自动安装任何你认为有必要的插件、主题、脚本甚至二进制程序。但是对于非 zsh 插件的程序,在安装之前要先看看 zplug 的文档,搞清楚如何安装。

2. zsh-syntax-highlighting

shell 命令的代码高亮。你没有理由拒绝高亮。

3. zsh-autosuggestions

在输入命令的过程中根据你的历史记录显示你可能想要输入的命令,按 tab 补全。

不过 tab 键似乎与 zsh 的补全有冲突,所以我改成了 ctrl-y 直接运行命令,关于如何修改快捷键,项目主页上也有写。

l

在校外时利用Easy Connect连接西工大校园内网(FTP、内网资源)简易教程

1.使用场景

在校外或者电脑未连接校园网的情况下,想访问内网信息。

2.所需工具

能联网的电脑

3.使用步骤

  1. 浏览器中输入https://vpn.nwpu.edu.cn,跳转至以下页面,点击“下载客户端”。

  1. 客户端安装完成后,桌面上会创建如下快捷方式,双击即可。

得到以下页面

  1. 输入图片中的网址,西工大的为https://vpn.nwpu.edu.cnµ,其他高校应该在自己学校官网可以查到对应的vpn地址。点击。跳转至以下页面:

  2. 输入用户名及密码,点击登录即可。(西工大的用户名密码即为登录翱翔门户的用户名密码,其他高校可到自家官网查询要求)登陆成功,右下角会显示登陆成功的提示信息。

  3. 获取资源
    3.5.1双击桌面Easy Connect 快捷方式即可得到校内资源的访问。

  4. FTP资源
    和在校内一样,在我的电脑的地址栏里输入对应得ftp地址,就可以成功跳转。

l

glance内存分析工具使用

glances 是一款用于 Linux、BSD 的开源命令行系统监视工具,它使用 Python 语言开发,能够监视 CPU、负载、内存、磁盘 I/O、网络流量、文件系统、系统温度等信息。本文介绍 glances 的使用方法和技巧,帮助 Linux 系统管理员了解掌握服务器性能。

前言

glances 可以为 Unix 和 Linux 性能专家提供监视和分析性能数据的功能,其中包括:

  • CPU 使用率
  • 内存使用情况
  • 内核统计信息和运行队列信息
  • 磁盘 I/O 速度、传输和读/写比率
  • 文件系统中的可用空间
  • 磁盘适配器
  • 网络 I/O 速度、传输和读/写比率
  • 页面空间和页面速度
  • 消耗资源最多的进程
  • 计算机信息和系统资源

glances 工具可以在用户的终端上实时显示重要的系统信息,并动态地对其进行更新。这个高效的工具可以工作于任何终端屏幕。另外它并不会消耗大量的 CPU 资源,通常低于百分之二。glances 在屏幕上对数据进行显示,并且每隔两秒钟对其进行更新。您也可以自己将这个时间间隔更改为更长或更短的数值。glances 工具还可以将相同的数据捕获到一个文件,便于以后对报告进行分析和绘制图形。输出文件可以是电子表格的格式 (.csv) 或者 html 格式。

两种方法安装 glances

通 常可以有两种方法安装 glances。第一种是通过编译源代码的方式,这种方法比较复杂另外可能会遇到软件包依赖性问题。还有一种是使用特定的软件包管理工具来安装 glances,这种方法比较简单。本文使用后者,需要说明的是在 CentOS 特定的软件包管理工具来安装。glances 要首先配置 EPEL repo,然后使用 pip 工具安装 glances。

pip 软件包简介

通 常 Linux 系统管理员有两种方式来安装一个 Python 的软件包:一种是通过系统的包管理工具(如 apt-get)从系统的软件仓库里安装,一种是通过 Python 自己的包管理工具(如 easy_install 或者 pip)从 Python Cheese Shop 中下载安装。笔者推荐使用 pip。pip 是一个可以代替 easy_install 的安装和管理 Python 软件包的工具,是一个安装 Python 库很方便的工具,功能类似 YUM。注意 CentOS 和 Fedora 下安装 Python-pip 后,关键字不是 pip 而是 pip-Python。

首先配置 EPEL repo

如 果既想获得 RHEL 的高质量、高性能、高可靠性,又需要方便易用(关键是免费)的软件包更新功能,那么 Fedora Project 推出的 EPEL(Extra Packages for Enterprise Linux ,http://fedoraproject.org/wiki/EPEL)正好适合你。它是由 Fedora 社区打造,为 RHEL 及衍生发行版如 CentOS、Scientific Linux 等提供高质量软件包的项目。装上了 EPEL,就像在 Fedora 上一样,可以通过 yum install package-name,随意安装软件。安装使用 EPEL 非常简单:

1
2
3
4
5
6
7
8
9
10
#wget http://ftp.riken.jp/Linux/fedora/epel/RPM-GPG-KEY-EPEL-6
#rpm --import RPM-GPG-KEY-EPEL-6
#rm -f RPM-GPG-KEY-EPEL-6
#vi /etc/yum.repos.d/epel.repo
# create new
[epel]
name=EPEL RPM Repository for Red Hat Enterprise Linux
baseurl=http://ftp.riken.jp/Linux/fedora/epel/6/$basearch/
gpgcheck=1
enabled=0

使用 pip 安装 glances

这里介绍一下安装过程:首先使用 YUM 安装 pip 工具,然后使用 pip 工具安装 glances 和用来显示系统温度的相关软件。

1
2
#yum --enablerepo=epel install Python Python-pip Python-devel gcc
# pip-Python install glances

安装 lm_sensors 软件

lm_sensors 的软件可以帮助我们来监控主板、CPU 的工作电压、风扇转速、温度等数据。这些数据我们通常在主板的 BIOS 也可以看到。当我们可以在机器运行的时候通过 lm_sensors 随时来监测着 CPU 的温度变化,可以预防呵保护因为 CPU 过热而会烧掉。lm_sensors 软件监测到的数据可以被 glances 调用并且显示 。

1
2
#yum install lm_sensor
# pip-Python install PySensors

glances 使用方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
glances 是一个命令行工具包括如下命令选项:
-b:显示网络连接速度 Byte/ 秒
-B @IP|host :绑定服务器端 IP 地址或者主机名称
-c @IP|host:连接 glances 服务器端
-C file:设置配置文件默认是 /etc/glances/glances.conf
-d:关闭磁盘 I/O 模块
-e:显示传感器温度
-f file:设置输出文件(格式是 HTML 或者 CSV)
-m:关闭挂载的磁盘模块
-n:关闭网络模块
-p PORT:设置运行端口默认是 61209
-P password:设置客户端 / 服务器密码
-s:设置 glances 运行模式为服务器
-t sec:设置屏幕刷新的时间间隔,单位为秒,默认值为 2 秒,数值许可范围:1~32767
-h : 显示帮助信息
-v : 显示版本信息

glances 工作界面如图 1
图 1.glances 工作界面

glances

glances 工作界面的说明 :

在图 1 的上部是 CPU 、Load(负载)、Mem(内存使用)、 Swap(交换分区)的使用情况。在图 1 的中上部是网络接口、Processes(进程)的使用情况。通常包括如下字段:

1
2
3
4
5
6
7
8
9
10
11
12
13
VIRT: 虚拟内存大小
RES: 进程占用的物理内存值
%CPU:该进程占用的 CPU 使用率

%MEM:该进程占用的物理内存和总内存的百分比

PID: 进程 ID 号
USER: 进程所有者的用户名
TIME+: 该进程启动后占用的总的 CPU 时间
IO_R 和 IO_W: 进程的读写 I/O 速率
NAME: 进程名称
NI: 进程优先级
S: 进程状态,其中 S 表示休眠,R 表示正在运行,Z 表示僵死状态。

在图 1 的中下部是传感器检测到的 CPU 温度。 在图 1 的下部是磁盘 I/O 的使用情况。 另外 glances 可以使用交互式的方式运行该工具,用户可以使用如下快捷键:

1
2
3
4
5
6
7
8
9
10
11
12
h : 显示帮助信息
q : 离开程序退出
c :按照 CPU 实时负载对系统进程进行排序
m :按照内存使用状况对系统进程排序
i:按照 I/O 使用状况对系统进程排序
p: 按照进程名称排序
d : 显示磁盘读写状况
w : 删除日志文件
l :显示日志
s: 显示传感器信息
f : 显示系统信息
1 :轮流显示每个 CPU 内核的使用情况(次选项仅仅使用在多核 CPU 系统)

glances 的高级应用

glances 的结果输出方法

让 glances 输出 HTML 格式文件,首先安装相关软件包

1
2
# pip-Python install Jinja2
# glances -o HTML -f /var/www/html

下面可以使用 Firefox 浏览器输入网址: http://localhost/glances.html,结果如图 2。
图 2.输出 HTML 格式文件

[glances

输出 csv 格式

该文件采用逗号分隔值(CSV)的格式,并且可以将其直接导入到电子表格中。

1
# glances -o CSV -f /home/cjh/glances.csv

下面使用 libreoffice 的 calc 工具打开 csv 格式文件(如图 3)

1
#libreoffice --calc %U /tmp/glances.csv

图 3.使用 libreoffice 的 calc 工具打开 csv 格式文件

glances

glances 服务器 / 客户端工作方式

glances 支持服务器/客户端工作方式,可以实现远程监控。首先假设

服务器 IP 地址:10.0.2.14

客户端 IP 地址:10.0.2.15

确保二者都已经安装好 glances 软件包。

首先在服务器端启动;

1
2
# glances -s -B 10.0.2.15
glances server is running on 10.0.2.15:61209

可以看到 glances 使用的端口号是 61209,所以用户需要确保防火墙打开这个端口。

下面在客户端使用如下命令连接服务器如图 4:

1
# glances -c 10.0.2.15

图 4.客户端连接服务器

[glances

注意图 4 的左下角显示“Connected to 10.0.2.15”>表示客户端已经连接服务器成功。

通过 glances 输出颜色了解系统性能
图 5.是 glances 的一个输出界面

glances

绿色表示性能良好,无需做任何额外工作;(此时 CPU 使用率、磁盘空间使用率和内存使用率低于 50%,系统负载低于 0.7)。

蓝色表示系统性能有一些小问题,用户应当开始关注系统性能;(此时 CPU 使用率、磁盘空间使用率和内存使用率在 50%-70% 之间,系统负载在 0.7-1 之间)。

品红表示性能报警,应当采取措施比如备份数据;(此时 CPU 使用率、磁盘空间使用率和内存使用率在 70%-90% 之间,,系统负载在 1-5 之间)。

红色表示性能问题严重,可能宕机;(此时 CPU 使用率、磁盘空间使用率和内存使用率在大于 90%,系统负载大于 5)。

l

命令行的艺术

Join the chat at https://gitter.im/jlevy/the-art-of-command-line

熟练使用命令行是一种常常被忽视,或被认为难以掌握的技能,但实际上,它会提高你作为工程师的灵活性以及生产力。本文是一份我在 Linux 上工作时,发现的一些命令行使用技巧的摘要。有些技巧非常基础,而另一些则相当复杂,甚至晦涩难懂。这篇文章并不长,但当你能够熟练掌握这里列出的所有技巧时,你就学会了很多关于命令行的东西了。

这篇文章是许多作者和译者共同的成果。这里的部分内容首次出现Quora,但已经迁移到了 Github,并由众多高手做出了许多改进。如果你在本文中发现了错误或者存在可以改善的地方,请贡献你的一份力量

前言

涵盖范围:

  • 这篇文章不仅能帮助刚接触命令行的新手,而且对具有经验的人也大有裨益。本文致力于做到覆盖面广(涉及所有重要的内容),具体(给出具体的最常用的例子),以及简洁(避免冗余的内容,或是可以在其他地方轻松查到的细枝末节)。在特定应用场景下,本文的内容属于基本功或者能帮助您节约大量的时间。
  • 本文主要为 Linux 所写,但在仅限 OS X 系统章节和仅限 Windows 系统章节中也包含有对应操作系统的内容。除去这两个章节外,其它的内容大部分均可在其他类 Unix 系统或 OS X,甚至 Cygwin 中得到应用。
  • 本文主要关注于交互式 Bash,但也有很多技巧可以应用于其他 shell 和 Bash 脚本当中。
  • 除去“标准的”Unix 命令,本文还包括了一些依赖于特定软件包的命令(前提是它们具有足够的价值)。

注意事项:

  • 为了能在一页内展示尽量多的东西,一些具体的信息可以在引用的页面中找到。我们相信机智的你知道如何使用 Google 或者其他搜索引擎来查阅到更多的详细信息。文中部分命令需要您使用 apt-getyumdnfpacmanpipbrew(以及其它合适的包管理器)来安装依赖的程序。
  • 遇到问题的话,请尝试使用 Explainshell 去获取相关命令、参数、管道等内容的解释。

基础

  • 学习 Bash 的基础知识。具体地,在命令行中输入 man bash 并至少全文浏览一遍; 它理解起来很简单并且不冗长。其他的 shell 可能很好用,但 Bash 的功能已经足够强大并且到几乎总是可用的( 如果你学习 zsh,fish 或其他的 shell 的话,在你自己的设备上会显得很方便,但过度依赖这些功能会给您带来不便,例如当你需要在服务器上工作时)。

  • 熟悉至少一个基于文本的编辑器。通常而言 Vim (vi) 会是你最好的选择,毕竟在终端中编辑文本时 Vim 是最好用的工具(甚至大部分情况下 Vim 要比 Emacs、大型 IDE 或是炫酷的编辑器更好用)。

  • 学会如何使用 man 命令去阅读文档。学会使用 apropos 去查找文档。知道有些命令并不对应可执行文件,而是在 Bash 内置好的,此时可以使用 helphelp -d 命令获取帮助信息。你可以用 type 命令 来判断这个命令到底是可执行文件、shell 内置命令还是别名。

  • 学会使用 >< 来重定向输出和输入,学会使用 | 来重定向管道。明白 > 会覆盖了输出文件而 >> 是在文件末添加。了解标准输出 stdout 和标准错误 stderr。

  • 学会使用通配符 * (或许再算上 ?[]) 和引用以及引用中 '" 的区别(后文中有一些具体的例子)。

  • 熟悉 Bash 中的任务管理工具:&ctrl-zctrl-cjobsfgbgkill 等。

  • 学会使用 ssh 进行远程命令行登录,最好知道如何使用 ssh-agentssh-add 等命令来实现基础的无密码认证登录。

  • 学会基本的文件管理工具:lsls -l (了解 ls -l 中每一列代表的意义),lessheadtailtail -f (甚至 less +F),lnln -s (了解硬链接与软链接的区别),chownchmoddu (硬盘使用情况概述:du -hs *)。 关于文件系统的管理,学习 dfmountfdiskmkfslsblk。知道 inode 是什么(与 ls -idf -i 等命令相关)。

  • 学习基本的网络管理工具:ipifconfigdig

  • 学习并使用一种版本控制管理系统,例如 git

  • 熟悉正则表达式,学会使用 grepegrep,它们的参数中 -i-o-v-A-B-C 这些是很常用并值得认真学习的。

  • 学会使用 apt-getyumdnfpacman (具体使用哪个取决于你使用的 Linux 发行版)来查找和安装软件包。并确保你的环境中有 pip 来安装基于 Python 的命令行工具 (接下来提到的部分程序使用 pip 来安装会很方便)。

日常使用

  • 在 Bash 中,可以通过按 Tab 键实现自动补全参数,使用 ctrl-r 搜索命令行历史记录(按下按键之后,输入关键字便可以搜索,重复按下 ctrl-r 会向后查找匹配项,按下 Enter 键会执行当前匹配的命令,而按下右方向键会将匹配项放入当前行中,不会直接执行,以便做出修改)。

  • 在 Bash 中,可以按下 ctrl-w 删除你键入的最后一个单词,ctrl-u 可以删除行内光标所在位置之前的内容,alt-balt-f 可以以单词为单位移动光标,ctrl-a 可以将光标移至行首,ctrl-e 可以将光标移至行尾,ctrl-k 可以删除光标至行尾的所有内容,ctrl-l 可以清屏。键入 man readline 可以查看 Bash 中的默认快捷键。内容有很多,例如 alt-. 循环地移向前一个参数,而 alt-* 可以展开通配符。

  • 你喜欢的话,可以执行 set -o vi 来使用 vi 风格的快捷键,而执行 set -o emacs 可以把它改回来。

  • 为了便于编辑长命令,在设置你的默认编辑器后(例如 export EDITOR=vim),ctrl-x ctrl-e 会打开一个编辑器来编辑当前输入的命令。在 vi 风格下快捷键则是 escape-v

  • 键入 history 查看命令行历史记录,再用 !nn 是命令编号)就可以再次执行。其中有许多缩写,最有用的大概就是 !$, 它用于指代上次键入的参数,而 !! 可以指代上次键入的命令了(参考 man 页面中的“HISTORY EXPANSION”)。不过这些功能,你也可以通过快捷键 ctrl-ralt-. 来实现。

  • cd 命令可以切换工作路径,输入 cd ~ 可以进入 home 目录。要访问你的 home 目录中的文件,可以使用前缀 ~(例如 ~/.bashrc)。在 sh 脚本里则用环境变量 $HOME 指代 home 目录的路径。

  • 回到前一个工作路径:cd -

  • 如果你输入命令的时候中途改了主意,按下 alt-# 在行首添加 # 把它当做注释再按下回车执行(或者依次按下 ctrl-a, **#**, enter)。这样做的话,之后借助命令行历史记录,你可以很方便恢复你刚才输入到一半的命令。

  • 使用 xargs ( 或 parallel)。他们非常给力。注意到你可以控制每行参数个数(-L)和最大并行数(-P)。如果你不确定它们是否会按你想的那样工作,先使用 xargs echo 查看一下。此外,使用 -I{} 会很方便。例如:

    1
    2
    find . -name '*.py' | xargs grep some_function
    cat hosts | xargs -I{} ssh root@{} hostname
  • pstree -p 以一种优雅的方式展示进程树。

  • 使用 pgreppkill 根据名字查找进程或发送信号(-f 参数通常有用)。

  • 了解你可以发往进程的信号的种类。比如,使用 kill -STOP [pid] 停止一个进程。使用 man 7 signal 查看详细列表。

  • 使用 nohupdisown 使一个后台进程持续运行。

  • 使用 netstat -lntpss -plat 检查哪些进程在监听端口(默认是检查 TCP 端口; 添加参数 -u 则检查 UDP 端口)或者 lsof -iTCP -sTCP:LISTEN -P -n (这也可以在 OS X 上运行)。

  • lsof 来查看开启的套接字和文件。

  • 使用 uptimew 来查看系统已经运行多长时间。

  • 使用 alias 来创建常用命令的快捷形式。例如:alias ll='ls -latr' 创建了一个新的命令别名 ll

  • 可以把别名、shell 选项和常用函数保存在 ~/.bashrc,具体看下这篇文章。这样做的话你就可以在所有 shell 会话中使用你的设定。

  • 把环境变量的设定以及登陆时要执行的命令保存在 ~/.bash_profile。而对于从图形界面启动的 shell 和 cron 启动的 shell,则需要单独配置文件。

  • 要想在几台电脑中同步你的配置文件(例如 .bashrc.bash_profile),可以借助 Git。

  • 当变量和文件名中包含空格的时候要格外小心。Bash 变量要用引号括起来,比如 "$FOO"。尽量使用 -0-print0 选项以便用 NULL 来分隔文件名,例如 locate -0 pattern | xargs -0 ls -alfind / -print0 -type d | xargs -0 ls -al。如果 for 循环中循环访问的文件名含有空字符(空格、tab 等字符),只需用 IFS=$'\n' 把内部字段分隔符设为换行符。

  • 在 Bash 脚本中,使用 set -x 去调试输出(或者使用它的变体 set -v,它会记录原始输入,包括多余的参数和注释)。尽可能地使用严格模式:使用 set -e 令脚本在发生错误时退出而不是继续运行;使用 set -u 来检查是否使用了未赋值的变量;试试 set -o pipefail,它可以监测管道中的错误。当牵扯到很多脚本时,使用 trap 来检测 ERR 和 EXIT。一个好的习惯是在脚本文件开头这样写,这会使它能够检测一些错误,并在错误发生时中断程序并输出信息:

    1
    2
    set -euo pipefail
    trap "echo 'error: Script failed: see failed command above'" ERR
  • 在 Bash 脚本中,子 shell(使用括号 (...))是一种组织参数的便捷方式。一个常见的例子是临时地移动工作路径,代码如下:

    1
    2
    3
    # do something in current dir
    (cd /some/other/dir && other-command)
    # continue in original dir
  • 在 Bash 中,变量有许多的扩展方式。${name:?error message} 用于检查变量是否存在。此外,当 Bash 脚本只需要一个参数时,可以使用这样的代码 input_file=${1:?usage: $0 input_file}。在变量为空时使用默认值:${name:-default}。如果你要在之前的例子中再加一个(可选的)参数,可以使用类似这样的代码 output_file=${2:-logfile},如果省略了 $2,它的值就为空,于是 output_file 就会被设为 logfile。数学表达式:i=$(( (i + 1) % 5 ))。序列:{1..10}。截断字符串:${var%suffix}${var#prefix}。例如,假设 var=foo.pdf,那么 echo ${var%.pdf}.txt 将输出 foo.txt

  • 使用括号扩展({})来减少输入相似文本,并自动化文本组合。这在某些情况下会很有用,例如 mv foo.{txt,pdf} some-dir(同时移动两个文件),cp somefile{,.bak}(会被扩展成 cp somefile somefile.bak)或者 mkdir -p test-{a,b,c}/subtest-{1,2,3}(会被扩展成所有可能的组合,并创建一个目录树)。

  • 通过使用 <(some command) 可以将输出视为文件。例如,对比本地文件 /etc/hosts 和一个远程文件:

    1
    diff /etc/hosts <(ssh somehost cat /etc/hosts)
  • 编写脚本时,你可能会想要把代码都放在大括号里。缺少右括号的话,代码就会因为语法错误而无法执行。如果你的脚本是要放在网上分享供他人使用的,这样的写法就体现出它的好处了,因为这样可以防止下载不完全代码被执行。

    1
    2
    3
    {
    # 在这里写代码
    }
  • 了解 Bash 中的“here documents”,例如 cat <<EOF ...

  • 在 Bash 中,同时重定向标准输出和标准错误:some-command >logfile 2>&1 或者 some-command &>logfile。通常,为了保证命令不会在标准输入里残留一个未关闭的文件句柄捆绑在你当前所在的终端上,在命令后添加 </dev/null 是一个好习惯。

  • 使用 man ascii 查看具有十六进制和十进制值的ASCII表。man unicodeman utf-8,以及 man latin1 有助于你去了解通用的编码信息。

  • 使用 screentmux 来使用多份屏幕,当你在使用 ssh 时(保存 session 信息)将尤为有用。而 byobu 可以为它们提供更多的信息和易用的管理工具。另一个轻量级的 session 持久化解决方案是 dtach

  • ssh 中,了解如何使用 -L-D(偶尔需要用 -R)开启隧道是非常有用的,比如当你需要从一台远程服务器上访问 web 页面。

  • 对 ssh 设置做一些小优化可能是很有用的,例如这个 ~/.ssh/config 文件包含了防止特定网络环境下连接断开、压缩数据、多通道等选项:

    1
    2
    3
    4
    5
    6
    7
    TCPKeepAlive=yes
    ServerAliveInterval=15
    ServerAliveCountMax=6
    Compression=yes
    ControlMaster auto
    ControlPath /tmp/%r@%h:%p
    ControlPersist yes
  • 一些其他的关于 ssh 的选项是与安全相关的,应当小心翼翼的使用。例如你应当只能在可信任的网络中启用 StrictHostKeyChecking=noForwardAgent=yes

  • 考虑使用 mosh 作为 ssh 的替代品,它使用 UDP 协议。它可以避免连接被中断并且对带宽需求更小,但它需要在服务端做相应的配置。

  • 获取八进制形式的文件访问权限(修改系统设置时通常需要,但 ls 的功能不那么好用并且通常会搞砸),可以使用类似如下的代码:

    1
    stat -c '%A %a %n' /etc/timezone
  • 使用 percol 或者 fzf 可以交互式地从另一个命令输出中选取值。

  • 使用 fppPathPicker)可以与基于另一个命令(例如 git)输出的文件交互。

  • 将 web 服务器上当前目录下所有的文件(以及子目录)暴露给你所处网络的所有用户,使用:
    python -m SimpleHTTPServer 7777 (使用端口 7777 和 Python 2)或python -m http.server 7777 (使用端口 7777 和 Python 3)。

  • 以其他用户的身份执行命令,使用 sudo。默认以 root 用户的身份执行;使用 -u 来指定其他用户。使用 -i 来以该用户登录(需要输入_你自己的_密码)。

  • 将 shell 切换为其他用户,使用 su username 或者 sudo - username。加入 - 会使得切换后的环境与使用该用户登录后的环境相同。省略用户名则默认为 root。切换到哪个用户,就需要输入_哪个用户的_密码。

  • 了解命令行的 128K 限制。使用通配符匹配大量文件名时,常会遇到“Argument list too long”的错误信息。(这种情况下换用 findxargs 通常可以解决。)

  • 当你需要一个基本的计算器时,可以使用 python 解释器(当然你要用 python 的时候也是这样)。例如:

    1
    2
    >>> 2+3
    5

文件及数据处理

  • 在当前目录下通过文件名查找一个文件,使用类似于这样的命令:find . -iname '*something*'。在所有路径下通过文件名查找文件,使用 locate something (但注意到 updatedb 可能没有对最近新建的文件建立索引,所以你可能无法定位到这些未被索引的文件)。

  • 使用 ag 在源代码或数据文件里检索(grep -r 同样可以做到,但相比之下 ag 更加先进)。

  • 将 HTML 转为文本:lynx -dump -stdin

  • Markdown,HTML,以及所有文档格式之间的转换,试试 pandoc

  • 当你要处理棘手的 XML 时候,xmlstarlet 算是上古时代流传下来的神器。

  • 使用 jq 处理 JSON。

  • 使用 shyaml 处理 YAML。

  • 要处理 Excel 或 CSV 文件的话,csvkit 提供了 in2csvcsvcutcsvjoincsvgrep 等方便易用的工具。

  • 当你要处理 Amazon S3 相关的工作的时候,s3cmd 是一个很方便的工具而 s4cmd 的效率更高。Amazon 官方提供的 aws 以及 saws 是其他 AWS 相关工作的基础,值得学习。

  • 了解如何使用 sortuniq,包括 uniq 的 -u 参数和 -d 参数,具体内容在后文单行脚本节中。另外可以了解一下 comm

  • 了解如何使用 cutpastejoin 来更改文件。很多人都会使用 cut,但遗忘了 join

  • 了解如何运用 wc 去计算新行数(-l),字符数(-m),单词数(-w)以及字节数(-c)。

  • 了解如何使用 tee 将标准输入复制到文件甚至标准输出,例如 ls -al | tee file.txt

  • 要进行一些复杂的计算,比如分组、逆序和一些其他的统计分析,可以考虑使用 datamash

  • 注意到语言设置(中文或英文等)对许多命令行工具有一些微妙的影响,比如排序的顺序和性能。大多数 Linux 的安装过程会将 LANG 或其他有关的变量设置为符合本地的设置。要意识到当你改变语言设置时,排序的结果可能会改变。明白国际化可能会使 sort 或其他命令运行效率下降许多倍。某些情况下(例如集合运算)你可以放心的使用 export LC_ALL=C 来忽略掉国际化并按照字节来判断顺序。

  • 你可以单独指定某一条命令的环境,只需在调用时把环境变量设定放在命令的前面,例如 TZ=Pacific/Fiji date 可以获取斐济的时间。

  • 了解如何使用 awksed 来进行简单的数据处理。 参阅 One-liners 获取示例。

  • 替换一个或多个文件中出现的字符串:

    1
    perl -pi.bak -e 's/old-string/new-string/g' my-files-*.txt
  • 使用 repren 来批量重命名文件,或是在多个文件中搜索替换内容。(有些时候 rename 命令也可以批量重命名,但要注意,它在不同 Linux 发行版中的功能并不完全一样。)

    1
    2
    3
    4
    5
    6
    # 将文件、目录和内容全部重命名 foo -> bar:
    repren --full --preserve-case --from foo --to bar .
    # 还原所有备份文件 whatever.bak -> whatever:
    repren --renames --from '(.*)\.bak' --to '\1' *.bak
    # 用 rename 实现上述功能(若可用):
    rename 's/\.bak$//' *.bak
  • 根据 man 页面的描述,rsync 是一个快速且非常灵活的文件复制工具。它闻名于设备之间的文件同步,但其实它在本地情况下也同样有用。在安全设置允许下,用 rsync 代替 scp 可以实现文件续传,而不用重新从头开始。它同时也是删除大量文件的最快方法之一:

    1
    mkdir empty && rsync -r --delete empty/ some-dir && rmdir some-dir
  • 若要在复制文件时获取当前进度,可使用 pvpycpprogressrsync --progress。若所执行的复制为block块拷贝,可以使用 dd status=progress

  • 使用 shuf 可以以行为单位来打乱文件的内容或从一个文件中随机选取多行。

  • 了解 sort 的参数。显示数字时,使用 -n 或者 -h 来显示更易读的数(例如 du -h 的输出)。明白排序时关键字的工作原理(-t-k)。例如,注意到你需要 -k1,1 来仅按第一个域来排序,而 -k1 意味着按整行排序。稳定排序(sort -s)在某些情况下很有用。例如,以第二个域为主关键字,第一个域为次关键字进行排序,你可以使用 sort -k1,1 | sort -s -k2,2

  • 如果你想在 Bash 命令行中写 tab 制表符,按下 ctrl-v [Tab] 或键入 $'\t' (后者可能更好,因为你可以复制粘贴它)。

  • 标准的源代码对比及合并工具是 diffpatch。使用 diffstat 查看变更总览数据。注意到 diff -r 对整个文件夹有效。使用 diff -r tree1 tree2 | diffstat 查看变更的统计数据。vimdiff 用于比对并编辑文件。

  • 对于二进制文件,使用 hdhexdump 或者 xxd 使其以十六进制显示,使用 bvihexedit 或者 biew 来进行二进制编辑。

  • 同样对于二进制文件,strings(包括 grep 等工具)可以帮助在二进制文件中查找特定比特。

  • 制作二进制差分文件(Delta 压缩),使用 xdelta3

  • 使用 iconv 更改文本编码。需要更高级的功能,可以使用 uconv,它支持一些高级的 Unicode 功能。例如,这条命令移除了所有重音符号:

    1
    uconv -f utf-8 -t utf-8 -x '::Any-Lower; ::Any-NFD; [:Nonspacing Mark:] >; ::Any-NFC; ' < input.txt > output.txt
  • 拆分文件可以使用 split(按大小拆分)和 csplit(按模式拆分)。

  • 操作日期和时间表达式,可以用 dateutils 中的 dateadddatediffstrptime 等工具。

  • 使用 zlesszmorezcatzgrep 对压缩过的文件进行操作。

  • 文件属性可以通过 chattr 进行设置,它比文件权限更加底层。例如,为了保护文件不被意外删除,可以使用不可修改标记:sudo chattr +i /critical/directory/or/file

  • 使用 getfaclsetfacl 以保存和恢复文件权限。例如:

    1
    2
    getfacl -R /some/path > permissions.txt
    setfacl --restore=permissions.txt
  • 为了高效地创建空文件,请使用 truncate(创建稀疏文件),fallocate(用于 ext4,xfs,btrf 和 ocfs2 文件系统),xfs_mkfile(适用于几乎所有的文件系统,包含在 xfsprogs 包中),mkfile(用于类 Unix 操作系统,比如 Solaris 和 Mac OS)。

系统调试

  • curlcurl -I 可以被轻松地应用于 web 调试中,它们的好兄弟 wget 也是如此,或者也可以试试更潮的 httpie

  • 获取 CPU 和硬盘的使用状态,通常使用使用 tophtop 更佳),iostatiotop。而 iostat -mxz 15 可以让你获悉 CPU 和每个硬盘分区的基本信息和性能表现。

  • 使用 netstatss 查看网络连接的细节。

  • dstat 在你想要对系统的现状有一个粗略的认识时是非常有用的。然而若要对系统有一个深度的总体认识,使用 glances,它会在一个终端窗口中向你提供一些系统级的数据。

  • 若要了解内存状态,运行并理解 freevmstat 的输出。值得留意的是“cached”的值,它指的是 Linux 内核用来作为文件缓存的内存大小,而与空闲内存无关。

  • Java 系统调试则是一件截然不同的事,一个可以用于 Oracle 的 JVM 或其他 JVM 上的调试的技巧是你可以运行 kill -3 <pid> 同时一个完整的栈轨迹和堆概述(包括 GC 的细节)会被保存到标准错误或是日志文件。JDK 中的 jpsjstatjstackjmap 很有用。SJK tools 更高级。

  • 使用 mtr 去跟踪路由,用于确定网络问题。

  • ncdu 来查看磁盘使用情况,它比寻常的命令,如 du -sh *,更节省时间。

  • 查找正在使用带宽的套接字连接或进程,使用 iftopnethogs

  • ab 工具(Apache 中自带)可以简单粗暴地检查 web 服务器的性能。对于更复杂的负载测试,使用 siege

  • wiresharktsharkngrep 可用于复杂的网络调试。

  • 了解 straceltrace。这俩工具在你的程序运行失败、挂起甚至崩溃,而你却不知道为什么或你想对性能有个总体的认识的时候是非常有用的。注意 profile 参数(-c)和附加到一个运行的进程参数 (-p)。

  • 了解使用 ldd 来检查共享库。但是永远不要在不信任的文件上运行

  • 了解如何运用 gdb 连接到一个运行着的进程并获取它的堆栈轨迹。

  • 学会使用 /proc。它在调试正在出现的问题的时候有时会效果惊人。比如:/proc/cpuinfo/proc/meminfo/proc/cmdline/proc/xxx/cwd/proc/xxx/exe/proc/xxx/fd//proc/xxx/smaps(这里的 xxx 表示进程的 id 或 pid)。

  • 当调试一些之前出现的问题的时候,sar 非常有用。它展示了 cpu、内存以及网络等的历史数据。

  • 关于更深层次的系统分析以及性能分析,看看 stapSystemTap),perf,以及sysdig

  • 查看你当前使用的系统,使用 unameuname -a(Unix/kernel 信息)或者 lsb_release -a(Linux 发行版信息)。

  • 无论什么东西工作得很欢乐(可能是硬件或驱动问题)时可以试试 dmesg

  • 如果你删除了一个文件,但通过 du 发现没有释放预期的磁盘空间,请检查文件是否被进程占用:
    lsof | grep deleted | grep "filename-of-my-big-file"

单行脚本

一些命令组合的例子:

  • 当你需要对文本文件做集合交、并、差运算时,sortuniq 会是你的好帮手。具体例子请参照代码后面的,此处假设 ab 是两内容不同的文件。这种方式效率很高,并且在小文件和上 G 的文件上都能运用(注意尽管在 /tmp 在一个小的根分区上时你可能需要 -T 参数,但是实际上 sort 并不被内存大小约束),参阅前文中关于 LC_ALLsort-u 参数的部分。

    1
    2
    3
    sort a b | uniq > c   # c 是 a 并 b
    sort a b | uniq -d > c # c 是 a 交 b
    sort a b b | uniq -u > c # c 是 a - b
  • 使用 grep . *(每行都会附上文件名)或者 head -100 *(每个文件有一个标题)来阅读检查目录下所有文件的内容。这在检查一个充满配置文件的目录(如 /sys/proc/etc)时特别好用。

  • 计算文本文件第三列中所有数的和(可能比同等作用的 Python 代码快三倍且代码量少三倍):

    1
    awk '{ x += $3 } END { print x }' myfile
  • 如果你想在文件树上查看大小/日期,这可能看起来像递归版的 ls -l 但比 ls -lR 更易于理解:

    1
    find . -type f -ls
  • 假设你有一个类似于 web 服务器日志文件的文本文件,并且一个确定的值只会出现在某些行上,假设一个 acct_id 参数在 URI 中。如果你想计算出每个 acct_id 值有多少次请求,使用如下代码:

    1
    egrep -o 'acct_id=[0-9]+' access.log | cut -d= -f2 | sort | uniq -c | sort -rn
  • 要持续监测文件改动,可以使用 watch,例如检查某个文件夹中文件的改变,可以用 watch -d -n 2 'ls -rtlh | tail';或者在排查 WiFi 设置故障时要监测网络设置的更改,可以用 watch -d -n 2 ifconfig

  • 运行这个函数从这篇文档中随机获取一条技巧(解析 Markdown 文件并抽取项目):

    1
    2
    3
    4
    5
    6
    7
    8
    function taocl() {
    curl -s https://raw.githubusercontent.com/jlevy/the-art-of-command-line/master/README-zh.md|
    pandoc -f markdown -t html |
    iconv -f 'utf-8' -t 'unicode' |
    xmlstarlet fo --html --dropdtd |
    xmlstarlet sel -t -v "(html/body/ul/li[count(p)>0])[$RANDOM mod last()+1]" |
    xmlstarlet unesc | fmt -80
    }

冷门但有用

  • expr:计算表达式或正则匹配

  • m4:简单的宏处理器

  • yes:多次打印字符串

  • cal:漂亮的日历

  • env:执行一个命令(脚本文件中很有用)

  • printenv:打印环境变量(调试时或在写脚本文件时很有用)

  • look:查找以特定字符串开头的单词或行

  • cutpastejoin:数据修改

  • fmt:格式化文本段落

  • pr:将文本格式化成页/列形式

  • fold:包裹文本中的几行

  • column:将文本格式化成多个对齐、定宽的列或表格

  • expandunexpand:制表符与空格之间转换

  • nl:添加行号

  • seq:打印数字

  • bc:计算器

  • factor:分解因数

  • gpg:加密并签名文件

  • toe:terminfo 入口列表

  • nc:网络调试及数据传输

  • socat:套接字代理,与 netcat 类似

  • slurm:网络流量可视化

  • dd:文件或设备间传输数据

  • file:确定文件类型

  • tree:以树的形式显示路径和文件,类似于递归的 ls

  • stat:文件信息

  • time:执行命令,并计算执行时间

  • timeout:在指定时长范围内执行命令,并在规定时间结束后停止进程

  • lockfile:使文件只能通过 rm -f 移除

  • logrotate: 切换、压缩以及发送日志文件

  • watch:重复运行同一个命令,展示结果并/或高亮有更改的部分

  • when-changed:当检测到文件更改时执行指定命令。参阅 inotifywaitentr

  • tac:反向输出文件

  • shuf:文件中随机选取几行

  • comm:一行一行的比较排序过的文件

  • strings:从二进制文件中抽取文本

  • tr:转换字母

  • iconvuconv:文本编码转换

  • splitcsplit:分割文件

  • sponge:在写入前读取所有输入,在读取文件后再向同一文件写入时比较有用,例如 grep -v something some-file | sponge some-file

  • units:将一种计量单位转换为另一种等效的计量单位(参阅 /usr/share/units/definitions.units

  • apg:随机生成密码

  • xz:高比例的文件压缩

  • ldd:动态库信息

  • nm:提取 obj 文件中的符号

  • abwrk:web 服务器性能分析

  • strace:调试系统调用

  • mtr:更好的网络调试跟踪工具

  • cssh:可视化的并发 shell

  • rsync:通过 ssh 或本地文件系统同步文件和文件夹

  • wiresharktshark:抓包和网络调试工具

  • ngrep:网络层的 grep

  • hostdig:DNS 查找

  • lsof:列出当前系统打开文件的工具以及查看端口信息

  • dstat:系统状态查看

  • glances:高层次的多子系统总览

  • iostat:硬盘使用状态

  • mpstat: CPU 使用状态

  • vmstat: 内存使用状态

  • htop:top 的加强版

  • last:登入记录

  • w:查看处于登录状态的用户

  • id:用户/组 ID 信息

  • sar:系统历史数据

  • iftopnethogs:套接字及进程的网络利用情况

  • ss:套接字数据

  • dmesg:引导及系统错误信息

  • sysctl: 在内核运行时动态地查看和修改内核的运行参数

  • hdparm:SATA/ATA 磁盘更改及性能分析

  • lsblk:列出块设备信息:以树形展示你的磁盘以及磁盘分区信息

  • lshwlscpulspcilsusbdmidecode:查看硬件信息,包括 CPU、BIOS、RAID、显卡、USB设备等

  • lsmodmodinfo:列出内核模块,并显示其细节

  • fortuneddatesl:额,这主要取决于你是否认为蒸汽火车和莫名其妙的名人名言是否“有用”

仅限 OS X 系统

以下是仅限于 OS X 系统的技巧。

  • brew (Homebrew)或者 port (MacPorts)进行包管理。这些可以用来在 OS X 系统上安装以上的大多数命令。

  • pbcopy 复制任何命令的输出到桌面应用,用 pbpaste 粘贴输入。

  • 若要在 OS X 终端中将 Option 键视为 alt 键(例如在上面介绍的 alt-balt-f 等命令中用到),打开 偏好设置 -> 描述文件 -> 键盘 并勾选“使用 Option 键作为 Meta 键”。

  • open 或者 open -a /Applications/Whatever.app 使用桌面应用打开文件。

  • Spotlight:用 mdfind 搜索文件,用 mdls 列出元数据(例如照片的 EXIF 信息)。

  • 注意 OS X 系统是基于 BSD UNIX 的,许多命令(例如 pslstailawksed)都和 Linux 中有微妙的不同( Linux 很大程度上受到了 System V-style Unix 和 GNU 工具影响)。你可以通过标题为 “BSD General Commands Manual” 的 man 页面发现这些不同。在有些情况下 GNU 版本的命令也可能被安装(例如 gawkgsed 对应 GNU 中的 awk 和 sed )。如果要写跨平台的 Bash 脚本,避免使用这些命令(例如,考虑 Python 或者 perl )或者经过仔细的测试。

  • sw_vers 获取 OS X 的版本信息。

仅限 Windows 系统

以下是仅限于 Windows 系统的技巧。

在 Winodws 下获取 Unix 工具

  • 可以安装 Cygwin 允许你在 Microsoft Windows 中体验 Unix shell 的威力。这样的话,本文中介绍的大多数内容都将适用。

  • 在 Windows 10 上,你可以使用 Bash on Ubuntu on Windows,它提供了一个熟悉的 Bash 环境,包含了不少 Unix 命令行工具。好处是它允许 Linux 上编写的程序在 Windows 上运行,而另一方面,Windows 上编写的程序却无法在 Bash 命令行中运行。

  • 如果你在 Windows 上主要想用 GNU 开发者工具(例如 GCC),可以考虑 MinGW 以及它的 MSYS 包,这个包提供了例如 bash,gawk,make 和 grep 的工具。MSYS 并不包含所有可以与 Cygwin 媲美的特性。当制作 Unix 工具的原生 Windows 端口时 MinGW 将特别地有用。

  • 另一个在 Windows 下实现接近 Unix 环境外观效果的选项是 Cash。注意在此环境下只有很少的 Unix 命令和命令行可用。

实用 Windows 命令行工具

  • 可以使用 wmic 在命令行环境下给大部分 Windows 系统管理任务编写脚本以及执行这些任务。

  • Windows 实用的原生命令行网络工具包括 pingipconfigtracert,和 netstat

  • 可以使用 Rundll32 命令来实现许多有用的 Windows 任务

Cygwin 技巧

  • 通过 Cygwin 的包管理器来安装额外的 Unix 程序。

  • 使用 mintty 作为你的命令行窗口。

  • 要访问 Windows 剪贴板,可以通过 /dev/clipboard

  • 运行 cygstart 以通过默认程序打开一个文件。

  • 要访问 Windows 注册表,可以使用 regtool

  • 注意 Windows 驱动器路径 C:\ 在 Cygwin 中用 /cygdrive/c 代表,而 Cygwin 的 / 代表 Windows 中的 C:\cygwin。要转换 Cygwin 和 Windows 风格的路径可以用 cygpath。这在需要调用 Windows 程序的脚本里很有用。

  • 学会使用 wmic,你就可以从命令行执行大多数 Windows 系统管理任务,并编成脚本。

  • 要在 Windows 下获得 Unix 的界面和体验,另一个办法是使用 Cash。需要注意的是,这个环境支持的 Unix 命令和命令行参数非常少。

  • 要在 Windows 上获取 GNU 开发者工具(比如 GCC)的另一个办法是使用 MinGW 以及它的 MSYS 软件包,该软件包提供了 bash、gawk、make、grep 等工具。然而 MSYS 提供的功能没有 Cygwin 完善。MinGW 在创建 Unix 工具的 Windows 原生移植方面非常有用。

更多资源

免责声明

除去特别小的工作,你编写的代码应当方便他人阅读。能力往往伴随着责任,你 有能力 在 Bash 中玩一些奇技淫巧并不意味着你应该去做!;)

授权条款

Creative Commons License

本文使用授权协议 Creative Commons Attribution-ShareAlike 4.0 International License

l