ruby-system.md

ruby 系统管理源手册

  • 编程的艺术本质上就是管理复杂度的艺术

    • 功能特性应该划分为清晰的逻辑模块
      • 从整体上对功能模块有一个总体概括, 从而更容易理解内部运作机制和原理
      • 每个模块只关心与自己相关的必要的代码, 最小认知成本能实现一小块功能
    • 各模块之间定义经过深思熟虑的清晰的接口
      • 让评审和测试更容易发现逻辑和语义错误
      • 对领域知识进行抽象, 对数据和操作进行封装
  • 面向对象

    • 对象是一个遵循预设规则的实体
      • 一些被保护的无法直接操作的内部结构
      • 一组方法让我们与这些数据进行交互
    • 一门语言提供让你遵循编程模式(比如抽象接口)的容易程度, 是非常关键的
      • 如果你得绕无数弯路才能创建更优雅的程序, 那么你会自然的走捷径, 这是人性
  • Ruby 的面向对象

    • 程序运行在某个某个上下文中

      • 总是会隐式的在调用之前增加 self
        • 在 main 程序中 self = Kernal
      • 一切都是对象, 与对象交互的唯一途径就是方法
        • 方法调用的括号是可选的
      • 类型系统采用鸭子定型 duck typing
        • 如果某个对象看起来像一只鸭子, 并且呱呱叫得像只鸭子, 那么它就是一只鸭子
        • 并把这种类型策略应用到方法的签名上
          • 能调用 puts 的参数是任何只需要实现 tos 的方法的对象就可以
    • 约定惯例

      • !结尾的方法表明直接对 self (绑定的对象) 进行了修改
      • ?结尾的方法表明返回 bool 类型的值 (True/False)
  • 协同例程支持 coroutine support

    • 两段代码来回调用的思想
      • ruby 通过 yield 向 block 中传递参数进行回调
    • 实际的场景中总是能找到可以复用 80% 逻辑的方法, 剩下的 20% 的逻辑需要和具体业务上下文进行绑定

常规任务的快速解决方案

  • 管道

    ruby -e 'puts "hello world"' | grep hello
  • grep 匹配搜索

    ruby -ne 'puts $_ if $_ =~ /zhijia/ ' /etc/passwd  /etc/group
  • 快速注释

-i in-place 就地修改, 并备份的后缀

ruby -i.bak -pe ' $_ = "# " + $_ ' args_test.rb

ruby -ne 'puts "#{$<.filename}:#{$<.lineno}" if $_ =~ /zhijia/  ' /etc/passwd /etc/group
# $. == $<.lineno
ruby -ne 'puts "#{$<.filename}:#{$.}" if $_ =~ /zhijia/  ' /etc/passwd /etc/group
  • 字段分割

    echo "I love ruby 2022 " | ruby -a -ne ' puts $F '
    echo "apple,banana,orage" | ruby -aF, -ne ' puts $F '
    # ; 在shell中会被截断
    echo "apple;banana;orage" | ruby -aF\; -ne ' puts $F '
  • 电话簿整理

    bash -c 'cat <<EOF
    32,chichago,shanghai,man
    30,lime,nanjin,woman
    EOF' | ruby -aF, -ne 'puts $F.values_at(1, 0, 2, 3).join("\t")'
    
    bash>
    
      cat <<EOF | ruby -aF, -ne 'puts $F.values_at(1, 0, 2, 3).join("\t")'
    32,go,shanghai,man
    30,lime,nanjin,woman
    EOF
  • 目录列表排序

    https://dextutor.com/difference-between-access-modification-and-change-time-in-linux/

    1. Access Time: is the time when the file was last accessed or read.
      • For example, using the cat, head or an editor. But remember you did not modify the contents.
    2. Modification Time: is the time when the contents of the file was last modified.
      • For example, you used an editor to add new content or delete some existing content.
    3. Change Time: is the time when the file’s inode has been changed.
      • For example, by changing permissions, ownership, file name, number of hard links.
ruby -e 'puts Dir["**/*.go"].find_all { File.size(_1) > 1024 }.sort_by { File.mtime _1 } '
  • 目录监控

    # exa --help | bat -p -lman
    ruby -e 'system "clear; exa -m -s modified -alh *.go "  while sleep 1'
    touch tree.go
  • 自动处理分割符

    # man ascii | bat -p -lman
    # 015   13    0D    CR  '\r' (carriage ret)
    # vim /tmp/1.bin
    ruby -e 'File.write("/dev/stdout", "hello\rworld")' | ruby -015 -l  -ne 'puts $_'
  • 环境路径列表

    echo $PATH | ruby -a -ne 'puts $F'
  • 文本匹配替换

# sed
# - sed -i 's/\[\X\]/\[\x\]/g' todos.md
# - sed -i 's/\[\-\]/\[\ \]/g' todos.md
ruby -i -p -e 'gsub(/\[X\]/,"[x]"); gsub(/\[-\]/, "[ ]")' todos.md
  • 文件操作

字节(Byte)是计量单位, 表示数据量多少, 用于计量存储容量的一种计量单位, 一个字节等于八位(Bits) 字符(Char)在计算机中表示字母、数字、字和符号, 比如'A'、'B'、'$'、'&'等 通常在英文状态下一个字母或字符占用一个字节 一个汉字用两个字节表示 1 byte = 8 bits a "bit" is atomic: the smallest unit of storage a bit stores just a 0 or 1 one byte can store one character, e.g. 'A' or 'x' or '$' 1k = 1024byte

touch file-to-backup
# ri FileUtils | cat -lman
ls file-to-backup | ruby -rfileutils -lne 'f = $_; FileUtils.mv(f , f + Time.now.strftime(".%Y%m%dT%H%M%S")) if File.exist?(f) and File.size(f) < 1024'
  • ruby 作为可执行脚本
#!/usr/bin/env ruby -w
puts "hello world"
chomd u+x hell.rb
  • 动态构建任务
# 从org 中解析出路径并根据最后的修改时间来决定是否需要构建html
cat ~/develop/think.org/index.org
| ruby -ne 'puts "#{$1}.md" if $_ =~ /\[\[(.*)\.html\]/
        and (File.mtime("#{Dir.home}/develop/think.org/#{$1}.md") > File.mtime("/var/www/#{$1}.html") rescue true)'
| while read line; do task think:publish-html -- $line; done