用 ruby 实现简单的并行处理
num_threads = 4

arg_list = ["foo", "bar"] # and probably more
Thread.abort_on_exception = true

queue = arg_list.each_with_object(Queue.new) { |f, q| q << f }

threads = Array.new(num_threads) do
  Thread.new do
    until queue.empty?
      arg = queue.shift
      do_something_with(arg)
    end
  end
end

threads.each(&:join)
建立 WSL 程序的快捷方式

安装 WSL 后,里面的 ssh 等程序本身就是一个非常好的 ssh 客户端。但是如果要从 cmd 环境运行的话,需要输入 bash -c "ssh user@host",比较麻烦。把下面的 ssh.cmd 加入到 PATH 可以简化掉前面的 bash -c,变为 ssh user@host 以减少输入的长度。

ssh.cmd:

@SETLOCAL EnableDelayedExpansion
@SET args=%*
@SET args=!args:\=\\!
@SET args=!args:"=\"!
@bash -c "%~n0 %args%"

这段 cmd 脚本不只可以用来做 ssh 的快捷方式,也可以拿来做 scp 等程序的快捷方式(但使用绝对路径时需要用 /mnt/c/path/to/file 的形式)。使用该脚本可以方便地在 cmd 环境中调用 WSL 中的程序。

脚本只做了最简单的转义,但在日常中应该是足够使用了。


2017/11/01 追记:

Windows 10 秋季创意者更新版可以使用原生的 ssh 和 scp 了。美中不足的是不支持 rsa 密钥。


2018/06/14 追记:

Windows 10 1803 版本已经支持了 rsa 密钥。此外,bash -c 可以简单地替换为 wsl,转义之类的操作应该也不再需要了。

多媒体处理 Cheatsheet
# Image format conversion
magick input.gif output.png
magick %03d.png[0-255] output.pdf
magick %03d.png[0-255] -delay 2 -loop 0 output.gif
magick mogrify -format jpg *.png
gs -dSAFER -dBATCH -dNOPAUSE -dEPSCrop -r300 -sDEVICE=pngalpha -sOutputFile=output.png input.eps
rsvg-convert -z 2 --no-keep-image-data input.svg output.png

# Batch Processing
magick *.png -set filename:f "%f" +adjoin -other-options "path/to/output/%[filename:f]"
magick mogrify -path path/to/output -other-options *.png

# Transparenting white background
magick input.png -transparent white output.png

# Zeroing all transparent background
magick input.png -background none -alpha Background output.png

# Cropping
magick input.png[32x32+16+16] output.png
magick input.png -crop 32x32+16+16 output.png

# Resizing
magick input.png[64x64] output.png
magick input.png -filter box -resize 50% output.png

# Composition
magick destination.png source.png -geometry +32+32 -compose Over -composite output.png

# Removing alpha channel
magick input.png -alpha off output.png

# Clearing a rectangle
magick input.png -alpha set -size 32x32 xc: -geometry +32+32 -compose DstOut -composite output.png

# Conversion from video to image
#   Every frame
ffmpeg -i input.mp4 "output_%04d.png"
#   With fixed fps
ffmpeg -i input.mp4 -vf "select='between(t,10,20)',fps=30" "output_%04d.png"

# Merging video and audio
#   Without re-encoding
ffmpeg -i input.mp4 -i audio.m4a -c copy output.mp4
#   With re-encoding
ffmpeg -i input.mp4 -i audio.wav -c:v copy -c:a aac output.mp4

# Cutting video
ffmpeg -i input.mp4 -c copy -ss 00:11:22 -to 00:33:44 output.mp4

# Delay video or audio with re-encoding
ffmpeg -i input.mp4 -itsoffset 1.0 -i input.mp4 -map 1:v -map 0:a -c:v libx265 -crf 28 -preset veryslow -c:a copy movie-video-delayed.mp4
ffmpeg -i input.mp4 -itsoffset 1.0 -i input.mp4 -map 0:v -map 1:a -c:v libx265 -crf 28 -preset veryslow -c:a copy movie-audio-delayed.mp4

# Submit to bilibili
ffmpeg -y -i input.mp4 -c:v libx264 -pass 1 -fastfirstpass 0 -b:v 2990k -preset placebo -tune animation -vf format=yuv420p -psy-rd 0:0 -aq-strength 0.8 -aq-mode 2 -g 600 -bf 9 -b_strategy 2 -qcomp 0.75 -trellis 2 -subq 10 -refs 4 -8x8dct 1 -partitions all -qdiff 7 -me_method tesa -c:a copy -f mp4 NUL
ffmpeg -y -i input.mp4 -c:v libx264 -pass 2 -b:v 2990k -preset placebo -tune animation -vf format=yuv420p -psy-rd 0:0 -aq-strength 0.8 -aq-mode 2 -g 600 -bf 9 -b_strategy 2 -qcomp 0.75 -trellis 2 -subq 10 -refs 4 -8x8dct 1 -partitions all -qdiff 7 -me_method tesa -c:a copy output.mp4

# Optimize PNG image
optipng -i 0 -o 7 -zm 1-9 -strip all input.png
pngcrush -blacken -brute -reduce -remove alla -ow input.png

# Remove exif data
#  one file
exiftool -all= input.jpg
#  recursively (. for current directory)
exiftool -all= -r -overwrite_original -ext jpg .