solomonxie / blog-in-the-issues

A personalised tech-blog, notebook, diary, presentation and introduction.
https://solomonxie.github.io
68 stars 12 forks source link

Linux 命令行终端操作积累 #27

Open solomonxie opened 6 years ago

solomonxie commented 6 years ago

积累终端命令行相关经验,包括Shell中的bash,zsh,终端中的Terminal, Mac Terminal.app,iTerm等

注意:这里说linux,linux之类的,其实在mac中也ok。只不过说起来和搜索起来方便而已。

涉及领域

solomonxie commented 6 years ago

Linux uniq命令 删除文本中重复行

$ uniq <FILE.txt>

# 只显示非重复的行
$ uniq -u <FILE.txt>

# 只显示重复的行
$ uniq -d <FILE.txt>
solomonxie commented 6 years ago

base64 命令让图片于base64字符串互转

base64是绝大多数linux系统自带的程序,可以轻松快速把二进制文件转换成base64字符串,或者反之转换回来。用法极其简单,如下:

# 把图片转换成base64字符串,且保存为文本文件
$ base64 test111.jpg > string.txt

# 把含有base64字符串的文本转换回图片文件
$ base64 -D string.txt -o test222.jpg
solomonxie commented 6 years ago

❖ ZSH终极美化

终端专用字体

终端美化不管是什么方案,都少不了的就是炫丽的字体安装。 这个就是OS系统级别的东西了,所以我们要对在电脑系统里面安装。 可以手动下载主题包,然后双击打开装到自己的电脑里(Mac、Windows、Linux)。 如果是Mac和Linux,也可以在命令行里完成。 程序员几乎需要的所有字体都在这个repo里了:

安装方法:

# 下载
cd ~
git clone https://github.com/powerline/fonts.git --depth=1
# 到该目录下执行安装。Mac、Linux都可以
cd fonts
./install.sh
# 删除刚刚下载的
cd ..
rm -rf fonts

安装完成后显示: image

经典的Agnoster主题

参考Github:agnoster/agnoster-zsh-theme

image

要正常显示出Agnoster主题效果,需满足以下几点:

安装方法:

# 下载主题文件到`oh-my-zsh`的主题目录
$ wget https://raw.githubusercontent.com/agnoster/agnoster-zsh-theme/master/agnoster.zsh-theme -P ~/.oh-my-zsh/themes/

# 在`~/.zshrc`中开启主题:
ZSH_THEME="agnoster" 

# 安装主题所需的字体(需要Powerline-patched font )

超帅的Powerlevel9k主题

参考Github:bhilburn/powerlevel9k

687474703a2f2f67696679752e636f6d2f696d616765732f70396b6e65772e676966

首先注意:字体目前测试可用的有:

最方便的安装方法是用oh-my-zsh安装,方法如下:

# 下载主题包到oh-my-zsh目录下
$ git clone https://github.com/bhilburn/powerlevel9k.git ~/.oh-my-zsh/custom/themes/powerlevel9k

# 在`~/.zshrc`中开启主题
ZSH_THEME="powerlevel9k/powerlevel9k"

# 安装主题所需的字体(需要在电脑上安装Powerline字体)
solomonxie commented 6 years ago

❖ Tmux Like a Boss [DRAFT]

进阶参考:10 Killer Tmux Tips

Tmux会话自动保存

Tmux会话是整个tmux中最最最重要的东西。在tmux中创建多个window,且合理分配窗格,是让tmux运用如飞的核心。但是关机重启电脑后tmux-server服务器也重启了,session就会消失。这绝对是不能允许的,因为一次重启就让之前所有的窗格设计全消失肯定不行。

所以,tmux的会话保存是tmux 101第一课。 这里主要就是用两个插件:tmux-resurrect保存会话,然后加上tmux-continuum来自动保存运行resurrect。

tmux-resurrect

参考Github: tmux-resurrect

由于tmux不能持久保存session的特性,我们需要安装这个插件来将session的设置完全保存到本地,然后重启后也能够快速恢复窗口等设置的内容。 首先在~/.tmux.conf文件的List of plugins部分加入这句话:

set -g @plugin 'tmux-plugins/tmux-resurrect'

保存好后,在tmux的任意窗口按<前缀键>I (注意是大写的i),即可完成下载安装。

用法:

重要缺陷:

Bug发现:

对于自动保存的问题,tmux-resurrect官方推荐另一个插件:tmux-continuum。非常好用,定期自动帮你保存session,电脑关机重启的话,打开tmux后会第一时间恢复上一次的session。

tmux-continuum

参考Github: tmux-continuum

Continuum会默认每15分钟调用一次tmux-resurrect插件的保存功能。可以自己改成5分钟。 但是不用担心太多保存文件占用空间,continuum只在tmux窗格发生变动时才保存。而且每个文件才5k,不占多少地方。

常见问题:continuum无法自动保存

有时候可以自动保存很方便,但是很多时候总是无法自动保存。 参考官方Github的issues, 作者说,tmux-continuum是由Status bar中触发continuum的脚本从而达到自动保存的作用,所以很有可能在修改tmux状态栏时候,产生了冲突造成continuum不生效。

image

根据经验,.tmux.conf的其它所有改动都可以在<前缀键>r后立即生效, 唯独修改continuum相关设置,必须杀死所有tmux相关进程和session后才会生效。 记住这点,会省很多时间。

解决方案:

一般如果能正常重启,就都能解决了。

tmuxinator

网上几乎所有人都在说这个是tmux的最佳伴侣。 但是我看了一圈后发现这几个一开始就不让人喜欢的特性:

看到这里,我就放弃了安装它的念头了。

Tmux常用插件集合

tmux-sensible

tmux-yank

solomonxie commented 6 years ago

ZSH隐藏命令行前面的用户名和主机名

只需要修改~/.zshrc即可:

solomonxie commented 6 years ago

修改默认Shell

直接在用户文件里面给自己的用户设定默认shell:

$ sudo vim /etc/passwd

找到自己的用户,修改为自己想要的shell的位置:

image

solomonxie commented 6 years ago
solomonxie commented 6 years ago

Linux 修改本机时区

参考:linux修改时区

# 查看当前时间
$ date -R
Fri, 09 Jan 2015 13:56:05 +0700

# 修改时区为中国时区
$ sudo cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

# 查看时间
$ date -R
Mon, 07 Sep 2015 02:12:43 -0700
solomonxie commented 6 years ago

Linux/Mac 修改终端的登录欢迎信息

Linux可以设置登录前后的欢迎信息,可以修改3个文件:

Before login:

/etc/issue
/etc/issue.net #网络登陆显示

After login:

/etc/motd

Mac上默认没有这些文件,需要手动创建。

如果是需要执行某个命令生成信息,那就需要改~/.zshrc~/.bash_profile了。只需要在里面加入具体命令即可。

如果是只给SSH登录执行命令,则这么写:

if [[ -n $SSH_CONNECTION ]] ; then
    echo "I'm logged in remotely"
fi
solomonxie commented 6 years ago
solomonxie commented 6 years ago

❖ 树莓派/Ubuntu 挂载外置存储

$ mount -t deviceFileFormat -o umask=filePermissons,gid=ownerGroupID,uid=ownerID /device /mountpoint

# 可选-o 模式
rw,suid,dev,exec,auto,nouser,async

树莓派挂载U盘

参考文章

# 检查设备名字
$ df -h
# 或详细展示已连接设备,包括文件系统等信息 (没有sudo无法使用fdisk)
$ sudo fdisk -l

# 设定映射目录
$ sudo mkdir /media/pi/udisk
# 将指定设备映射到刚刚创建到目录
$ sudo mount /dev/sda1 /media/pi/udisk

# 开机自动执行
$ sudo vim /etc/rc.local
# 将下面这句加到文件内容中(rc.local最后的exit 0之前都行)
$ mount -o uid=pi,gid=pi /dev/sda1 /media/pi/udisk

# 取消挂载优盘(不是reject弹出)
$ sudo umount /dev/sda1

树莓派挂载FAT32格式的U盘

如果是默认挂载的话,FAT32的U盘在Linux上是只读的,所以必须要指定用户、用户组、读写权限、设备类型等:

$ sudo mount -t vfat -o rw,uid=pi,gid=pi /dev/sda1 /media/pi/udisk

树莓派挂载NTFS格式移动硬盘

# 安装ntfs-3g程序
$ sudo apt-get install ntfs-3g

# 先查找当前已经插上的NTFS格式硬盘的设备位置,如:/dev/sda1
$ sudo fdisk -l | grep NTFS

# 随便找个地方建立一个空目录,用来映射硬盘内容
$ sudo mkdir ~/drive

# 挂载硬盘
$ sudo mount -t ntfs-3g /dev/sda1 ~/drive
# 或
$ ntfs-3g /dev/sda1 ~/drive

由于NTFS格式不支持Unix系列的用户组策略,所以默认都是root用户,无法修改所有者。 所以我们可以在挂载的时候选择所有者达到目的:

$ ntfs-3g /dev/sda1 /media/pi/drive -o gid=6001, uid=6001

指定挂载磁盘的用户、组、权限

同样是编辑/etc/fstab,在第一个参数处添加uid=用户名,gid=组名即可。示例:

UUID=5B7D-9E47 /media/pi/udisk exfat nofail,uid=root,gid=root 0 2

保存退出后,需要umount卸载再mount挂载。

树莓派挂载exFat格式硬盘

如果移动硬盘是exFAT格式,那么mount命令无法正常挂载这个移动硬盘。 所以我们需要安装exfat-fuse插件,让mount支持这个格式:

# 安装支持exfat系统的程序 
# 树莓派:
$ sudo apt-get install exfat-fuse

# 如果是Ubuntu就用这个:
#$ sudo apt-get install exfat-utils

# 挂载硬盘
$ sudo mount -t exfat /dev/sda1 ~/drive

常用硬盘调试命令

显示所有正常连接的存储设备:

$ lsblk

这个命令可以看到有那些外置盘连接上了,有没有映射,映射到哪个目录。 image

显示一切硬件连接的流水账信息:

# 显示最新的20条信息 且友好的输出时间(-T)
$ dmesg -T | tail -20

# 显示所有SD卡或U盘相关
$ dmesg |grep sda

# 显示一切USB相关
$ dmesg |grep usb

这个显示出刚刚插上的USB设备出了问题:供电不足 image

禁止树莓派自动挂载

我自己挂载的目录失效,树莓派自动挂载到另一个目录。 这是树莓派自动的,就像Windows一样插上硬盘就会挂载成一个驱动盘。 但是这个不方便我们操作,因为目录和路径图都是不确定的,所以就关闭掉树莓派自动挂载。

参考:禁止u盘自动弹出

# 查看各个设备的uuid号
$ ls -l /dev/disk/by-uuid/
lrwxrwxrwx 1 root root 10  6月 27 16:24 0000678400004823 -> ../../sdb1

#  在fstab中关闭这个设备的自动挂载 noauto
$ vim /etc/fstab

UUID=0000678400004823 /media vfat noauto 0 0

注意:如果设置成了noauto,那么就无法用mount -a全部挂载了。

开机重启后自动挂载外置存储

由于/dev/sda1这个位置是不固定的,每次都是随机分配的,所以无法在开机根据这个位置来挂载U盘。 但是每个U盘都是有自己的唯一名称的:UUID,我们可以用这个ID进行挂载。

首先,要查看每个设备的UUID:

$ ls -l /dev/disk/by-uuid
>>> lrwxrwxrwx 1 root root 10  6月 27 16:24 0000678400004823 -> ../../sdb1

知道这个UUID是0000678400004823后,我们就在/etc/fstab中指定它和某个文件夹的关联(注意是关联而不是挂载):

UUID=0000678400004823 /udisk exfat nofail 0 2

保存退出后,再到/etc/rc.local中加入挂载命令:

sudo mount -a

mount -a代表挂载所有”已经已知的或在fstab中定义过的设备“。反过来umount -a是取消挂载所有设备。

重启后就可以看到所有定义过的设备都自动挂载到指定的目录了。

当然,如果不愿意开机自动挂载,那么如果已经在fstab中定义过关联了,你只需要简单的输入sudo mount /udisk即可完成挂载。

常见问题

挂载的U盘或磁盘变成只读

最常见的原因是:

mount时候,没有指定,或者没有正确指定磁盘的格式。所以才会只读。

如果不管怎么chmodchownmount -o rw,都不管用的话,那就是磁盘本身的问题了。 通过以下dosfsck文件系统错误修复命令瞬间修复:

# 先卸载磁盘 (比如磁盘sda1)
$ sudo umount /dev/sda1

# 修复磁盘
$ sudo dosfsck  -v -a /dev/sda1

显示U盘文件系统出错

image

显示Input/output error错误并无法读取设备

这个经常出现在大批量读取U盘或移动硬盘时,突然掉线导致的,可能是设备老化吧。 这个时候,无法读取部分或所有目录,甚至无法挂载在原先的目录。 这种时候,最快捷的就是重启。或者挂载到另一个目录。

mount 映射时显示 Transport endpoint is not connected

这个是在mount命令挂载的过程中出现的错误。 一般是被映射的空目录本身出了问题,所以只要删除这个目录,或者换个地方再映射,就好了。 如果删不掉这个目录,就重启一下就可以删了。

弹出硬盘时显示 Target Busy

看看有没有哪个设备正在连接这个目录,有的话就关掉。 或者重启电脑。

sudo fuser -k /dev/sda1
solomonxie commented 6 years ago

❖ 深究cp拷贝文件夹时“/”的用法

假设现有一个source文件夹:

source
    sub
        a.jpg
    b.jpg
    c.jpg

目标文件夹「不存在」的情况

$ cp -r source target
$ cp -r source/ target
$ cp -r source/ target/

▲ 结果:「source = target」以上三句话一样,都是创建一个source的同级克隆,只不过名字不同:
target
    ......
source
    ......

$ cp -r source/* target
▲ 结果:「命令错误」

目标文件夹「已存在」且为空

$ cp  -r source target

▲ 结果:「source ≠ target」无论是否有内容,都在target目录下存放source目录:
source
    ......
target
    source
        ......

$ cp  -r source/ target
$ cp  -r source/ target/
$ cp -r source/* target
$ cp  -r source/* target/
▲ 结果:「source = target」以上几句话一样,会正确的把source下的内容拷贝到target下
target
    ......
source
    ......

目标文件夹「已存在」且不为空,且无同名文件

$ cp  -r source target
$ cp  -r source target/

▲ 结果:「source ≠ target」无论是否有内容,都在target目录下存放source目录:
source
    ......
target
    source
        ......

$ cp  -r source/ target
$ cp  -r source/ target/
$ cp  -r source/* target
$ cp  -r source/* target/
▲ 结果:「target ∋ source」会把source下的内容全部拷贝到targe之中
source
    ......
target
    ......
    ......

目标文件夹「已存在」且有冲突文件

▲结果:「默认覆盖有冲突的目标文件」无论怎么拷贝都默认覆盖
solomonxie commented 6 years ago

❖ 深究mv移动文件夹时”/“的用法

目标文件夹「不存在」的情况

$ mv source target

▲结果:把source文件夹「更名」为target

目标文件夹「已存在」且为空

$ mv source/ target
$ mv source/ target/
$ mv source target/
$ mv source/ target/
▲结果:将source移动到target下,成为子文件夹
target
    source
        ......

$ mv source/* target
$ mv source/* target/

▲结果:将source的所有内容移动到target下
source
target
        ......

目标文件夹「已存在」且有冲突文件

这就比较复杂了。 如果有冲突文件,则会不询问直接覆盖。 如果有冲突文件夹,则会把文件先全都移动过去,对于有冲突的文件夹,则无论如何都无法移动或覆盖。这时候要用cp -r命令先复制,在rm -r命令删除源文件夹。

solomonxie commented 6 years ago

❖ Linux查看系统信息 [DRAFT]

查看系统版本

查看kernel内核:

$ cat /etc/os-release

image

查看版本Distribution(内置工具):

$ cat /etc/*release # 查看所有版本相关(os-release, lsb-release)
$ cat /etc/lsb-release #查看发行版信息
>>> 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04.4 LTS"

$ cat /etc/issue* #查看包括/etc/issue和/etc/issue.net
>>>
Ubuntu 16.04.4 LTS \n \l
Ubuntu 16.04.4 LTS

$ cat /proc/version
>>> Linux version 4.4.0-1069-aws (buildd@lcy01-amd64-023) (gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.10) ) #79-Ubuntu SMP Mon Sep 24 15:01:41 UTC 2018

查看版本Distribution(第三方工具):

$ lsb_release -a #显示全部
$ lsb_release -si #显示distribution
$ lsb_release -sd #显示distro描述
$ lsb_release -sr #显示distro的版本号数字
$ lsb_release -sc #显示distro的版本名称

image

查看CPU型号

$ cat /proc/cpuinfo

image

查看内存

$ cat /proc/meminfo

image

查看GPU

如果是Nvidia显卡

$ sudo apt-get install nvidia-smi
$ nvidia-smi -stats

查看存储

$ df -h

image

solomonxie commented 6 years ago

❖ sed 文本编辑命令一文入门

参考极客学院:正则表达式和 SED 参考菜鸟教程:Linux sed命令 参考酷壳:SED 简明教程

sed匹配没有问题,但是默认会显示一行中所有内容,所以难的是你需要知道保存分组并且只显示你想要的分组。

image

基本语法:

sed [-n] [-e <expression>] [-f <外部脚本文件>] [被处理的文件]

参数说明:

-n或--quiet或--silent 仅显示expression处理后的结果
-e或--expression 可用来执行多个表达式:-e <expression1> -e <expression2>
-f<文件>或--file=<script文件> 读取外部文件里的脚本

动作命令说明:

a :新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)
c :取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行
d :删除,d 后面不会加任何动作
i :插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行)
p :打印,亦即将某个选择的数据印出。通常 p 会与参数 sed -n 一起运行
s :替换,通常这个 s 的动作可以搭配正规表示. 例如 `1,20s/old/new/g`

支持的正则表达式: image

以行号为单位操作

操作的格式:

按照行号执行命令:

以文字匹配为单位操作

操作格式:

sed /<RegX>/<Action>

按照搜索结果执行命令:

文字匹配加行号匹配执行操作

结尾命令(Action):

操作格式:

sed '<Range>s/<RegX>/<Text>/<CMD>' <File>

组合文字和行号匹配执行命令:

sed直接修改文件

多次匹配

sed '<expression1>; <expression2>'
# 或
sed -e '<expression1>' -e '<expression2>'

正则表达式的变量

&代表匹配到的文字:

sed 's/<RegX>/Before & After/g' <file>

( )创建分组,并用\n代表匹配到的文字:

sed 's/(Reg1)(Reg2)/\1\2/g'

常用

假设我们用ping -c 10 localhost >> ping.txt文件,然后用sed来操作:

# 只显示第1行
$ cat ping.txt | sed -n '1p'
# 只显示最后一行(这个无需sed)
$ tail ping.txt -n 1

# 只显示第2-4行
$ cat ping.txt | sed -n '2,4p'

# 删除第2-4行并显示
$ cat ping.txt | sed '2,4d'

# 显示本机在局域网内IP地址
$ /sbin/ifconfig eth0 | grep 'inet addr' | sed 's/^.*addr://g' | sed 's/Bcast.*$//g'
>>> 192.168.1.100 Bcast:192.168.1.255 Mask:255.255.255.0
solomonxie commented 6 years ago

Neofetch 超帅终端显示系统信息

Neofetch主要是用来炫桌面的、截图用的。

Refer to: neofetch – Awesome system info bash script for Linux, MacOS, Unix

支持多种OS:Linux/Mac

Mac安装:

$ brew install neofetch

image

Ubuntu安装:

sudo add-apt-repository ppa:dawidd0811/neofetch

sudo apt update && sudo apt install neofetch

image

树莓派安装(Jessie版):

sudo echo "deb [arch=all] http://dl.bintray.com/dawidd6/neofetch jessie main" > /etc/apt/sources.list.d/neofetch.list

sudo apt update && sudo apt install neofetch

image

很快安装好后,只要输入neofetch命令,就会马上显示出漂亮的信息。

solomonxie commented 6 years ago

Awesome Window Manager 超帅Linux新型桌面 [DRAFT]

最近总是在Reddit上看Arch Linux的人炫桌面截图。确实很帅很现代化,极简风格。查了下,原来是一个叫Awesome的桌面管理器,替代传统的Gnome/Unity等等难看桌面,而且据说这个桌面极快、极小、高度可定制。

参考官网:Awesome Window Manager

image

安装

Ubuntu安装如下:

solomonxie commented 6 years ago
solomonxie commented 6 years ago

Mac Homebrew 更换中国源

Homebrew安装主要靠git仓库,切换源实际上就是切换相关git repo的remote url.

具体做法:

切换USTC源:https://lug.ustc.edu.cn/wiki/mirrors/help/brew.git

# 更换brew.git的源
cd "$(brew --repo)"
git remote set-url origin https://mirrors.ustc.edu.cn/brew.git
# 更换homebrew-core.git的源
cd "$(brew --repo)/Library/Taps/homebrew/homebrew-core"
git remote set-url origin https://mirrors.ustc.edu.cn/homebrew-core.git

brew update

另外,还需要更换Homebrew Bottle源,这个只要在shell配置文件里加上(或更改)一个变量即可。 如zsh就是编辑~/.zshrc文件, bash就是~/.bash_profile文件:

export HOMEBREW_BOTTLE_DOMAIN=https://mirrors.ustc.edu.cn/homebrew-bottles

切换清华源:https://mirror.tuna.tsinghua.edu.cn/help/homebrew/

cd "$(brew --repo)"
git remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/brew.git
cd "$(brew --repo)/Library/Taps/homebrew/homebrew-core"
git remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-core.git
cd "$(brew --repo)/Library/Taps/homebrew/homebrew-science"
git remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-science.git
cd "$(brew --repo)/Library/Taps/homebrew/homebrew-python"
git remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-python.git

brew update

重置官方源:

# 重置brew.git:
cd "$(brew --repo)"
git remote set-url origin https://github.com/Homebrew/brew.git

# 重置homebrew-core.git:
cd "$(brew --repo)/Library/Taps/homebrew/homebrew-core"
git remote set-url origin https://github.com/Homebrew/homebrew-core.git
solomonxie commented 6 years ago

Linux Environment Variables 环境变量

用户相关

位置相关

程序相关

系统设置相关

solomonxie commented 6 years ago

❖ Disk Management 磁盘管理 [DRAFT]

Badblocks 坏道修复

坏道检查命令/sbin/badblocks

# 检测并输出坏道信息(信息等下会被用到)
$ sudo badblocks -v /dev/sda > badsectors.txt

# 根据坏道信息进行修复
# ------------ 针对 for ext2/ext3/ext4 文件系统 ------------
$ sudo e2fsck -l badsectors.txt /dev/sda
#或
# ------------ 针对其它文件系统 ------------
$ sudo fsck -l badsectors.txt /dev/sda

cron任务定期坏道检查,编辑/etc/cron.d/badblocks文件:

30 4 * * 3 root [ -x /sbin/badblocks ] && [ $(date +\%d) -le 7 ] && /sbin/badblocks /dev/sda

空白硬盘分区、格式化

主要执行的命令顺序为:lsblk查看已连接硬盘 -> file查看硬盘是否格式化 -> fdisk分区 -> mkfs格式化

Ubuntu系下:

# 查看添加的网盘名称和地址(如/dev/sda)
$ lsblk

# 查看网盘的文件系统状况(是否格式化了)
$ sudo file -s /dev/sda

# 最好先检查和修复坏道后再操作
# ......

# 分区 (进入交互shell)
$ sudo fdisk /dev/sda
# 创建一个或几个分区,根据提示很容易搞定
# ....
# 保存分区表
:w

# 用不同的格式来格式化每个分区(不要在fdisk里面格式化)
$ sudo mkfs -t exfat /dev/sda1
$ sudo mkfs -t ntfs /dev/sda2

Mac终端下:

solomonxie commented 6 years ago

❖ Linux 路径名称操作

Linux自带的basenamedirname命令就极其好用,很多情况都不需要sedawk等高级复杂工具。

常用命令:

# 获取路径名
$ dirname "/etc/apt/abc.txt"
>>> /etc/apt

$ dirname "/etc/apt/"
>>> /etc

# 获取<当前目录>的绝对路径
$ echo ${PWD##*/}

# 获取<当前目录>的父目录的绝对路径
$ dirname $(pwd)
# 或
$ echo ${PWD%/*}

# 获取文件名(或最后一个目录名)
$ basename "/etc/apt/abc.list"
>>> abc.list

$ basename "/etc/apt/"
>>> apt

# 获取名称不包括扩展名
# (通过去掉结尾的指定文字来达到)
$ basename "/etc/apt/abc.list" .list
>>> abc

常用脚本中路径命令:

# 获取<当前脚本>的绝对路径
$ dirname $0

# 获取<当前脚本>的父目录的绝对路径
cd $(dirname $0)
echo $(dirname $(pwd))
solomonxie commented 6 years ago

fstab与mount挂载外部磁盘详解

/etc/fstab文件中,每一行都是一个Entry Point “入口”,每一条入口的格式为:

File_system   Mount_point   Type  Options   Dump/Pass

image

参考:配置启动挂载:fstab文件详解

  1. File_system 即设备ID或设备位置,如/dev/sdax
  2. Mount_point 挂载点(文件夹地址)
  3. Type 格式类型,如fat32,ntfs, ntfs-3g,ext2,ext4 4. Options 加载参数:最重要的命令!
  4. Dump 备份命令:用来决定是否做备份的. 值为0或1。如果是0,dump就会忽略这个文件系统,如果是1,dump就会作一个备份。大部分用户都没有安装dump utility,所以对他们而言这里都写0。
  5. Pass 启动时是否以fsck检验扇区。值为0或1。0 是不要检验(swap等不需要), 1 表示最早检验(一般只有根目录会配置为 1); 2 也是要检验,不过是在重要目录检验之后才执行!一般来说,根目录配置为1,其他的要检验的filesystem都配置为 2 就好了。

其中,最重要的设置就是Options

它会设置设备的读写权限、开机自动加载、中文显示乱码问题等。它的内容是与mount命令的-o选项内容是一样的。

Option中可以有很多参数值,每个值之间用,逗号隔开。

Options 常用参数:

fstab详细参考

you will see this in the file and you need to add your new entry under this line.

brief explanation of the above format:

1.file_system = your device id.

use this:

/dev/sdax ( you should check it with sudo fdisk -l)

it may be /dev/sdbx or /dev/sdcx if you have more than one disks connected.

2. mount_point =where you want to mount your partition.

use this:

/media/user/label  

here user is your user name, label is "software", "movies" or whatever label your partiton have.

3. type=fat32,ntfs, ntfs-3g,ext2,ext4 or whatever your partition type is.

4. options =mount options for the partition(explained later).

5. dump=Enable or disable backing up of the device/partition .usually set to 0, which disables it.

6. pass =Controls the order in which fsck checks the device/partition for errors at boot time. The root device should be 1. Other partitions should be 2, or 0 to disable checking.

so for auto mounting case the above format reduces to:

/dev/sdax /media/user/label  type  options           0  0

(you can check the type with sudo fdisk -l)

the options field:

sync/async - All I/O to the file system should be done synchronously/asynchronously.
auto/noauto - The filesystem will be mounted automatically at startup/The filesystem will NOT be automatically mounted at startup.
dev/nodev - Interpret/Do not interpret character or block special devices on the file system.
exec / noexec - Permit/Prevent the execution of binaries from the filesystem.
suid/nosuid - Permit/Block the operation of suid, and sgid bits.
ro/rw - Mount read-only/Mount read-write.
user/nouser - Permit any user to mount the filesystem. (This automatically implies noexec, nosuid,nodev unless overridden) / Only permit root to mount the filesystem. This is also a default setting.
defaults - Use default settings. Equivalent to rw, suid, dev, exec, auto, nouser, async.
_netdev - this is a network device, mount it after bringing up the network. Only valid with fstype nfs.
now the final format reduces to (for auto mount):

/dev/sdax /media/user/label  type     defaults       0  0  

for ntfs

/dev/sdax /media/user/label   ntfs  defaults       0  0  

for ext4

/dev/sdax /media/user/label   ext4  defaults       0  0  

etc.....

you can change defaults by your own configuration, like

/dev/sdax /media/user/label   ext4  rw,suid,dev,noexec,auto,user,async      0  0

etc...

you need to add entry for each partiton you want to auto mount.

3. save and exit the file then restart and see the result.
solomonxie commented 6 years ago

Ubuntu将命令或脚本变成服务开机启动

有很多程序比如ssh-tunnel、frp、jekyll、Jupyter notebook等网络服务,都是在前台执行监听的,必须一直保持进程连接才行,每次还要手动输入命令打开,不方便,也不稳定。 比如ssh-tunnel,如果其中哪个节点的终端稍稍断开,那就都断了,不稳定。在这种情况下非常有必要把它转为后台运行的服务,且开机自动启动,不需要手动打开。

Linux的各种distro的添加服务方式都不一样,所以需要分别查。 Linux的服务,其实就是自定义的shell脚本。需要做的主要就是把这个脚本以各种系统要求的格式或位置放好,然后用某个工具添加到服务中即可。

Redhat系是用chkconfig命令,而Ubuntu系是用update-rc.d命令。具体做法如下:

关于自定义脚本的编写

Linux的服务的本质是一个shell脚本,但是需要遵循service的标准模版,比如在头注释中编写service描述等,以供系统读取;还要定义每种操作的具体实行方式,比如在service start时会执行脚本中的start()函数。

参考:在Ubuntu下添加自定义服务

以下为标准模版:

#!/bin/bash
### BEGIN INIT INFO
#
# Provides:  location_server
# Required-Start:   $local_fs  $remote_fs
# Required-Stop:    $local_fs  $remote_fs
# Default-Start:    2 3 4 5
# Default-Stop:     0 1 6
# Short-Description:    initscript
# Description:  This file should be used to construct scripts to be placed in /etc/init.d.
#
### END INIT INFO

## Fill in name of program here.
PROG="location_server"
PROG_PATH="/opt/location_server" ## Not need, but sometimes helpful (if $PROG resides in /opt for example).
PROG_ARGS="" 
PID_PATH="/var/run/"

start() {
    if [ -e "$PID_PATH/$PROG.pid" ]; then
        ## Program is running, exit with error.
        echo "Error! $PROG is currently running!" 1>&2
        exit 1
    else
        ## Change from /dev/null to something like /var/log/$PROG if you want to save output.
        $PROG_PATH/$PROG $PROG_ARGS 2>&1 >/var/log/$PROG &
    $pid=`ps ax | grep -i 'location_server' | sed 's/^\([0-9]\{1,\}\).*/\1/g' | head -n 1`

        echo "$PROG started"
        echo $pid > "$PID_PATH/$PROG.pid"
    fi
}

stop() {
    echo "begin stop"
    if [ -e "$PID_PATH/$PROG.pid" ]; then
        ## Program is running, so stop it
    pid=`ps ax | grep -i 'location_server' | sed 's/^\([0-9]\{1,\}\).*/\1/g' | head -n 1`
    kill $pid

        rm -f  "$PID_PATH/$PROG.pid"
        echo "$PROG stopped"
    else
        ## Program is not running, exit with error.
        echo "Error! $PROG not started!" 1>&2
        exit 1
    fi
}

## Check to see if we are running as root first.
## Found at http://www.cyberciti.biz/tips/shell-root-user-check-script.html
if [ "$(id -u)" != "0" ]; then
    echo "This script must be run as root" 1>&2
    exit 1
fi

case "$1" in
    start)
        start
        exit 0
    ;;
    stop)
        stop
        exit 0
    ;;
    reload|restart|force-reload)
        stop
        start
        exit 0
    ;;
    **)
        echo "Usage: $0 {start|stop|reload}" 1>&2
        exit 1
    ;;
esac

其中,PROG变量为所要运行的可执行程序的名称, PROG_PATH为可执行文件所在的目录,PROG_ARGS为执行程序的各个参数。

solomonxie commented 6 years ago

Linux 用户管理

添加新Admin用户

参考:How to Change Linux User’s Password in One Command Line

假设我们要添加一个用户test:

# 添加用户
$ sudo adduser test

# 根据交互,填写密码和默认信息
#...

# 将用户添加到sudoer权限组
$ sudo usermod -aG sudo test

# 切换到用户
$ su - test

root用户下无交互模式创建新用户test

useradd  -s /bin/bash test
usermod -aG sudo test
echo -e "test123\ntest123" | passwd test
su - test

在本机通过ssh一键添加sudo用户并创建密码:

ssh root@IP 'useradd  -s /bin/bash test; usermod -aG sudo test; echo -e "test123\ntest123" | passwd test' && echo '[ OK ]'

记住,如果是在脚本里面,引号必须用双引号",而不能单引号!

pass="test123"
echo -e "${pass}\n${pass}" | passwd test
solomonxie commented 6 years ago

❖ Linux/Mac 创建Ram Disk内存盘

把内存空间转换为本地使用的硬盘,加速文件读取。适用于处理高并发任务。

如果只是作为临时缓存的话,连数据库存储也可以放到Ram Disk中进行。(但是如果自己手动这样操作,还不如直接用Redis)

所以,参考Redis,内存盘在开发中还有各种的可能性可以供你去创造。

Mac创建Ram Disk

参考:How to Create a 4GB/s RAM Disk in Mac OS X

Mac上,需要用到diskutil命令和hdiutil命令,这个都是默认有的不需要安装:

$ diskutil erasevolume HFS+ 'RAM Disk' `hdiutil attach -nomount ram://204800`

其中ram://00000是代表分配的内存大小,以byte为单位。2048byte为1MB。

image

安装完后就会看到文件夹中多出一个磁盘: image

尝试拷贝个文件后发现:100MB的文件拷贝进去只是一瞬间,连进度条都没有出现!

删除内存盘: 先用df -h找到磁盘的所在位置,比如我的是/dev/disk5, 然后卸除挂载需执行:

hdiutil detach disk5

image

如果报busy,那么就用各种方法关闭相关的文件夹、终端shell等,再来执行。

Ubuntu创建Ram Disk

参考:How to use a ramdisk on Linux

mkdir ~/ramdisk

# 分配/挂载内存盘
sudo mount -t tmpfs -o size=200M tmpfs ~/ramdisk

# 卸载/删除内存盘
sudo umount ~/ramdisk

其中tmpfs是内存,我们随便创建了一个文件夹就可以挂载上去。

可以看到,我们从内存中分了200MB出来作为本地磁盘使用: image

Linux分配内存盘实在太方便了。

开机自动挂载Ram Disk

直接修改/etc/fstab文件,加入以下:

none /home/ubuntu/ramdisk tmpfs nodev,nosuid,noexec,nodiratime,size=200M 0 0

定期备份内存盘

直接在crontab里面添加*/15 * * * * cp -ru /home/ubuntu/ramdisk /home/ubuntu/backup

solomonxie commented 5 years ago

❖ Linux/Unix 编译安装软件源代码的最佳实践 [DRAFT]

Subtitle: Linux / Unix Build Software From Source Code Best Practice

*nix下编译安装开源软件是新手的一大痛。鉴于我胆小怕事、在正式学习前不随便使用新东西的心态,用了Linux很多年后现在才开始正式学习怎么编译一个新版本的开源软件。因为迫于跟不上新版本、包管理器不支持某些硬件平台等原因,现在已经到了不编译不行的地步,所以扛不住了,开始学习!

理解软件编译

源代码下载的话,基本上都是到Github直接下载zip或tar包即可。

常用的需要编译的开源软件主要指C或C++开发的软件。

一般编译这些软件主要有这几步:

Dependency Hell

软件编译的最大问题就是依赖。遇到Dependency Hell,绝对是大概率事件。

/usr/local vs. /opt [DRAFT]

对于自己编译的软件安装到哪里,可以比得上Vim vs. Emacs之争了。

简单来说:

总结

./configure --prefix=/opt/MyProgram && echo [  OK  ]
make && echo [  OK  ]
sudo make install && echo [  OK  ]

每一句是完全隔离是因为这样能更清晰的知道错误出现在哪里。 每一句后面打印[ OK ]是为了更方便看到知道命令是否产生错误。

solomonxie commented 5 years ago

编译安装FFmpeg [DRAFT]

参考官方:Compile FFmpeg for Ubuntu, Debian, or Mint

编译安装FFmpeg不光是需要编译它本身,还需要编译安装一系列的视频处理器。 基本安装步骤:

注意:lib265libaom这两个高清编码器,对于树莓派这种小机器来说还是有点费劲了。所以目前也很难找到正确能编译安装上的方式。

# Download
cd /tmp
wget https://github.com/FFmpeg/FFmpeg/archive/n4.1.tar.gz
tar -xzvf n4.1.tar.gz
cd n4.1*

# Build
./configure --prefix=/opt/ffmpeg-4.1  && echo OK.
make && echo OK.
sudo make install  && echo OK.

MacOS编译问题

Error: nasm/yasm not found or too old.

查看了下本机的yasm版本$ yasm --version,发现是1.3.0。 所以就用homebrew重新安装了一下:

$ brew instlal yasm

得到的版本是1.3.0.1。

solomonxie commented 5 years ago
solomonxie commented 5 years ago

❖ Mac安装包管理器MacPorts:从入门到放弃

安装

MacPorts的pkg安装包经常遇到的问题是:卡住不动。不用想也知道是网络问题。

不过经过多次尝试,最好的做法还是直接自己编译:

# Download
cd /tmp
sudo curl -O https://distfiles.macports.org/MacPorts/MacPorts-2.5.4.tar.bz2
sudo tar xf MacPorts-2.5.4.tar.bz2

# Build
cd MacPorts-2.5.4/
./configure --prefix=/opt/macports-2.5.4   && echo "[ OK ]"
make   && echo "[ OK ]"
sudo make install   && echo "[ OK ]"

# Export Path or Create symlink
echo "export PATH=/opt/local/bin:/opt/local/sbin:$PATH" >> ~/.bash_profile
# or
ln -s /opt/local/bin/port /usr/local/bin/port

更新:

sudo port selfupdate

安装:

sudo port install ffmpeg

体积

在都还没装什么软件的时候(只装了一个ffmpeg),整个macports的目录就高达3.5GB,这个在MBA笔记本上来说实在是太重了!而且编译一个ffmpeg,用了半个小时还没完成,这实在是匪夷所思。 注:和网络没关系,镜像已经设为了国内的。看时间卡住的,纯在Build上。

想着,既然安装一个都这么费劲,还不如自己compile。

solomonxie commented 5 years ago

Apt包管理器常用命令

apt包管理器有很多命令可以使用:

显示已安装的某包具体信息:

$ apt-cache show 包名

显示已用apt-get安装的某包的所有安装位置:

$ dpkg -S 包名
solomonxie commented 5 years ago

❖ Linux 压缩包 [DRAFT]

.zip

解压:unzip FileName.zip 压缩:zip FileName.zip DirName

解压多个文件到各自独立目录: 参考:https://askubuntu.com/questions/518370/extract-several-zip-files-each-in-a-new-folder-with-the-same-name-via-ubuntu-t

for i in *.zip; do unzip "$i" -d "${i%%.zip}"; done

———————————————

.tar

解包:tar xvf FileName.tar 打包:tar cvf FileName.tar DirName (注:tar是打包,不是压缩!) ———————————————

.gz

解压1:gunzip FileName.gz 解压2:gzip -d FileName.gz 压缩:gzip FileName

.tar.gz 和 .tgz

解压:tar xzvf FileName.tar.gz 压缩:tar czvf FileName.tar.gz DirName ———————————————

.bz2

解压1:bzip2 -d FileName.bz2 解压2:bunzip2 FileName.bz2 压缩: bzip2 -z FileName

.tar.bz2

解压:tar xjvf FileName.tar.bz2 压缩:tar cjvf FileName.tar.bz2 DirName ———————————————

.bz

解压1:bzip2 -d FileName.bz 解压2:bunzip2 FileName.bz 压缩:未知

.tar.bz

解压:tar xjvf FileName.tar.bz 压缩:未知 ———————————————

.xz

解压1:xz -d FileName.xz 压缩:

———————————————

.tar.xz

解压1:xz -d FileName.tar.xz && tar -xvf FileName.tar 解压2:tar -xJvf FileName.tar.xz 压缩:

———————————————

.Z

解压:uncompress FileName.Z 压缩:compress FileName .tar.Z

解压:tar xZvf FileName.tar.Z 压缩:tar xZvf FileName.tar.Z DirName ———————————————

.rar

解压:rar x FileName.rar 压缩:rar a FileName.rar DirName ———————————————

.lha

解压:lha -e FileName.lha 压缩:lha -a FileName.lha FileName ———————————————

.rpm

解包:rpm2cpio FileName.rpm | cpio -div ———————————————

.deb

解包:ar p FileName.deb data.tar.gz | tar zxf - ———————————————

.tar .tgz .tar.gz .tar.Z .tar.bz .tar.bz2 .zip .cpio .rpm .deb .slp .arj .rar .ace .lha .lzh .lzx .lzs .arc .sda .sfx .lnx .zoo .cab .kar .cpt .pit .sit .sea

解压:sEx x FileName. 压缩:sEx a FileName. FileName

solomonxie commented 5 years ago

Linux进程管理 [DRAFT]

查看进程

# 常用:
ps aux

# 直接根据进程名查看进程ID:
pgrep zsh

关闭进程

# 关闭单个进程
kill <进程ID>

# 关闭所有进程
pkill <进程名>

# 或
killall <进程名>

# 或
pgrep <进程名> |xargs kill
solomonxie commented 5 years ago

❖ CLI命令行模糊搜索的超强大工具:fzf

参考官方:junegunn/fzf 参考:Fuzzy finder(fzf+vim) 使用全指南 参考:模糊搜索神器fzf

image

无需复杂配置,非常简单就能使用:

git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
~/.fzf/install

安装过程,只是简单的分别在zshrcbashrc等各个shell的配置文件中加入如下内容(已简化):

# 将可执行文件加入PATH
if [[ ! "$PATH" == *~/.fzf/bin* ]]; then export PATH="$PATH:$HOME/.fzf/bin"; fi
# 引入shell中的"**"符号自动补全
[[ $- == *i* ]] && source "$HOME/.fzf/shell/completion.zsh" 2> /dev/null  # Auto-completion
# 引入shell中的快捷键设置
source "$HOME/.fzf/shell/key-bindings.zsh" # Key bindings
# 外观设置(高亮、预览、高度)
export FZF_DEFAULT_OPTS="--height 40% --layout=reverse --preview '(highlight -O ansi {} || cat {}) 2> /dev/null | head -500'"

安装好后,直接调用fzf即可打开搜索。

为了更方便,我们应该在zsh或bash的配置文件中加入alias fzf="~/.fzf/bin/fzf"

输入fzf命令后,自动会显示出搜索框。基本操作命令如下:

使用命令

fzf命令在搜索后,当你选择时,只会返回你这个文件的全路径字符串。也就是:fzf默认会从STDIN读入数据,然后将结果输出到STDOUT

我们当然不能拿字符串来做什么。所以还是要配合各种文字编辑、shell命令等来使用。

用VIM编辑搜索到的结果文件:

$ vim $(fzf)

# 可以将alias设置为:
alias vfzf="vim $(fzf)"

效果如下: v2-54208c2f5675c44dc312827a271743f6_b

切换到某个目录,可以完成切换到当前以下任意目录的效果:

$ cd $(find * -type d | fzf)

# 建议alias设置:
alias dfzf="cd $(find * -type d | fzf)"

每次移动光标,可以快速看到文件预览:

$ fzf --preview 'head -100 {}'

效果如下: image

配置

如果要更方便的使用fzf,而不输入那么多命令,那就直接在shell的配置里加一个环境变量即可。

这个环境变量名叫FZF_DEFAULT_OPTS,所有fzf的配置都写在这一个变量里:

export FZF_DEFAULT_OPTS="--height 40% --layout=reverse --preview '(highlight -O ansi {} || cat {}) 2> /dev/null | head -500'"

由于fzf安装时候会自动在你的zshrcbashrc中加入[ -f ~/.fzf.zsh ] && source ~/.fzf.zsh,不是很直观。如果想更直观更可控,可以直接把.fzf.zsh中为数不多的内容复制到zshrc中集中管理:

# Setup fzf Searching tool {
    # Import binary execution to PATH
    if [[ ! "$PATH" == *~/.fzf/bin* ]]; then export PATH="$PATH:$HOME/.fzf/bin"; fi
    # Import key bindings for auto completion
    [[ $- == *i* ]] && source "$HOME/.fzf/shell/completion.zsh" 2> /dev/null
    # Import specific key bindings
    source "$HOME/.fzf/shell/key-bindings.zsh"
    # Setup appearence (Highlighting, scale, preview...)
    export FZF_DEFAULT_OPTS="--height 40% --layout=reverse --preview '(highlight -O ansi {} || cat {}) 2> /dev/null | head -500'"
# }

搜索语法

solomonxie commented 5 years ago

❖ Linux 搜索工具 [DRAFT]

文件搜索程序候选列表

Mac安装:

brew install fd

Ubuntu安装:

sudo apt-get install fd-find

文本搜索候选列表

测试——在整个Linux内核源码中执行搜索效率:

image

文件搜索:fd命令

fd能实现find的80%功能,速度更快,增加忽略文件功能

Mac安装:

brew install fd

Ubuntu安装:

sudo apt-get install fd-find

常用命令:

- Find files matching the given pattern in the current directory:
    fd pattern

- Find files that begin with "foo":
    fd '^foo'

- Find files with a specific extension:
    fd --extension txt

- Find files in a specific directory:
    fd pattern path/to/dir

- Include ignored and hidden files in the search:
    fd --hidden --no-ignore pattern

文本搜索:ag命令

ag的特点:

Mac安装:

brew install ag

常用命令:

- Find files containing "foo", and print the line matches in context:
    ag foo

- Find files containing "foo" in a specific directory:
    ag foo path/to/folder

- Find files containing "foo", but only list the filenames:
    ag -l foo

- Find files containing "FOO" case-insensitively, and print only the match, rather than the whole line:
    ag -i -o FOO

- Find "foo" in files with a name matching "bar":
    ag foo -G bar

- Find files whose contents match a regular expression:
    ag '^ba(r|z)$'

- Find files with a name matching "foo":
    ag -g foo 

简单一句ag 关键字 ./就搜索当前文件夹,看一下搜索效果:

image

solomonxie commented 5 years ago

Linux 查看CPU温度

每种设备查看温度的方式都不同。

树莓派

无需安装工具即可查看:

cat /sys/class/thermal/thermal_zone0/temp
>>> 62838

# 或者直接以度为单位显示
echo $[$(cat /sys/class/thermal/thermal_zone0/temp)/1000]°
>>> 63

显示数字为千分之一度。所以说,除以1000就是当前温度值。

可以设置watch实时观看:

watch -n 0.1 echo CPU: $[$(cat /sys/class/thermal/thermal_zone0/temp)/1000]°

image

PC

直接查看:

# 查看第一个核心
$ cat /proc/acpi/thermal_zone/TZS0/temperature

# 查看第二个核心
$ cat /proc/acpi/thermal_zone/TZS1/temperature

lm_sensors

Ubuntu:

# 安装
sudo apt-get install lm-sensors -y
yes | sudo sensors-detect
# 运行
sensors
solomonxie commented 5 years ago

<M-e>键的问题

初看,并不明白在键盘上是什么?Google了很久也查不到。最后终于在查关键字Vim Key Notation发现了,原来<M>代表Meta key,在很多终端或平台是不支持的。偶尔有支持的,那就是Alt键。这个时候,它和<A-..>是同样的意思。

但是,自动补全括号中,有一个fast wrap功能,需要用到<M-e>键,即Alt-e键。可是不管怎么按,在insert还是normal模式按,都只会输出一个奇怪符号´,而不执行命令。

为什么? 因为Alt快捷键,在很多Terminal或平台都是不支持的,比如Mac的终端。

经过一番查询,Mac的iTerm2可以将Alt(Option)键映射为Meta键。 位置为:Preference -> Profiles -> Keys -> Left Option key -> ESC+.

image

solomonxie commented 5 years ago

ZSH安装超酷的powerlevel9k主题

网上看到别人的命令行右面竟然有个漂亮的时间戳,非常好奇。搜了下发现竟然是zsh的主题,叫powerlevel9k

image

参考Github官方文档:https://github.com/bhilburn/powerlevel9k

安装

有了Oh my zsh的话就安装非常简单, 如下两步:

色彩问题

安装后有可能会提示你的终端色彩不够256色问题, image

可以找它建议的,直接在~/.zshrc中强制指定终端色彩来解决:

export TERM="xterm-256color"

image

常用配置

默认配置参考官方说明:https://github.com/bhilburn/powerlevel9k/wiki/Stylizing-Your-Prompt 官方推荐的各种用户配置(带各种截图):https://github.com/bhilburn/powerlevel9k/wiki/Show-Off-Your-Config

# ==== Theme Settings ====
# PowerLevel9k
# 左侧栏目显示的要素(指定的关键字参考官网)
POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(os_icon context dir vcs)
# 右侧栏目显示的要素
POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=(status root_indicator background_jobs time virtualenv)
#新起一行显示命令 (推荐!极其方便)
POWERLEVEL9K_PROMPT_ON_NEWLINE=true
#右侧状态栏与命令在同一行
POWERLEVEL9K_RPROMPT_ON_NEWLINE=true
#缩短目录层级
POWERLEVEL9K_SHORTEN_DIR_LENGTH=1
#缩短目录策略:隐藏上层目录中间的字
#POWERLEVEL9K_SHORTEN_STRATEGY="truncate_middle"
#添加连接上下连接箭头更方便查看
POWERLEVEL9K_MULTILINE_FIRST_PROMPT_PREFIX="↱"
POWERLEVEL9K_MULTILINE_LAST_PROMPT_PREFIX="↳ "
# 新的命令与上面的命令隔开一行
#POWERLEVEL9K_PROMPT_ADD_NEWLINE=true
# Git仓库状态的色彩指定
POWERLEVEL9K_VCS_CLEAN_FOREGROUND='blue'
POWERLEVEL9K_VCS_CLEAN_BACKGROUND='black'
POWERLEVEL9K_VCS_UNTRACKED_FOREGROUND='yellow'
POWERLEVEL9K_VCS_UNTRACKED_BACKGROUND='black'
POWERLEVEL9K_VCS_MODIFIED_FOREGROUND='red'
POWERLEVEL9K_VCS_MODIFIED_BACKGROUND='black'

Python的Virtualenv和Pipenv虚拟环境显示问题

一般命令行里,进入虚拟环境的shell时会显示如(venv) ~$这样的。 但是安装这个主题后,默认是没有的。 你必须手动设置添加才行。

方法是: 在POWERLEVEL9K_LEFT_PROMPT_ELEMENTS或者POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS中添加virtualenv要素,就能够显示了。 如:

POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(os_icon context dir vcs virtualenv)

image

但是也有不能正常显示的时候,而且还会报错:

$ pipenv shell
Shell for UNKNOWN_VIRTUAL_ENVIRONMENT already activated.
No action taken to avoid nested environments.

这个不是主题的问题,测试后发现换了主题还是这样显示,所以这是ZSH的问题。 找了半天都没有结果怎么解决。 结果发现,不需任何修改,

只要关闭当前的终端窗口,重新打开就好了。

显示主机型号图标问题

像这种显示当前主机(如Mac)图标和Git图标的问题,是需要字体支持的。

image

默认是不开启的,必须要在~/.zshrc中指定使用这种方式显示:

#字体设定 (注意,字体设定必须放在主题之前)
POWERLEVEL9K_MODE='nerdfont-complete'
#主题设定
ZSH_THEME="powerlevel9k/powerlevel9k"

上面的字体模式可选的有:

根据你的情况来尝试,因为不是每个都能完美无乱码显示出来。

solomonxie commented 5 years ago

ZSH不支持*星号匹配符

Bash中,我们经常会用这些语句:

find . -name *.txt

apt-get remove mysql*

rm /tmp/*.jpg

然后在zsh中,经常会无法解析*通配符,产生这个错误:

zsh: no matches found

解决方法很简单,在~/.zshrc中加入setopt no_nomatch即可。

solomonxie commented 5 years ago

Linux查看某个文件或命令的真实全路径

简单的使用*nix内置命令:realpath

文件/文件夹/链接:

# FILE
$ realpath README.md
/home/pi/project/README.md

# SYMLINK
$ realpath ~/.vimrc
/home/pi/dotfiles/vim/vimrc-mini

命令:

$ which vim
vim: aliased to vim8
$ which vim8
/usr/bin/vim8

$ realpath $(which vim)
/opt/vim-8.1/bin/vim

我们可以看到,在查看命令的位置上,which是不太可靠的,因为它只会显示出链接别名,而不显示真实地址。

solomonxie commented 5 years ago

Busybox的安装包管理器opkg [DRAFT]

opkg是OpenWrt系统下的安装包管理器,相当于Ubuntu的apt,或CentOS的yum,或Mac的Homebrew

使用方法:

# 更新
$ opkg update

# 查看已安装软件
$ opkg list-installed
$ opkg list

# 安装指定软件
$ opkg install 包名

但是,opkg目前只支持少量的软件。如果要查看当前支持哪些软件安装,可以查看这个目录下的各个文件。其中每个文件代表一个提供源:

$ cat /var/opkg-lists/barrier_breaker

$ cat /var/opkg-lists/openwrtio

更改安装源/etc/opkg.conf

参考:OpenWrt.io - opkg 软件源

常用的软件安装:

$ opkg install tcpdump
solomonxie commented 5 years ago

Ranger:帅气强大的命令行文件管理器 [DRAFT]

Ranger是一个极轻量(700k)又像VIM一样高可配置的命令行文件管理器,用起来很多时候比桌面上的文件夹方便多了。

参考:Installing and Using Ranger, a Terminal File Manager, on a Ubuntu VPS 参考官方:ranger/ranger - A VIM-inspired filemanager for the console 参考Luke Smith: RANGER: the aesthetic way to manage files on Linux

为什么要用Ranger? 因为终端里,你可能真的会厌倦了各自cd, cp, mv, rm等等。如果有桌面上那种快捷又直观的方式,加上各自超级方便如Vim的快捷键,你肯定会乐于接受。

Ranger就是这种能给你带来终端里舒服体验的轻量又强大的文件管理器。

image

Mac安装:

$ brew install ranger

Ubuntu安装:

$ sudo apt-get install ranger

运行:

$ ranger

刚刚安装好后,颜色都是默认的:

image

基本使用

通用快捷键:

移动键:

文件夹操作:

文件操作:

Tab标签窗口:

在Shell中cd进入Ranger选中的文件夹路径:

S (大写),ranger就会退出,并且在shell中cd进入该路径。

基本配置

参考详细配置:ranger - Archlinux

首先需要“生成配置文件“:

$ ranger --copy-config=all

然后ranger就会把系统级的配置文件保存的当前用户文件夹下的~/.config/ranger/目录中。其中包括5个配置文件:

色彩配置

如同Vim一样,可以直接按:输入命令,查看效果,确定后再写入配置文件。

设置颜色主题的命令和vim一样:set colorscheme NAME。 默认的主题只有:default, jungle, snow, solarized.

自定义的主题放在~/.config/ranger/colorschemes/文件夹中即可识别。

去哪找主题? 官方并没有推荐任何主题网站,也没有说明任何主题安装方法等。 通过摸索发现,不要搜ranger colorscheme,而是在Github搜索ranger theme即可获得各种主题。

安装第三方主题方法: 只要把xx.py拷贝至~/.config/ranger/colorschemes/文件夹下即可。然后在rc.conf中设定主题名称。

推荐一款主题:RougarouTheme/ranger

image

安装方法:

mkdir -p ~/.config/ranger/colorschemes/
wget https://raw.githubusercontent.com/RougarouTheme/ranger/master/rougarou.py -P ~/.config/ranger/colorschemes/

然后在~/.config/ranger/rc.conf中的主题设定处改为set colorscheme rougarou,重启ranger即可。

插件安装使用

Ranger可以有很多种在命令行下预览图片等文件的方法,这都需要安装第三方程序才行。

参考:ranger的配置与使用

Ubuntu上,可以安装这些插件进行预览:

$ sudo apt-get install caca-utils # img2txt 图片
$ sudo apt-get install highlight  # 代码高亮
$ sudo apt-get install atool     # 存档预览
$ sudo apt-get install w3m        # html页面预览
$ sudo apt-get install poppler    # pdf预览
$ sudo apt-get install mediainfo  # 多媒体文件预览
$ sudo apt-get install catdoc     # doc预览
$ sudo apt-get install docx2txt   # docx预览
$ sudo apt-get install xlsx2csv   # xlsx预览

图片预览 [DRAFT]

image

全真彩色图片的预览,需要第三方的支持:

添加文件图标:ranger_devicons插件

参考官方:alexanderjeurissen/ranger_devicons

image

添加插件方法:

cd /tmp
git clone https://github.com/alexanderjeurissen/ranger_devicons.git
cd ranger_devicons/
make install && echo [  OK  ]

# UNINSTALL
# make uninstall

体验: 非常简单也非常好看。安装方便、卸载方便。虽说是make install,但其实什么都没编译只是自动在rc.conf中加入相应内容而已。

只有一个问题,比如Vim中嵌入了Ranger插件,那么图标就会显示乱码。

solomonxie commented 5 years ago

W3M:超酷的命令行浏览器! [DRAFT]

超酷不是说这个网页浏览器显示效果多酷,而是在命令行终端里浏览网页这件事非常酷!

试想一下: 你可以SSH进远程的服务器,任意浏览服务器“所在地”的网页,而不用建立任何隧道,这是什么体验?

当然,既然是命令行里的,也不要对排版有太大期待。可以说,所有的CSS和JS都是失效的,只是简化版的HTML展示。 但一些常用的功能如填写表格,搜索,链接跳转等,都还是能轻松实现的。

Mac安装:

$ brew install w3m

Ubuntu安装:

$ sudo apt-get install w3m

安装包才2M+,轻量到让我惊讶的地步。

浏览某个网页的方法:

$ w3m google.com

image

默认的情况下,是不会展示网页中图片和视频的,需要我们额外进行配置。

基本操作

参考:文本浏览器w3m

浏览网页图片

修改浏览器属性

有时候我们访问网页,不想让网站知道我们是在用w3m浏览器,而是想让人知道我用的是Chrome浏览器。那么就需要修改User-Agent

修改方法是在~/.w3m/config文件中,找到user_agent处,加入自己想要的agent,如:

user_agent Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36

然后用w3m https://www.whatsmyua.info/命令打开网页,看看自己的User-Agent是不是改了呢。

solomonxie commented 5 years ago

❖ Awesome Linux Lightweight Programs [DRAFT]

Axel 超强超速多线程的下载器 代替wget

Mac安装:

brew install axel

Ubuntu安装:

sudo apt-get install axel

使用:

$ axel <URL>

指定线程数:

$ axel -n 10 <URL>

效果:

image

如果遇到SSL error: certificate verify failed错误,解决方法是-k参数“禁止安全检查“,相当于wget的--no-check-certificate,方法如下:

$ axel -k <URL>
solomonxie commented 5 years ago

Homebrew 备份所有brew安装过的程序

为什么需要备份?

新版Homebrew已经可以很方便的备份所有用Homebrew安装过的程序了。 需要用到Homebrew/homebrew-bundle这个程序。

参考:Homebrew/homebrew-bundle 参考:Restore, Clone or Backup your Homebrew Setup

备份:

# 先安装
brew bundle dump

# 再运行一遍执行
brew bundle dump

这时候,会在当前目录生产一个Brewfile的文件,记录了所有已安装的程序。

大概内容如下:

tap "homebrew/bundle"
tap "homebrew/core", "https://github.com/Homebrew/homebrew-core.git"
brew "autojump"
brew "axel"
brew "ctags"
brew "git"
brew "neovim", link: false
brew "pngpaste"
brew "python"
brew "python@2"
brew "ranger"
brew "reattach-to-user-namespace"
brew "tmux"
brew "w3m"

把它保存在自己备份文件的地方。

恢复安装的时候,只需要进入Brewfile所在文件夹,执行:

$ brew bundle
solomonxie commented 5 years ago

nnn 真正极简主义的命令行文件管理器 [DRAFT]

参考官方:jarun/nnn 参考官方推荐的视频教程:Luke Smith - I'M GOING TO USE THE NNN FILE BROWSER!

image

nnn相对Ranger来讲,界面真的是极简,速度也能感觉到明显提升:完全无卡顿。 nnn真正贴合了命令行里快速浏览文件夹的需求:稳准狠。 nnn的安装又简单又轻量(55K),对各种OS的支持又多到发指。

奇怪的是:nnn是Python开发的,但是速度竟然快到这种程度,是很让人惊讶的。

常用安装: Mac:brew install nnn Ubuntu: sudo apt-get install nnn

安装好后直接输入nnn命令就进入一个小小的文件夹浏览界面了。也可以nnn ~/myfolder进入指定文件夹。

基本操作(类似vim):

文件的选择(类似平常用的Ctrl-c):

文件复制、移动、删除(在已选中文件前提下):

文件重命名:

列表排序:

建议不要按照文件大小排序,否则每次进入目录前都会执行du命令计算所有子文件和文件夹才能进入。

编译安装方法

树莓派Raspbian18.04也不支持nnn,所以试着编译安装。

cd  /tmp
wget https://github.com/jarun/nnn/archive/v2.2.tar.gz
tar xzvf v2.2.tar.gz
cd nnn-*

sudo apt-get install pkg-config libncursesw5-dev libreadline6-dev -y
make
sudo mv ./nnn /usr/local/bin

因为程序极轻量,所以就在原地生成一个nnn单二进制文件,也就是全程序。 然后直接把nnn文件移动到本地自己喜欢到bin目录即可开始用了。

solomonxie commented 5 years ago

❖ Linux下「发送」邮件的命令行应用

发送邮件有超多种方法,但是接收邮件就要麻烦很多。所以这里先只讲发送邮件

先说明下:不管是什么邮件客户端,都是可以直接发邮件的。但是,因为默认的话,发件人是很随便地设置成你本机地名字。并且100%会被邮箱当成垃圾邮件处理。如果你去垃圾箱里找,还是可以看到的。这就是为什么,我们还是需要配置它,让它登录某个邮箱来使用它的身份发邮件了,比如gmail邮箱或阿里云邮箱。(国内的163和qq邮箱都已经屏蔽第三方客户端登录了)

另注:为什么如今这么电子技术这么发达的年代,命令行邮件终端相关的应用和文章还这么少几乎都是很多年前的?我想是因为:python等都已经能很好很方便支持发邮件了,没必要折腾命令行版本。 事实上,试过就知道:为什么这些客户端会被抛弃了。。。请看下面我入的坑:

「Mail」和「Sendmail」

注:Mail的配置相当麻烦,网上找文章也寥寥无几,有也都是十几年前的东西。所以建议放弃,使用更先进的客户端。

「Mutt」

Mutt是Linux邮箱客户端榜上有名的利器了。

注意:这里不介绍Mutt作为邮件客户端的界面操作,而是直接作为命令行的命令来操作。

为什么?因为我们用命令行的邮箱客户端都是用来自动化的,一般来说不太需要终端的邮箱界面。

参考:Linux使用mutt发送邮件

安装

其中mutt是软件本身,msmtp是用来帮助发件的工具。

# Linux
$ sudo apt-get install mutt msmtp

# 或Mac
$ brew install mutt msmtp

配置

你需要配置两个文件,一个是~/.muttrc用来配置Mutt本身,一个是~/.msmtprc用来配置发件人的,需要写入密码一类的。

参考:Linux下使用mutt,msmtp发信

配置~/.msmtprc:

account     Aliyun
host        smtp.aliyun.com
from        jason@aliyun.com
auth        login
user        jason@aliyun.com
password    abcde123123123
account default : Aliyun
logfile ~/.msmtp.log

然后必须修改~/.msmtprc文件的权限,否则程序无法读取,发邮件时会报错。修改如下:

chmod 600 ~/.msmtprc

配置~/.muttrc

set sendmail="/usr/bin/msmtp"
set use_from=yes
set realname="Jason"
set from="Jason@aliyun.com"
set envelope_from=yes
set editor="vim -nw"

注意:第一条set sendmail中的位置不一定是这样的,在Mac和Linux上都会不同,所以需要用which msmtp来找到它的真实位置,再填进去。

关于配置的解释可以看这里: image

发送邮件命令格式

注意:收件人的地址前一定要明确指定参数名--,如下所示。否则无法正确发送附件。

# 常用格式如下 -s   “标题”  -c    抄送  -a  附件
$ echo “HELLO WORLD” | mutt -s “TITLE” -- RECIPIENT@gmail.com

# 发送HTML格式漂亮的邮件
$ mutt -- RECIPIENT@gmail.com -e 'set content_type="text/html"' -s "TITLE" < out.html

# 发送给多人,抄送,添加附件
$ echo "hello" | mutt -s "TITLE" aaa@gmail.com, bbb@gmail.com -c ccc@gmail.com -a /home/pi/pic.jpg address="RECIPIENT@gmail.com"

# 发送邮件时设置邮件的文本类型为:html格式,邮件的等级为:重要
$ echo $content | mutt  -s "${subject}" -e 'set content_type="text/html"' -e 'send-hook . "my_hdr  X-Priority: 1"' $address

语法: image

参数: image

Mutt发送HTML漂亮富文本邮件

默认语法是:

$ mutt -- RECIPIENT@gmail.com -e 'set content_type="text/html"' -s "TITLE" < out.html

但是,值得注意的是,语法虽然简单,可一旦你本机的mutt版本不对,邮件将无法显示出正确的格式,而只是无尽的html源代码。 通过mutt -v可以看到,发送出显示正常的邮件的mutt版本是在树莓派上安装的Mutt 1.5.23 (2014-03-12)。而不成功的是在Mac上的Mutt 1.9.5 (2018-04-13),反而是最新的版本!

邮箱配置

solomonxie commented 5 years ago

❖ 正式的介绍「Mutt」:命令行的邮件大师 (一文详解)

为什么要用Mutt? 这个世界已经有了成百上千的漂亮邮件客户端,为什么还要用命令行里的? 其实说什么功能都没用。说到本质上,其实是一种Geek精神,一种爱折腾的精神,一种Customizability的精神。就像明明有WhatsApp,还要用IRC一样的精神;明明有Finder,还要用Ranger的精神。 在终端里待久了,会比较烦GUI,所以不管什么软件都会寻求终端的替代方案。 对于这个需求来说,在Linux的世界里,似乎就只有一个选择:Mutt。

Mutt的可配置性,强如Vim。配置起来也和Vim差不多,有专门的~/.muttrc供你配置软件本身。

需要理解的是:Mutt本身是一个框架而已。收件、发件、编辑邮件等功能,是要通过搭配不同的程序来做到的。

Mutt的模块搭配方案

就像穿衣搭配一样,收件发件过滤邮件转发邮件各种功能都有很多种程序可以用,mutt怎么搭配呢? 常用选项有这些(User/Transport/Delivery):

参考邮件代理(功能分类):Email agent (infrastructure) - Wikipedia

一般搭配是:

但是maildrop不支持Mac,而procmail比较通用一点。所以这里我们用: mutt + fetchmail + msmtp + procmail

安装:

# Mac
$ brew install mutt fetchmail msmtp procmail

# Ubuntu
$ sudo apt-get install mutt fetchmail msmtp procmail -y

Mutt或各个写协作程序在配置前都是不能使用的,学习曲线还是比较陡峭的,所以要做好准备去花好一段去了解和学习各个部件。

大概的配置流程是:

注意:初学过程中,不要一上来就配置mutt。最好是先从各个部件开始:收件->过滤邮件->阅读邮件->发件->mutt界面,按照这种顺序。

配置参考: 参考Arch Wiki:Mutt (极详细,但对人类不友好) 参考Youtube:Mutt - Email for everyone (nerds like me)

收件:配置Fetchmail

Fetchmail是由著名的《大教堂与集市》作者 Eric Steven Raymond 编写的。

Fetchmail是一个非常简单的收件程序,而且是前台运行一次性运行的,意思是:你每次手动执行fetchmail命令,都是在前台一次收取完,程序就自动退出了,不是像一般邮件客户端一直在后台运行。

注意:fetchmail只负责收件,而不负责存储!所以它是要调用另一个程序如procmail来进行存储的。

fetchmail的配置文件为~/.fetchmailrc。然后文件权限最少要设置chmod 600 ~/.fetchmailrc

参考:Using Fetchmail to Retrieve Email

比如我们要设置多个邮箱账户同时收取,那么配置如下:

poll pop.AAA.com protocol POP3 user "me@AAA.com" password "123"
poll pop.BBB.com protocol POP3 user "me" there with password "123" is falko here fetchall
poll pop.CCC.com protocol POP3 user "me" there with password "123" is till here keep
poll pop.DDD.com
  protocol POP3
  user "me"
  password "123"

# 全局选项
mimedecode
mda "/usr/local/bin/procmail"

其中,

配置完成后,可以运行fetcmail -v来看看是否有错误信息,如果能够正常显示很多行的收取信息,那么就能正确登录邮箱收取了。

一般收取的命令如下:

# 只收取未读邮件
$ fetchmai

# 收取所有邮件
$ fetchmail -a

# (重要)收取新邮件,但不在服务器端删除已经收取的邮件
$ fetchmail -k

但是fetchmail只负责收取,不负责“下载”部分,你找不到邮件存在哪了。 所以还需要配置MDA分类器,如procmail,才能看到下载后的邮件。

注意:Fetch其实不是在Mutt“里”使用的,而是脱离mutt之外的!也就是说,Mutt只负责读取本地存储邮件的文件夹更新,而不会自动帮你去执行fetchmail命令。

你必须自己手动执行,或者用Crontab定期收取,或者设为Daemon守护进程,还可以在Mutt中设置快捷键执行Shell命令。

设置Mutt快捷键收取邮件的方法是在~/.muttrc中加入macro:

macro index,pager I '<shell-escape> fetchmail -vk<enter>'

这样的话,你就可以在index邮件列表中按I执行外部shell命令收取邮件了。

邮件过滤:配置Procmail

Procmail是单纯负责邮件的存储、过滤和分类的,一般配合fetchmail收件使用。

在Pipline中,fetchmail把收到的邮件全部传送到Procmail进行过滤筛选处理,然后Procmail就会把邮件存到本地形成文件,然后给邮件分类为工作、生活、重要、垃圾等。

当然,分类规则是自己可以指定的。可以根据发信人、主题、长度以及关键字 等对邮件进行排序、分类、整理。

参考:Procmail

Procmail 的配置文件是 ~/.procmailrc ,记得改权限:chmod 600 ~/.procmailrc。 内容也非常简单,前面是邮件位置、日志等默认选项,后面则是一块一块的过滤规则。

基本配置:

MAILDIR=$HOME/Mail   #邮件存储地址
DEFAULT=$MAILDIR/inbox   #默认:收件箱
VERBOSE=off
LOGFILE=/tmp/procmaillog

# 某个垃圾邮件规则
:0
* ^From: webmaster@st\.zju\.edu\.cn
/dev/null    #垃圾文件的存储位置

# 其它所有都存到收件箱中
:0:
inbox/

其中,$HOME/Mail是设定的邮件存储位置。 我们需要手动创建mkdir ~/Mail,否则程序会报错。

配置好后,我们再测试一下,假设邮箱里有一封未读邮件,就会看到:

$ fetchmail
1 message for Jason@aliyun.com at pop3.aliyun.com (7833 octets).
reading message Jason@aliyun.com@pop3.aliyun.com:1 of 1 (7833 octets) flushed

$ tree ~/Mail
/Users/Jason/Mail
└── inbox
    ├── cur
    ├── new
    │   └── 1549706227.89809_0.Jason-mba.lan
    └── tmp

可以看到,一封新邮件保存到了~/Mail/inbox/new/中,文件为1549706227.89809_0.Jason-mba.lan。但是手动打开以后是这样的:

image

这个实际上就是邮件的真面目:MIME格式(协议)的邮件源码。就像HTML一样,展示给我们的和背后的源码不一样。

那么怎么把这个类似HTML的MIME格式邮件解析为我们人能读懂的内容呢? 这个我们就要靠mutt自己了,mutt自身具备基本的MIME邮件解析功能(不包括HTML格式邮件读取)。

但是这里我们先不讲邮件阅读的问题,把它留在最后。

发件:配置msmtp

msmtp是作为替代sendmail发邮件程序的更好替代品。 msmtp的配置文件为~/.msmtprc,记得改权限:chmod 600 ~/.msmtprc 配置内容比收件还简单,因为发件永远比收件简单。

Tip: 发件的服务器是smtp协议。收件才是pop3协议。

基本配置:

account default
  auth login
  host smtp.XXX.com
  port 587
  from ME@XXX.com
  user ME
  password passwd
  tls on
  tls_certcheck off

logfile /tmp/msmtp.log

其中注意,关于tls,如果是阿里云则不用写,如果是Outlook的话,必须写:

    tls on
    tls_starttls on
    tls_certcheck off

主界面:配置Mutt

Mutt的配置文件为~/.muttrc,记得改权限:chmod 600 ~/.muttrc

另外:mutt的配置文件还可以放在~/.mutt/muttrc。这种方法有一个好处,即~/.mutt/目录下可以放很多主题、插件等文件。

基本配置:

# 通用设定
set use_from=yes
set envelope_from=yes
set move=yes    #移动已读邮件
set include #回复的时候调用原文
set charset="utf-8"
auto_view text/html   #自动显示HTML

# 发送者账号
set realname="Solomon Xie"
set from="solomonxie@aliyun.com"

# 分类邮箱
set mbox_type = Maildir #Mail box type
set folder = "$HOME/Mail"
set spoolfile = "$HOME/Mail/inbox" #INBOX
set mbox="$HOME/Mail/seen"  #Seen box
set record="$HOME/Mail/sent"  #Sent box
set postponed="$HOME/Mail/draft"  #Draft box

# 关联程序(需要自己用which命令确定一下)
set editor="vim -nw"
set sendmail="/usr/local/bin/msmtp"

极简配置

综合上面的四大配置文件,下面是我的四个文件的极简配置:

image

另外可参考网友的极简配置:https://gist.github.com/iharsuvorau/45a078ecb597eb916fdf

现在我的目的是先让收发件运行起来,至于界面美化、快捷键设定等,我们以后再说,里面很有学问。

确认邮箱服务器有没有问题

即使上面配置一切OK,也不一定能正常收发邮件。因为你用的Gmail、QQ、网易、阿里云等等,后台都有一系列的第三方收取设置。这是各不相同的。

比如QQ和网易,现在几乎已经不能用了(2019),为什么?因为它们完全阻止了第三方客户端收发件。即使你去后台设置面板,可以通过手机短信验证之类设置,但是会发现实际上总是验证不了总是通过不了。所以本质上,他们只允许自己的官方客户端不允许任何别的手机、PC客户端(流氓行径)

Gmail在国内用不了众所周知。现在比较好用的只有阿里云和微软的Outlook了。

除了第三方客户端的允许,我们还要设置POP。最好放开全部邮件或者最近30天,然后禁止客户端删信。这是什么意思呢?POP默认客户端在收件后,服务器上的邮件就自动删除了!这个不太合适,所以必须要禁止

例如阿里云邮箱:

image

Mutt主界面的基本操作

参考:How to Use the Fast and Powerful Mutt Email Client with Gmail 参考Youtube:mutt - Terminal Email Client - Linux TUI

邮件列表操作:

在邮件中的操作:

使用命令操作

Mutt如同Vim一样,不光可以把命令绑定为快捷键,还能直接输入:直接输入命令。 但是稍有不同的是,Mutt称之为Action,而且需要用:exec <命令>这样格式执行。

比如sidebar侧边栏的移动,命令是:sidebar-next, sidebar-prev。 那么我们可以直接输入:exec sidebar-next,按下回车执行。

参考:https://gitlab.com/muttmua/mutt/wikis/MuttFaq/Action

Mutt乱码问题

一般分为:

无论~/.muttrc中怎么设置charset=utf-8都没用。

这个时候,先在mutt中输入命令查看软件当前的charset设置::set &charset ?charset 如果显示的是charset="us-ascii",那么就没错,ascii绝对不会显示中文。必须要utf-8等其它unicode格式才行。

但是为什么muttrc中设置charset没用呢?

测试了下,在MacOS、Ubuntu中同时设置一样的配置,Ubuntu正常显示中文,MacOS却不能。 在Ubuntu中输入测试的命令,显示出charset="utf-8";而MacOS里无论iTerm2或Terminal,都是显示us-ascii,且乱码。

问题就变成了:为什么muttrc中的charset不生效?

locale大法: 在命令行里分别输入$ locale命令,查看Shell中的语言设置,发现,我在Mac中的Locale是:

↳ $ locale
LANG=
LC_COLLATE="C"
LC_CTYPE="en_US.UTF-8"
LC_MESSAGES="C"
LC_MONETARY="C"
LC_NUMERIC="C"
LC_TIME="C"
LC_ALL=

而Ubuntu中的确是:

↳ $ locale
LANG=en_GB.UTF-8
LANGUAGE=
LC_CTYPE=en_GB.UTF-8
LC_NUMERIC="en_GB.UTF-8"
LC_TIME="en_GB.UTF-8"
LC_COLLATE="en_GB.UTF-8"
LC_MONETARY="en_GB.UTF-8"
LC_MESSAGES="en_GB.UTF-8"
LC_PAPER="en_GB.UTF-8"
LC_NAME="en_GB.UTF-8"
LC_ADDRESS="en_GB.UTF-8"
LC_TELEPHONE="en_GB.UTF-8"
LC_MEASUREMENT="en_GB.UTF-8"
LC_IDENTIFICATION="en_GB.UTF-8"
LC_ALL=

也许问题就出在这里:Shell的设置出了问题,而不是mutt的设置!

解决方法很简单:

$ export LANG=en_US.UTF-8

然后再输入locale命令就可以看到正常的语言编码设置了。 再打开mutt也是正常显示。

但是直接这样export是临时的,需要把这个加入到~/.zshrc~/.bash_profile中。

HTML网页格式邮件的浏览

参考:https://debian-administration.org/article/75/Reading_HTML_email_with_Mutt 参考:https://fiasko.io/projects/htmail-view.html.en 参考:http://jasonwryan.com/blog/2012/05/12/mutt/

大概两步:

普通的邮件,内容只是单纯的text/plain格式,这样我们不用渲染直接看就行。但有的邮件为了美化,往往用text/html的格式展现,这就很麻烦,因为看到的都是html代码。 所以遇到HTML格式的邮件,我们需要做的是利用第三方软件来Render(渲染).

渲染的问题涉及到两个问题需要解决:

HTML源码翻译成文字非常好解决,只要利用w3m等命令行浏览器即可完成,非常轻量非常简单非常快感受不到有它的存在,可以直接在mutt中查看。 但是图片就有些问题了:图片在终端里展示,一直是个问题。虽然可以达到,但是需要配置很多东西。所以有人为了图方便,遇到HTML格式邮件,就直接弹出chrome网页来看(不推荐)。这样说实话,就没什么意义了。

常用的HTML渲染为Text的方式有:

常用的图片显示方法有:

w3m渲染

brew install w3m后,就得到了一个命令行里的浏览器。

然后我们需要配置两个mutt配置文件。

~/.muttrc添加这两行:

auto_view text/html # View HTML automatically
alternative_order text/plain text/enriched text/html # save html for last

~/.mailcap添加这一行:

text/html; w3m -I %{charset} -T text/html; copiousoutput;

然后重新打开mutt,再打开一个html格式的邮件就发现,内容已经很好的转换成人可读的text格式了。 当然,这时候还不能看图片。

关于mutt图片渲染的问题,我们留到另一篇专门说明。

solomonxie commented 5 years ago

Mac上用Homebrew管理服务(守护进程) [DRAFT]

Mac上的后台服务或守护进程和Linux上有很大不同,为了减少学习曲线,我们可以直接Homebrew帮忙轻松设置服务。

brew services一开始没有,但是第一次使用这个命令的时候,Homebrew就会自动下载安装。

常用命令:

理解brew services

MacOS管理开机启动的服务,是采用系统内置的launchctl命令,Homebrew只是调用了这个程序,帮我们自动安装服务而已。但这也省去了不少自己配置服务的麻烦。

我们可以输入launchctl list命令,查看当前MacOS中已经安装的服务列表。 如果Homebrew已经帮我们安装了一些服务,那么运行这个列表,就会看到类似这种名称的服务:

image

参考:使用 brew services 管理后台服务(MacOS) 参考:brew services 原理解析,如何查看 brew services 列表?

MacOS设置服务的方法,实际上是在~/Library/LaunchAgents/这个目录下放置一个一个的*.plist文件,每个plist,都是一个服务。而服务的具体配置如启动位置、启动顺序等,都是在这个XML格式的plist文件中配置。

如果不想了解手动的配置方法,就直接使用brew services即可。当然,前提是程序是用homebrew安装的,且程序支持brew services配置。如果不支持,那么只能自己手动做了。

手动的方法就是用launchctl程序指定plist文件位置控制,如launchctl load 文件位置来启动服务,用launchctl unload 文件位置来停止服务。

参考:使用 Homebrew 管理 Mac 的后台服务.md

安装常用的程序

常用程序有:

solomonxie commented 5 years ago

Mutt美化指南 [DRAFT]

Mutt配置主题

Mutt主题配置非常简单:下载主题文件,然后在~/.muttrcsource /path/to/file引用这个主题,完成!

例如,我们用著名的Gruvbox主题:https://github.com/altercation/mutt-colors-solarized

下载各种文件后,挑一个dark或light主题,比如mutt-colors-solarized-dark-256.muttrc,然后,比如我们放到~/目录下。然后编辑~/.muttrc,在里面加一句:

source ~/.mutt/mutt-colors-solarized-dark-256.muttrc

重新打开mutt即可看到效果。

image

Sidebar 侧边栏设置

侧边栏可以在~/.muttrc中一句set sidebar_visible = yes就开启侧边栏。 但是,默认侧边栏是空的!必须要我们手动在muttrc中添加才行。

比如:

# Account Settings
mailboxes Personal \
          +jeff@jeffjewiss.com/INBOX \
          +jeff@jeffjewiss.com/archive \
          +jeff@jeffjewiss.com/github \
          +jeff@jeffjewiss.com/newsletters \
          +jeff@jeffjewiss.com/sent \
          +jeff@jeffjewiss.com/drafts \
          Gmail \
          +jeffjewiss@gmail.com/INBOX \
          +jeffjewiss@gmail.com/archive \
          +jeffjewiss@gmail.com/sent \
          +jeffjewiss@gmail.com/drafts \
          Work \
          +jeff@tallarium.com/INBOX \
          +jeff@tallarium.com/archive \
          +jeff@tallarium.com/sent \
          +jeff@tallarium.com/drafts \

然后就会显示出类似这种效果:

image

侧边栏的操作:

这个没有默认的快捷键,需要自己手动设置才能有。

示例:

    bind index,pager <up> sidebar-prev
    bind index,pager <down> sidebar-next
    bind index,pager <right> sidebar-open

    # Use 'B' to switch the Sidebar on and off
    bind index,pager B sidebar-toggle-visible

这样设置的话,Up/Down用来上下选择侧边栏的文件夹,Right键进入选中的文件夹。B用来开关侧边栏。

邮件列表美化

列表的排序,默认是从旧到新,但是一般我们习惯从新到旧。所以我们在muttrc中设置如下:

    set sort=threads
    set sort_browser=date
    set sort_aux=reverse-last-date-received

效果如下:

image