#9 zsh: you have running jobs.

2021-09-09

我定义了一个 gitg 的快捷方式:

function _new_gitg () {
    # alias g='gitg --all >/dev/null 2>&1 &'  # 覆盖 g=git
    if [ -z "$1" ]; then
        nohup gitg --all >/dev/null 2>&1 &!
    else
        nohup gitg -s $1 >/dev/null 2>&1 &!
    fi
}
alias g='_new_gitg'

但是每次退出 shell 会有提示:zsh: you have running jobs.

我就加上 nohup,以为不会有提示,但提示依旧(不过强制退出也不会关闭 gitg 就是了)。

在 SO 上搜到相同问题,这个答复就可以很好的解决我的问题:

If you want to not see that message, simply pass the job id to disown, like so:

> disown %1
> ```
> Or, start the job with &! (zsh-specific trick):
> ```sh
> nohup ./my_script.sh &!
> ```

```sh
function _new_gitg () {
    if [ -z "$1" ]; then
        nohup gitg --all >/dev/null 2>&1 &!
    else
        nohup gitg -s $1 >/dev/null 2>&1 &!
    fi
}
alias g='_new_gitg'

经过测试,这个技巧在 bash 5.1.4 下也有效。

#8 使用 nohup 的一个小问题

2021-07-22
function fq () {
    # ...
    nohup qv2ray &>> /tmp/qv2ray.log &
    # ...
}

每次关闭终端,qv2 就一起崩溃了。

然后我改成:

nohup sh -c "qv2ray &>> /tmp/qv2ray.log &"

就好了。

分析:可能是后面日志和改后台运行的部分被 nohup 拿走的缘故吧。

#7 高效搜索日志

2020-07-22

即便上了 ELK,也不可能所有日志往里面塞,搜日志是程序员的日常工作之一。

grep log by time efficiently 为关键词搜到 SO 上的这个问题: What is the most efficient way to extract logs between two time stamps?

要求:

  1. 能够过滤出指定时间段日志
  2. 效率,保证即便是大日志也不至于等太久,减少对服务的不良影响

提问的人自己提出来的方案:

grep -a -A 1000000 "03/09" fileName.txt | grep -a -B 1000000 "03/10"

他认为不好,因为有点慢,而且有时会漏掉一些日志。
漏掉日志可能和他的日志格式有关,这倒应该问题不大,主要是这个方案看起来就确实效率不行。
PS:如果不用模式匹配,可以加上 -F,应该可以提高效率。

# 2020/07/22 10:00:00,100 INFO [main] com.example.LoggingApplication - Starting Application
awk '$2>="16:30:00"{s=1} s; $2>="17:00:00"{exit}' event.log

这个看起来很牛逼,主要是有一个 exit

#6 Shell 转义

2020-07-21

这篇文章不是要记录那些乱七八糟的转义规则,而是讲怎么借助工具避开它。

GitHub 上偶然看到一个仓库 chrissimpkins/shellescape,做了些实验之后,发现非常好用。
别看就几行代码,真的感觉世界都清静了。
PS:代码我没细看,人生短暂,我不想去记这些没用的知识点。

import re

_find_unsafe = re.compile(r'[^\w@%+=:,./-]').search

def quote(s):
    if not s:
        return "''"
    if _find_unsafe(s) is None:
        return s
    return "'" + s.replace("'", "'\"'\"'") + "'"

示例:

commands = """
grep -F '"userId": "1"' /tmp/test.log
grep 'aaa.bbb.$100.*' /tmp/test.log
""".strip().splitlines()
for command in commands:
    print(quote(command))

#5 Shell 小技巧

2020-07-20

快速输入上一行命令的最后一个参数

touch nihao.txt
code !$

创建目录并进入

take xxx # oh-my-zsh

mkdir xxx && cd $_

重命名

for i in {0..100}; do touch aaa_bbb_$i.jpg; done
rename 's/_bbb//' aaa_*.jpg

# for zsh
autoload zmv
zmv -n '(*)_(*).jpg' '$2_$1.jpg'

#4 Shell 历史

2020-01-07

参考: https://en.wikipedia.org/wiki/Comparison_of_command_shells

Linux Shell

  • Thompson shell (sh), 1971, Unix v1 - v6
    只存在历史中
    在 Bourne shell 之前,贝尔实验室还出了一个 Mashey shell,只出现在 1976 年的 PWB UNIX 中(所以又叫 PWB shell),没有大范围使用
  • Bourne shell (sh), 1977, Unix v7
  • C shell (csh), 1978 img
  • TENEX C shell (tcsh), 1983 img
    是 TENEX 系统开发的 csh 兼容 Shell
  • Korn shell (ksh), 1983 img
  • Bash, 1989 img
  • Almquist shell (ash), 1989 img
  • zsh, 1990 img
  • Debian Almquist shell (dash), an ash fork, 1997
    主体随 ash 是 BSD 协议,不过,可能是为了保持对 bash 的兼容,采用了 bash 项目的一个文件
  • fish, 2005 img

分类

  • ksh, bash, zsh, ash, dash 都是 Bourne shell 兼容。
  • csh, tcsh 就是 csh 兼容。
  • fish

说明

  1. Unix 上的 sh 有版权问题, 所以 BSD 和 Linux 上的 /bin/sh 都指向某一种兼容 Shell (一般是默认 Shell)
  2. RHEL/CentOS 上,默认 Shell 是 Bash
  3. Debian/Ubuntu 上,默认 Shell 是 Dash
  4. FreeBSD 上默认采用 tcsh, 基于 FreeBSD 的 GhostBSD 采用 fish
  5. OpenBSD 上默认采用 pdksh (pd: Public Domain), 不知道和 tsh 什么关系。可能是 OpenBSD 维护的 tsh 兼容 Shell。
  6. NetBSD 上默认采用 ash
  7. 由于 ash 非常轻量级,BusyBox 采用了 dash fork
    然后 BusyBox 被 Alpine Linux, Tiny Core Linux 或者其他嵌入式 Linux (比如 OpenWrt) 采用,所以这些系统的默认 Shell 应该就是 ash

所以可能使用最广泛的 Shell 是 ash 和 bash。

其他:MacOS 上曾经默认采用 bash, 后来专向了 zsh

Windows 平台

  • command.com, 1980
  • cmd.exe, 1993
  • PowerShell, 2006

#2 Web 保存数据的特殊方案

2018-11-08

将数据通过编码存在图片里面,实现导出导入功能。
虽然我不知道什么场景下需要使用这个方案,但这个想法特有意思。