#164 Linux: find 命令

2016-07-29

目录

  • -path
  • -prune 不进入指定目录
find . -path ./.git -prune -o -print
find . -path ./.git -prune -o -path ./build -prune

目录深度

如果使用这几个参数,那么这个参数应该放到最前面

  • -depth
  • -maxdepth 最大迭代深度
  • -mindepth 最小迭代深度

文件名

  • -name
  • -iname

正则

  • -regex
  • -iregex
find ./apps/api/ -maxdepth 3 -regextype "posix-egrep" -regex ".*/(vpc.py|server.py)"

空目录/空文件

# 空目录
find . -type d -empty
# 删除空目录
find . -type d -empty -delete
find . -type d -empty -exec rmdir {} \;

# 空文件
find . -type f -size 0c
find . -type f -empty
# 删除空文件
find . -type f -empty -exec rm {} \;
find . -type f -empty | xargs rm -f
# 如果文件名中有空格,0 是很有必要的
find . -type f -empty -print0 | xargs -0 rm -f
# 交互式
find . -type f -empty -ok rm -rf {} \;

类型

选项:b, c, d (目录), p, f (文件), l (链接), s (Socket), D

用的多的还是目录和文件查找:

  • -type d
  • -type f

大小过滤

可用单位:b (块,512B,默认), c (Byte), w (字,2B), k , M, G

说明:+n, -n, n 分别表示大于,小于,等于。这个规则对 -amin (距离上次访问分钟数), -mtime (距离上次编辑天数), -gid, -inum (inode 数), -links (硬链数), -size, -uid, -used 有效。

大于/小于 10M 的文件:

find . -maxdepth 1 -type f -size +10M
find . -maxdepth 1 -type f -size -10M

# 列出小于三兆的 mp3 文件
find ~/Music -name '*.mp3' -size -3M -ls

权限过滤

# 精准匹配
find . -type f -perm 755 -iname "*.md" -exec chmod 644 {} \;
# 与:u g o 都有执行权限,最低权限判断
find . -type f -perm -111 -iname "*.md" -exec chmod 644 {} \;
# 或:u+x | g+x | o+x 满足一个条件即可
find . -type f -perm /111 -iname "*.md" -exec chmod 644 {} \;

# 这几个参数可以注意一下:
# -writable
# -readable
# -executable
find . -type f -executable -ls

时间过滤

创建和访问时间:

  • -amin 访问时间(分钟)
  • -atime 访问时间(天)
  • -cmin 创建时间(分钟)
  • -ctime 创建时间(天)
  • -mmin 修改时间(分钟)
  • -mtime 修改时间(天)

值得注意的是,上面按天为单位的那些时间过滤参数是按整除来算的,比如:find $HOME -mtime 0,表示一天以内,应为修改时间整除 24 小时为 0 的就是 24 小时以内。

还有一个参数 used,好像是文件状态变更之后的访问时间。

PS: 关于三种时间的差异,参考:2015-01-03 Linux 时间: atime, mtime, ctime

执行命令

  • -print 默认行为,打印文件名

使用 ls 参数

-lsls 命令一样,列出详细信息

find . -name '*.py' -ls

find $HOME -maxdepth 1 -type d -ls

# ls 输出非 ASCII 字符会转义,对中文环境不友好
find $HOME -maxdepth 1 -exec ls -ldh {} + | column -t

使用 delete 参数

find . -maxdepth 1 -type f -name '*~' -delete
find . -maxdepth 1 -type f -name '*.pyc' -delete

使用 exec 参数

find . -type f -exec chmod 644 {} \;
find . -name "*.php" -exec mv {} ~/codes/php \;

find . -type d -name "__pycache__" -exec rm -rf \;
find . -type d -name "__pycache__" -exec rm -rf {} +
find . -type d -name "__pycache__" -depth +4 -print0 -exec rm -rf {} +

联合 xargs 命令:

find . -type d -empty -print0 | xargs -0 -I {} /bin/rm -rf "{}"
find /var/cache/TheSunProject/ -type d -name "backup_*" -print0 | xargs -0 -I {} /bin/rm -rf "{}"
find . -type d -mtime +30 -print0 | xargs -I dir -0 /bin/rm -rvf "dir" > /tmp/delete.log

大部分时候,我们都是用 \; 结果,但其实是有两种方案的:

  • -exec command ; Shell 中,分号需要转义 (\;)
    总是成功返回
  • -exec command +
    一次提供所有参数
echo "import sys; print('>>> %r <<<' % (sys.argv[1:], )); exit(2)" > /tmp/a.py
mkdir -p /tmp/a; cd /tmp/a; touch a " b c " "d;" e;
find . -type f -exec python /tmp/a.py {} \;
# >>> ['./ b c '] <<<
# >>> ['./e'] <<<
# >>> ['./a'] <<<
# >>> ['./d;'] <<<
echo $?
# 0
find . -type f -exec python /tmp/a.py {} +
# >>> ['./ b c ', './e', './a', './d;'] <<<
echo $?
# 1

复杂逻辑

参考手册中 OPERATORS 一节:

  • ( expr ) 在 shell 中括号需要转义
  • expr1 expr2
  • expr1 -a expr2
  • expr1 -and expr2
  • expr1 -or expr2
  • expr1 -o expr2
  • -not expr
  • ! expr
  • expr1 , expr2

排除

find . -path ./.git -prune -false -o -type f
find . -name .git -prune -false -o -used -7 -type f -print
find . -type d \( -name .git -o -name node_modules -o -name build \) -prune -false -o -print

#163 转载:性能测试应该怎么做?

2016-07-08

偶然间看到了阿里中间件Dubbo的性能测试报告,我觉得这份性能测试报告让人觉得做这性能测试的人根本不懂性能测试,我觉得这份报告会把大众带沟里去,所以,想写下这篇文章,做一点科普。

#162 高效的代码部署 [编辑中]

2016-07-08

对于一个服务来讲,代码部署的速度和便捷性并不是一件很要紧的事情。但是对于开发者来说,能够高效部署代码,还是能够在一定程度上提升自己开发和测试的效率。

#160 逻辑运算与位运算

2016-07-01

逻辑运算,一共十六种结果:

  1. 0 矛盾 F
  2. 1 恒真 T
  3. p
  4. q
  5. not p
  6. not q 非 not
  7. p and q 与 and
  8. p or q 或 or
  9. p xor q 异或 xor(相异为 1,相同为 0)
  10. not (p and q) 与非 nand
  11. not (p or q) 或非 nor
  12. not (p xor q) 异或非 xnor(又叫同或,相同为 1,相异为 0)**
  13. (not p) and q 逆非蕴含
  14. p and (not q) 实质非蕴含
  15. (not p) or q 实质条件
  16. p or (not q) 逆命题

基础运算符:与、或、非、异或。

逻辑运算有与或非:&&, ||, !
按位运算有与或非和异或:&|~^

| 按位运算 | 运算符 |
| -------- | ------ | --- |
| 与 | & |
| 或 | | |
| 非 | ~ |
| 异或 | ^ |

参考资料与拓展阅读

#158 Linux 创建用户帐号

2016-06-28

概念

  • 用户
  • 用户组
  • ACL
  • SELinux

useradd 命令

sudo useradd testuser -m -d /home/testuser -s /bin/bash

如果忘记加上 -m 参数,那就只好手动创建用户主目录(家目录):

sudo mkdir /home/testuser
sudo cp -rT /etc/skel /home/testuser
sudo chown -R testuser:testuser /home/testuser

此外,修改用户信息可以使用 usermod 命令:

sudo usermod -d /home/testuser
sudo usermod -s /bin/bash
$ tail -1 /etc/passwd
testuser:x:1001:1001::/home/testuser:/bin/bash

adduser 命令

就相当于封装了比较低级的 useradd 命令,除了执行上面的全部操作,还提供更多的配置项。

# 创建普通的用户帐号
sudo adduser testuser2

# 创建不能用于登录的系统帐号
sudo adduser --system share
$ tail -2 /etc/passwd
testuser2:x:1002:1002:Test User,303,15812345678,02788888888,hello world:/home/testuser2:/bin/bash
share:x:131:65534::/home/share:/bin/false

“Test User,303,15812345678,02788888888,hello world” 这一串是创建过程中让你输入的 “全名”、“房间号”、“工作电话”、“家庭电话”、“其他”,最后逗号隔开,放在 /etc/passwd 文件的注释字段里面。

用户组

addgroup
groupadd
groupdel
groupmems
groupmod
groups

#156 利用 Nginx 做正向代理

2016-06-26

HTTP 代理

server {
    resolver 223.5.5.5;
    listen 80;
    location / {
        proxy_pass http://$host$request_uri;
        proxy_buffers 256 4k;
        proxy_max_temp_file_size 0k;
        proxy_connect_timeout 30;
        proxy_send_timeout 60;
        proxy_read_timeout 60;
        proxy_next_upstream error timeout invalid_header http_502;
    }
}

server {
    resolver 223.5.5.5;
    listen 443;
    location / {
        proxy_pass https://$host$request_uri;
        proxy_buffers 256 4k;
        proxy_max_temp_file_size 0k;
        proxy_connect_timeout 30;
        proxy_send_timeout 60;
        proxy_read_timeout 60;
        proxy_next_upstream error timeout invalid_header http_502;
    }
}

proxy_cache_path /data/Resources/PyPI/ levels=1:1:1 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;

server {
    location /pypi/ {
        proxy_cache pypi_cache;
        proxy_cache_revalidate on;
        proxy_cache_min_uses 3;
        proxy_cache_use_stale error timeout updating
                              http_500 http_502 http_503 http_504;
        proxy_cache_background_update on;
        proxy_cache_lock on;
        proxy_pass http://pypi.douban.com/simple/$request_uri;
    }
}

#155 关于机器学习

2016-06-25

最近一年来,在多个技术社区中看到大家讨论机器学习,似乎已经炙手可热了,作为一个程序员,还是需要学习了解一番。
相关的理论还没有进行深入的研究,实践经验也就更加谈不上,这里只是从“概念”层面上来学习(也算是一点小预研吧)。