aboutsummaryrefslogtreecommitdiffstats
path: root/unix
diff options
context:
space:
mode:
authorAaron LI <aaronly.me@outlook.com>2017-01-19 19:19:24 +0800
committerAaron LI <aaronly.me@outlook.com>2017-01-19 19:19:24 +0800
commita1815079ad4ff8076eb33bbd3f6b50e5c1a66763 (patch)
tree6bb032fb65e39e307288163f3adc64c0b2ffbcf6 /unix
parent582e8827ad9fe6c7843d7f4ad86337b68270996f (diff)
downloadatoolbox-a1815079ad4ff8076eb33bbd3f6b50e5c1a66763.tar.bz2
Add various scripts
Diffstat (limited to 'unix')
-rwxr-xr-xunix/ape2mp3.sh111
-rwxr-xr-xunix/backup_thunderbird.sh102
-rwxr-xr-xunix/colors.sh37
-rwxr-xr-xunix/colortest.bash39
-rwxr-xr-xunix/colortest.lua22
-rwxr-xr-xunix/colortest.pl365
-rwxr-xr-xunix/colortest.py18
-rwxr-xr-xunix/colortest.rb26
-rwxr-xr-xunix/colortest.sh53
-rwxr-xr-xunix/cueape2flac.sh71
-rwxr-xr-xunix/eps2pdf.sh8
-rwxr-xr-xunix/flac_encode.sh97
-rwxr-xr-xunix/getopt-simple.sh46
-rwxr-xr-xunix/gpg-agent.sh13
-rwxr-xr-xunix/id3tag.sh513
-rw-r--r--unix/iptables_portforwarding_nat.sh57
-rwxr-xr-xunix/jpegs2pdf.sh36
-rw-r--r--unix/lightsOn.sh217
-rwxr-xr-xunix/link_dup.sh93
-rwxr-xr-xunix/m4a_to_mp3.sh8
-rwxr-xr-xunix/pdfmerge.sh23
-rwxr-xr-xunix/shrinkpdf.sh50
-rwxr-xr-xunix/term_color.sh28
-rwxr-xr-xunix/term_color_2.sh32
-rwxr-xr-xunix/term_color_3.sh33
-rwxr-xr-xunix/unzip-gbk.py26
26 files changed, 2124 insertions, 0 deletions
diff --git a/unix/ape2mp3.sh b/unix/ape2mp3.sh
new file mode 100755
index 0000000..d9cf6d6
--- /dev/null
+++ b/unix/ape2mp3.sh
@@ -0,0 +1,111 @@
+#!/bin/sh
+
+### ###
+# For APE & CUE file --> Mp3 #
+# Version : 0.20 #
+# This script build high quality mp3 from APE. #
+# You just run it in the dir include APE & CUE file. #
+# #
+# Author : kevin.li823@gmail.com #
+### ###
+
+echo Lame is the best mp3 encoder!
+export APE_FILE=`ls *.[aA][pP][eE]`
+export CUE_FILE=`ls *.[cC][uU][eE]`
+export WAV_FILE=${APE_FILE%ape}wav
+export UTF_CUE_FILE='UTF.cue'
+
+ALBUM=
+CD_ACTOR=
+GENRE=
+DATE=2000
+ACTOR=
+TRACK=
+TITLE=
+
+# Tools have been Installed
+which dos2unix >/dev/null 2>&1 || (echo No dos2unix in System; exit )
+which mac >/dev/null 2>&1 || (echo No mac in System; exit )
+which bchunk >/dev/null 2>&1 || (echo No bchunk in System; exit )
+which iconv >/dev/null 2>&1 || (echo No iconv in System; exit )
+which lame >/dev/null 2>&1 || (echo No lame in System; exit )
+
+# DOS -> Unix
+dos2unix $CUE_FILE
+
+# GBK -> UTF8
+iconv -f gbk -t utf8 $CUE_FILE > $UTF_CUE_FILE
+
+# Monkey's Audio Codec, ape -> wav
+echo Decoding APE file, it may take a few minutes.
+echo Please wait...
+mac $APE_FILE $WAV_FILE -d
+echo "APE --> WAV Complete! "
+
+# Split wav with cue file
+echo "Start to split wav! "
+bchunk $WAV_FILE $CUE_FILE -w wav_
+echo "Splitting Done"
+
+# Scan Album's Information
+ALBUM=`grep 'TITLE' $CUE_FILE|sed -n '1p'|awk -F \" '{print $2}'|\
+ sed s/\ /_/g`
+UTF_ALBUM=`grep 'TITLE' $UTF_CUE_FILE|sed -n '1p'|awk -F \" '{print $2}'|\
+ sed s/\ /_/g`
+CD_ACTOR=`grep 'PERFORMER' $CUE_FILE|sed -n '1p'|awk -F \" '{print $2}'|\
+ sed s/\ /_/g`
+GENRE=`grep ^REM $CUE_FILE|awk '{print ($2, $3)}'|grep ^GENRE |sed -n '1p'|\
+ awk '{print $2}'|\sed s/\ /_/g`
+DATE=`grep ^REM $CUE_FILE|awk '{print ($2, $3)}'|grep ^DATE |sed -n '1p'|\
+ awk '{print $2}'|\sed s/\ /_/g`
+# Add Album's Information to CMD line
+[ -n $ALBUM ] && CD_INFO="--tl ${ALBUM} "
+[ -n $GENRE ] && CD_INFO="${CD_INFO}""--tg ${GENRE} "
+[ -n $DATE ] && CD_INFO="${CD_INFO}""--ty $i{DATE}"
+
+for i in `ls wav_*`
+do
+ # Scan Songs' Information
+ TRACK=`echo $i|sed s/wav_//g|sed s/.wav//g`
+ TITLE=`sed -n "/TRACK[\ \ ]"$TRACK"/,$"p $CUE_FILE|grep TITLE|\
+ sed -n '1p'|awk -F \" '{print $2}'|sed s/\ /_/g`
+ UTF_TITLE=`sed -n "/TRACK[\ \ ]"$TRACK"/,$"p $UTF_CUE_FILE|grep TITLE|\
+ sed -n '1p'|awk -F \" '{print $2}'|sed s/\ /_/g`
+ ACTOR=`sed -n "/TRACK[\ \ ]"$TRACK"/,$"p $CUE_FILE|grep PER|\
+ sed -n '1p'|awk -F \" '{print $2}'|sed s/\ /_/g`
+
+ # Add Actor to CMDline if possible
+ [ -z $ACTOR ] && ACTOR=$CD_ACTOR
+
+ # Add Songs' Information to CMD line
+ [ -n $TITLE ] && NAME=`echo $TRACK\_$UTF_TITLE.mp3`
+ [ -n $TRACK ] && LAME_INFO=" --tn $TRACK "
+ [ -n $TITLE ] && LAME_INFO="$LAME_INFO --tt $TITLE "
+ [ -n $ACTOR ] && LAME_INFO="$LAME_INFO --ta $ACTOR "
+ LAME_INFO="${LAME_INFO} --tc Made_by_Kevin_Li"
+
+ echo
+ echo "========== Now Laming $UTF_TITLE =========="
+
+ #lame -b 32 -m j -h -V 0 -B 320 -q 0 --noath -k --id3v2-only --tt\
+ # $TITLE --ta $ACTOR --tl $ALBUM --tc Made_by_Kevin_Li --tn\
+ # $TRACK $i $NAME
+
+ # Now Lame the Songs
+ lame -b 32 -m j -h -V 0 -B 320 -q 0 --noath -k --id3v2-only \
+ $CD_INFO $LAME_IMFO $i $NAME
+
+ LAME_INFO=
+
+ echo "========== Lame $UTF_TITLE Done! =========="
+ echo
+done
+
+# File Arrangement
+[ -n `ls *.mp3` ] && rm *.wav
+rm $UTF_CUE_FILE
+mkdir \[$ACTOR_$UTF_ALBUM\_MP3\]
+mv *.mp3 \[$ACTOR_$UTF_ALBUM\_MP3\]
+echo
+echo "===================== All Done! ======================="
+[/code]
diff --git a/unix/backup_thunderbird.sh b/unix/backup_thunderbird.sh
new file mode 100755
index 0000000..1ce311a
--- /dev/null
+++ b/unix/backup_thunderbird.sh
@@ -0,0 +1,102 @@
+#!/bin/sh
+#
+# Backup thunderbird data with rsync.
+#
+# Weitian LI <liweitianux@gmail.com>
+# 2015/01/09
+#
+
+SCRIPT_PATH=`readlink -f $0`
+# Backup destination: same directory as this script.
+DEST=`dirname ${SCRIPT_PATH}`
+
+# rsync options
+RSYNC_OPTS="-az"
+
+VERBOSE=FALSE
+
+usage() {
+ echo "Usage:"
+ echo "`basename $0` [ -hDv ] [ -d <dest_dir> ] <thunderbird_profile_dir>"
+ echo ""
+ echo " -h: show this help"
+ echo " -D: allow delete destination files"
+ echo " -v: show verbose information"
+ echo ""
+ echo "This script backups thunderbird mails and data with rsync."
+ echo ""
+}
+
+# disable 'verbose error handling' by preceeding with a colon(:)
+while getopts ":hDvd:" opt; do
+ case $opt in
+ h)
+ usage
+ exit 0
+ ;;
+ D)
+ RSYNC_OPTS="${RSYNC_OPTS} --delete"
+ ;;
+ v)
+ RSYNC_OPTS="${RSYNC_OPTS} -v"
+ VERBOSE=TRUE
+ ;;
+ d)
+ DEST="${OPTARG}"
+ ;;
+ \?)
+ echo "Invalid option: -${OPTARG}" >&2
+ exit 2
+ ;;
+ :)
+ echo "Option -${OPTARG} requires an argument." >&2
+ exit 3
+ ;;
+ esac
+done
+
+# shift the options processed by getopts
+shift $((${OPTIND} - 1))
+
+if [ $# -ne 1 ]; then
+ usage
+ exit 1
+fi
+
+# the remaining argument after shift
+SRC="$1"
+
+if [ "${VERBOSE}" = "TRUE" ]; then
+ echo "RSYNC_OPTS: ${RSYNC_OPTS}"
+ echo "SRC: ${SRC}"
+ echo "DEST: ${DEST}"
+fi
+
+# backup files and directories
+BACKUP_LIST="ImapMail/" # IMAP mail boxes
+BACKUP_LIST="${BACKUP_LIST} Mail/" # POP & Local mail boxes
+BACKUP_LIST="${BACKUP_LIST} abook.mab history.mab" # personal & collected addresses
+BACKUP_LIST="${BACKUP_LIST} persdict.dat" # personal spelling dictionary
+BACKUP_LIST="${BACKUP_LIST} prefs.js" # preferences & tags definitions
+BACKUP_LIST="${BACKUP_LIST} key3.db signons.sqlite cert8.db" # saved passwords
+#BACKUP_LIST="${BACKUP_LIST} cookies.sqlite permissions.sqlite storage.sdb" # Lightning add-on
+
+# check files and directories; and rsync
+for i in ${BACKUP_LIST}; do
+ if [ -e "${SRC}/${i}" ]; then
+ CMD="rsync ${RSYNC_OPTS} '${SRC}/${i}' '${DEST}/${i}'"
+ if [ "${VERBOSE}" = "TRUE" ]; then
+ echo "CMD: ${CMD}"
+ fi
+ eval ${CMD}
+ else
+ echo "${SRC}/${i}: not exist!" >&2
+ fi
+done
+
+# log
+DATETIME=`date -u +%FT%TZ`
+echo ""
+echo "Thunderbird data sync finished at ${DATETIME}"
+echo "${DATETIME}" >> "${DEST}/SYNC.log"
+
diff --git a/unix/colors.sh b/unix/colors.sh
new file mode 100755
index 0000000..a28c261
--- /dev/null
+++ b/unix/colors.sh
@@ -0,0 +1,37 @@
+#!/bin/sh
+# https://gist.github.com/esundahl/1651086
+
+function color_test {
+ # Daniel Crisman's ANSI color chart script from
+ # The Bash Prompt HOWTO: 6.1. Colours
+ # http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x329.html
+ #
+ # This function echoes a bunch of color codes to the
+ # terminal to demonstrate what's available. Each
+ # line is the color code of one forground color,
+ # out of 17 (default + 16 escapes), followed by a
+ # test use of that color on all nine background
+ # colors (default + 8 escapes).
+ #
+
+ T='gYw' # The test text
+
+ echo -e "\n 40m 41m 42m 43m\
+ 44m 45m 46m 47m"
+
+ for FGs in ' m' ' 1m' ' 30m' '1;30m' ' 31m' '1;31m' \
+ ' 32m' '1;32m' ' 33m' '1;33m' ' 34m' '1;34m' \
+ ' 35m' '1;35m' ' 36m' '1;36m' ' 37m' '1;37m';
+ do
+ FG=${FGs// /}
+ echo -en " $FGs \033[$FG $T "
+ for BG in 40m 41m 42m 43m 44m 45m 46m 47m; do
+ echo -en "$EINS \033[$FG\033[$BG $T \033[0m"
+ done
+ echo;
+ done
+ echo
+}
+
+color_test
+
diff --git a/unix/colortest.bash b/unix/colortest.bash
new file mode 100755
index 0000000..c777b9e
--- /dev/null
+++ b/unix/colortest.bash
@@ -0,0 +1,39 @@
+#!/usr/bin/env bash
+#
+# ANSI color scheme script featuring Space Invaders
+#
+# Original: http://crunchbang.org/forums/viewtopic.php?pid=126921%23p126921#p126921
+# Modified by lolilolicon
+#
+
+f=3 b=4
+for j in f b; do
+ for i in {0..7}; do
+ printf -v $j$i %b "\e[${!j}${i}m"
+ done
+done
+bld=$'\e[1m'
+rst=$'\e[0m'
+
+cat << EOF
+
+ $f1 ▀▄ ▄▀ $f2 ▄▄▄████▄▄▄ $f3 ▄██▄ $f4 ▀▄ ▄▀ $f5 ▄▄▄████▄▄▄ $f6 ▄██▄ $rst
+ $f1 ▄█▀███▀█▄ $f2███▀▀██▀▀███ $f3▄█▀██▀█▄ $f4 ▄█▀███▀█▄ $f5███▀▀██▀▀███ $f6▄█▀██▀█▄$rst
+ $f1█▀███████▀█ $f2▀▀███▀▀███▀▀ $f3▀█▀██▀█▀ $f4█▀███████▀█ $f5▀▀███▀▀███▀▀ $f6▀█▀██▀█▀$rst
+ $f1▀ ▀▄▄ ▄▄▀ ▀ $f2 ▀█▄ ▀▀ ▄█▀ $f3▀▄ ▄▀ $f4▀ ▀▄▄ ▄▄▀ ▀ $f5 ▀█▄ ▀▀ ▄█▀ $f6▀▄ ▄▀$rst
+
+ $bld$f1▄ ▀▄ ▄▀ ▄ $f2 ▄▄▄████▄▄▄ $f3 ▄██▄ $f4▄ ▀▄ ▄▀ ▄ $f5 ▄▄▄████▄▄▄ $f6 ▄██▄ $rst
+ $bld$f1█▄█▀███▀█▄█ $f2███▀▀██▀▀███ $f3▄█▀██▀█▄ $f4█▄█▀███▀█▄█ $f5███▀▀██▀▀███ $f6▄█▀██▀█▄$rst
+ $bld$f1▀█████████▀ $f2▀▀▀██▀▀██▀▀▀ $f3▀▀█▀▀█▀▀ $f4▀█████████▀ $f5▀▀▀██▀▀██▀▀▀ $f6▀▀█▀▀█▀▀$rst
+ $bld$f1 ▄▀ ▀▄ $f2▄▄▀▀ ▀▀ ▀▀▄▄ $f3▄▀▄▀▀▄▀▄ $f4 ▄▀ ▀▄ $f5▄▄▀▀ ▀▀ ▀▀▄▄ $f6▄▀▄▀▀▄▀▄$rst
+
+
+ $f7▌$rst
+
+ $f7▌$rst
+
+ $f7 ▄█▄ $rst
+ $f7▄█████████▄$rst
+ $f7▀▀▀▀▀▀▀▀▀▀▀$rst
+
+EOF
diff --git a/unix/colortest.lua b/unix/colortest.lua
new file mode 100755
index 0000000..8f8c95f
--- /dev/null
+++ b/unix/colortest.lua
@@ -0,0 +1,22 @@
+#!/usr/bin/env lua
+
+function cl(e)
+ return string.format('\27[%sm', e)
+end
+
+function print_fg(bg, pre)
+ for fg = 30,37 do
+ fg = pre..fg
+ io.write(cl(bg), cl(fg), string.format(' %6s ', fg), cl(0))
+ end
+end
+
+for bg = 40,47 do
+ io.write(cl(0), ' ', bg, ' ')
+ print_fg(bg, ' ')
+ io.write('\n ')
+ print_fg(bg, '1;')
+ io.write('\n\n')
+end
+
+-- Andres P
diff --git a/unix/colortest.pl b/unix/colortest.pl
new file mode 100755
index 0000000..767789e
--- /dev/null
+++ b/unix/colortest.pl
@@ -0,0 +1,365 @@
+#!/usr/bin/env perl
+
+# by entheon, do whatever the hell you want with this file
+
+print "\n";
+print "*****************************\n";
+print "* XTERM 256Color Test Chart *\n";
+print "*****************************\n";
+print "* 16 = black\n";
+print "* 255 = white\n";
+print "*\n";
+print "* Usage:\n";
+print "* colortest.pl -w\n";
+print "* wide display\n";
+print "*\n";
+print "* colortest.pl -w -r\n";
+print "* wide display reversed\n";
+print "*\n";
+print "* colortest.pl -w -s\n";
+print "* extra spaces padding\n";
+print "*\n";
+print "* colortest.pl -w -r -s\n";
+print "* available combination\n";
+print "*\n";
+print "**************************\n";
+
+if( $ARGV[0] eq "-w" || $ARGV[1] eq "-w" || $ARGV[2] eq "-w" ) {
+ push(@arr, [( " 16: 00/00/00", " 17: 00/00/5f", " 18: 00/00/87", " 19: 00/00/af", " 20: 00/00/d7", " 21: 00/00/ff")] );
+ push(@arr, [( " 22: 00/5f/00", " 23: 00/5f/5f", " 24: 00/5f/87", " 25: 00/5f/af", " 26: 00/5f/d7", " 27: 00/5f/ff")] );
+ push(@arr, [( " 28: 00/87/00", " 29: 00/87/5f", " 30: 00/87/87", " 31: 00/87/af", " 32: 00/87/d7", " 33: 00/87/ff")] );
+ push(@arr, [( " 34: 00/af/00", " 35: 00/af/5f", " 36: 00/af/87", " 37: 00/af/af", " 38: 00/af/d7", " 39: 00/af/ff")] );
+ push(@arr, [( " 40: 00/d7/00", " 41: 00/d7/5f", " 42: 00/d7/87", " 43: 00/d7/af", " 44: 00/d7/d7", " 45: 00/d7/ff")] );
+ push(@arr, [( " 46: 00/ff/00", " 47: 00/ff/5f", " 48: 00/ff/87", " 49: 00/ff/af", " 50: 00/ff/d7", " 51: 00/ff/ff")] );
+ push(@arr, [( " 52: 5f/00/00", " 53: 5f/00/5f", " 54: 5f/00/87", " 55: 5f/00/af", " 56: 5f/00/d7", " 57: 5f/00/ff")] );
+ push(@arr, [( " 58: 5f/5f/00", " 59: 5f/5f/5f", " 60: 5f/5f/87", " 61: 5f/5f/af", " 62: 5f/5f/d7", " 63: 5f/5f/ff")] );
+ push(@arr, [( " 64: 5f/87/00", " 65: 5f/87/5f", " 66: 5f/87/87", " 67: 5f/87/af", " 68: 5f/87/d7", " 69: 5f/87/ff")] );
+ push(@arr, [( " 70: 5f/af/00", " 71: 5f/af/5f", " 72: 5f/af/87", " 73: 5f/af/af", " 74: 5f/af/d7", " 75: 5f/af/ff")] );
+ push(@arr, [( " 76: 5f/d7/00", " 77: 5f/d7/5f", " 78: 5f/d7/87", " 79: 5f/d7/af", " 80: 5f/d7/d7", " 81: 5f/d7/ff")] );
+ push(@arr, [( " 82: 5f/ff/00", " 83: 5f/ff/5f", " 84: 5f/ff/87", " 85: 5f/ff/af", " 86: 5f/ff/d7", " 87: 5f/ff/ff")] );
+ push(@arr, [( " 88: 87/00/00", " 89: 87/00/5f", " 90: 87/00/87", " 91: 87/00/af", " 92: 87/00/d7", " 93: 87/00/ff")] );
+ push(@arr, [( " 94: 87/5f/00", " 95: 87/5f/5f", " 96: 87/5f/87", " 97: 87/5f/af", " 98: 87/5f/d7", " 99: 87/5f/ff")] );
+ push(@arr, [( " 100: 87/87/00", " 101: 87/87/5f", " 102: 87/87/87", " 103: 87/87/af", " 104: 87/87/d7", " 105: 87/87/ff")] );
+ push(@arr, [( " 106: 87/af/00", " 107: 87/af/5f", " 108: 87/af/87", " 109: 87/af/af", " 110: 87/af/d7", " 111: 87/af/ff")] );
+ push(@arr, [( " 112: 87/d7/00", " 113: 87/d7/5f", " 114: 87/d7/87", " 115: 87/d7/af", " 116: 87/d7/d7", " 117: 87/d7/ff")] );
+ push(@arr, [( " 118: 87/ff/00", " 119: 87/ff/5f", " 120: 87/ff/87", " 121: 87/ff/af", " 122: 87/ff/d7", " 123: 87/ff/ff")] );
+ push(@arr, [( " 124: af/00/00", " 125: af/00/5f", " 126: af/00/87", " 127: af/00/af", " 128: af/00/d7", " 129: af/00/ff")] );
+ push(@arr, [( " 130: af/5f/00", " 131: af/5f/5f", " 132: af/5f/87", " 133: af/5f/af", " 134: af/5f/d7", " 135: af/5f/ff")] );
+ push(@arr, [( " 136: af/87/00", " 137: af/87/5f", " 138: af/87/87", " 139: af/87/af", " 140: af/87/d7", " 141: af/87/ff")] );
+ push(@arr, [( " 142: af/af/00", " 143: af/af/5f", " 144: af/af/87", " 145: af/af/af", " 146: af/af/d7", " 147: af/af/ff")] );
+ push(@arr, [( " 148: af/d7/00", " 149: af/d7/5f", " 150: af/d7/87", " 151: af/d7/af", " 152: af/d7/d7", " 153: af/d7/ff")] );
+ push(@arr, [( " 154: af/ff/00", " 155: af/ff/5f", " 156: af/ff/87", " 157: af/ff/af", " 158: af/ff/d7", " 159: af/ff/ff")] );
+ push(@arr, [( " 160: d7/00/00", " 161: d7/00/5f", " 162: d7/00/87", " 163: d7/00/af", " 164: d7/00/d7", " 165: d7/00/ff")] );
+ push(@arr, [( " 166: d7/5f/00", " 167: d7/5f/5f", " 168: d7/5f/87", " 169: d7/5f/af", " 170: d7/5f/d7", " 171: d7/5f/ff")] );
+ push(@arr, [( " 172: d7/87/00", " 173: d7/87/5f", " 174: d7/87/87", " 175: d7/87/af", " 176: d7/87/d7", " 177: d7/87/ff")] );
+ push(@arr, [( " 178: d7/af/00", " 179: d7/af/5f", " 180: d7/af/87", " 181: d7/af/af", " 182: d7/af/d7", " 183: d7/af/ff")] );
+ push(@arr, [( " 184: d7/d7/00", " 185: d7/d7/5f", " 186: d7/d7/87", " 187: d7/d7/af", " 188: d7/d7/d7", " 189: d7/d7/ff")] );
+ push(@arr, [( " 190: d7/ff/00", " 191: d7/ff/5f", " 192: d7/ff/87", " 193: d7/ff/af", " 194: d7/ff/d7", " 195: d7/ff/ff")] );
+ push(@arr, [( " 196: ff/00/00", " 197: ff/00/5f", " 198: ff/00/87", " 199: ff/00/af", " 200: ff/00/d7", " 201: ff/00/ff")] );
+ push(@arr, [( " 202: ff/5f/00", " 203: ff/5f/5f", " 204: ff/5f/87", " 205: ff/5f/af", " 206: ff/5f/d7", " 207: ff/5f/ff")] );
+ push(@arr, [( " 208: ff/87/00", " 209: ff/87/5f", " 210: ff/87/87", " 211: ff/87/af", " 212: ff/87/d7", " 213: ff/87/ff")] );
+ push(@arr, [( " 214: ff/af/00", " 215: ff/af/5f", " 216: ff/af/87", " 217: ff/af/af", " 218: ff/af/d7", " 219: ff/af/ff")] );
+ push(@arr, [( " 220: ff/d7/00", " 221: ff/d7/5f", " 222: ff/d7/87", " 223: ff/d7/af", " 224: ff/d7/d7", " 225: ff/d7/ff")] );
+ push(@arr, [( " 226: ff/ff/00", " 227: ff/ff/5f", " 228: ff/ff/87", " 229: ff/ff/af", " 230: ff/ff/d7", " 231: ff/ff/ff")] );
+ push(@arr, [( " 232: 08/08/08", " 233: 12/12/12", " 234: 1c/1c/1c", " 235: 26/26/26", " 236: 30/30/30", " 237: 3a/3a/3a")] );
+ push(@arr, [( " 238: 44/44/44", " 239: 4e/4e/4e", " 240: 58/58/58", " 241: 62/62/62", " 242: 6c/6c/6c", " 243: 76/76/76")] );
+ push(@arr, [( " 244: 80/80/80", " 245: 8a/8a/8a", " 246: 94/94/94", " 247: 9e/9e/9e", " 248: a8/a8/a8", " 249: b2/b2/b2")] );
+ push(@arr, [( " 250: bc/bc/bc", " 251: c6/c6/c6", " 252: d0/d0/d0", " 253: da/da/da", " 254: e4/e4/e4", " 255: ee/ee/ee")] );
+
+ if( $ARGV[0] eq "-s" || $ARGV[1] eq "-s" || $ARGV[2] eq "-s" ){
+ $padding = " ";
+ }
+ else {
+
+ }
+
+ # display in reverse order
+ if( $ARGV[0] eq "-r" || $ARGV[1] eq "-r" || $ARGV[2] eq "-r" ){
+ for( $dimone = 0; $dimone < scalar @arr; $dimone++ ) {
+
+ $seed = ($dimone % 6) * -1;
+ for( $dimtwo = 0; $dimtwo < 6; $dimtwo++ ) {
+
+ $movone = $seed;
+ $movtwo = $seed * -1;
+
+ print $arr[$dimone][$dimtwo] . $padding;
+
+ $seed = $seed+1;
+ }
+
+ print "\n";
+ }
+ }
+ else {
+ for( $dimone = 0; $dimone < scalar @arr; $dimone++ ) {
+
+ $seed = ($dimone % 6) * -1;
+ for( $dimtwo = 0; $dimtwo < 6; $dimtwo++ ) {
+
+ $movone = $seed;
+ $movtwo = $seed * -1;
+
+ $newone = $dimone+$movone;
+ $newtwo = $dimtwo+$movtwo;
+
+ if( $newone < scalar @arr ){
+ print $arr[$newone][$newtwo] . $padding;
+ }
+
+ $seed = $seed+1;
+ }
+
+ print "\n";
+ }
+ }
+ print "\n";
+ print "\n";
+
+}
+else {
+ print " 16: 00/00/00\n";
+ print " 17: 00/00/5f\n";
+ print " 18: 00/00/87\n";
+ print " 19: 00/00/af\n";
+ print " 20: 00/00/d7\n";
+ print " 21: 00/00/ff\n";
+ print " 22: 00/5f/00\n";
+ print " 23: 00/5f/5f\n";
+ print " 24: 00/5f/87\n";
+ print " 25: 00/5f/af\n";
+ print " 26: 00/5f/d7\n";
+ print " 27: 00/5f/ff\n";
+ print " 28: 00/87/00\n";
+ print " 29: 00/87/5f\n";
+ print " 30: 00/87/87\n";
+ print " 31: 00/87/af\n";
+ print " 32: 00/87/d7\n";
+ print " 33: 00/87/ff\n";
+ print " 34: 00/af/00\n";
+ print " 35: 00/af/5f\n";
+ print " 36: 00/af/87\n";
+ print " 37: 00/af/af\n";
+ print " 38: 00/af/d7\n";
+ print " 39: 00/af/ff\n";
+ print " 40: 00/d7/00\n";
+ print " 41: 00/d7/5f\n";
+ print " 42: 00/d7/87\n";
+ print " 43: 00/d7/af\n";
+ print " 44: 00/d7/d7\n";
+ print " 45: 00/d7/ff\n";
+ print " 46: 00/ff/00\n";
+ print " 47: 00/ff/5f\n";
+ print " 48: 00/ff/87\n";
+ print " 49: 00/ff/af\n";
+ print " 50: 00/ff/d7\n";
+ print " 51: 00/ff/ff\n";
+ print " 52: 5f/00/00\n";
+ print " 53: 5f/00/5f\n";
+ print " 54: 5f/00/87\n";
+ print " 55: 5f/00/af\n";
+ print " 56: 5f/00/d7\n";
+ print " 57: 5f/00/ff\n";
+ print " 58: 5f/5f/00\n";
+ print " 59: 5f/5f/5f\n";
+ print " 60: 5f/5f/87\n";
+ print " 61: 5f/5f/af\n";
+ print " 62: 5f/5f/d7\n";
+ print " 63: 5f/5f/ff\n";
+ print " 64: 5f/87/00\n";
+ print " 65: 5f/87/5f\n";
+ print " 66: 5f/87/87\n";
+ print " 67: 5f/87/af\n";
+ print " 68: 5f/87/d7\n";
+ print " 69: 5f/87/ff\n";
+ print " 70: 5f/af/00\n";
+ print " 71: 5f/af/5f\n";
+ print " 72: 5f/af/87\n";
+ print " 73: 5f/af/af\n";
+ print " 74: 5f/af/d7\n";
+ print " 75: 5f/af/ff\n";
+ print " 76: 5f/d7/00\n";
+ print " 77: 5f/d7/5f\n";
+ print " 78: 5f/d7/87\n";
+ print " 79: 5f/d7/af\n";
+ print " 80: 5f/d7/d7\n";
+ print " 81: 5f/d7/ff\n";
+ print " 82: 5f/ff/00\n";
+ print " 83: 5f/ff/5f\n";
+ print " 84: 5f/ff/87\n";
+ print " 85: 5f/ff/af\n";
+ print " 86: 5f/ff/d7\n";
+ print " 87: 5f/ff/ff\n";
+ print " 88: 87/00/00\n";
+ print " 89: 87/00/5f\n";
+ print " 90: 87/00/87\n";
+ print " 91: 87/00/af\n";
+ print " 92: 87/00/d7\n";
+ print " 93: 87/00/ff\n";
+ print " 94: 87/5f/00\n";
+ print " 95: 87/5f/5f\n";
+ print " 96: 87/5f/87\n";
+ print " 97: 87/5f/af\n";
+ print " 98: 87/5f/d7\n";
+ print " 99: 87/5f/ff\n";
+ print " 100 :87/87/00\n";
+ print " 101 :87/87/5f\n";
+ print " 102 :87/87/87\n";
+ print " 103 :87/87/af\n";
+ print " 104 :87/87/d7\n";
+ print " 105 :87/87/ff\n";
+ print " 106 :87/af/00\n";
+ print " 107 :87/af/5f\n";
+ print " 108 :87/af/87\n";
+ print " 109 :87/af/af\n";
+ print " 110 :87/af/d7\n";
+ print " 111 :87/af/ff\n";
+ print " 112 :87/d7/00\n";
+ print " 113 :87/d7/5f\n";
+ print " 114 :87/d7/87\n";
+ print " 115 :87/d7/af\n";
+ print " 116 :87/d7/d7\n";
+ print " 117 :87/d7/ff\n";
+ print " 118 :87/ff/00\n";
+ print " 119 :87/ff/5f\n";
+ print " 120 :87/ff/87\n";
+ print " 121 :87/ff/af\n";
+ print " 122 :87/ff/d7\n";
+ print " 123 :87/ff/ff\n";
+ print " 124 :af/00/00\n";
+ print " 125 :af/00/5f\n";
+ print " 126 :af/00/87\n";
+ print " 127 :af/00/af\n";
+ print " 128 :af/00/d7\n";
+ print " 129 :af/00/ff\n";
+ print " 130 :af/5f/00\n";
+ print " 131 :af/5f/5f\n";
+ print " 132 :af/5f/87\n";
+ print " 133 :af/5f/af\n";
+ print " 134 :af/5f/d7\n";
+ print " 135 :af/5f/ff\n";
+ print " 136 :af/87/00\n";
+ print " 137 :af/87/5f\n";
+ print " 138 :af/87/87\n";
+ print " 139 :af/87/af\n";
+ print " 140 :af/87/d7\n";
+ print " 141 :af/87/ff\n";
+ print " 142 :af/af/00\n";
+ print " 143 :af/af/5f\n";
+ print " 144 :af/af/87\n";
+ print " 145 :af/af/af\n";
+ print " 146 :af/af/d7\n";
+ print " 147 :af/af/ff\n";
+ print " 148 :af/d7/00\n";
+ print " 149 :af/d7/5f\n";
+ print " 150 :af/d7/87\n";
+ print " 151 :af/d7/af\n";
+ print " 152 :af/d7/d7\n";
+ print " 153 :af/d7/ff\n";
+ print " 154 :af/ff/00\n";
+ print " 155 :af/ff/5f\n";
+ print " 156 :af/ff/87\n";
+ print " 157 :af/ff/af\n";
+ print " 158 :af/ff/d7\n";
+ print " 159 :af/ff/ff\n";
+ print " 160 :d7/00/00\n";
+ print " 161 :d7/00/5f\n";
+ print " 162 :d7/00/87\n";
+ print " 163 :d7/00/af\n";
+ print " 164 :d7/00/d7\n";
+ print " 165 :d7/00/ff\n";
+ print " 166 :d7/5f/00\n";
+ print " 167 :d7/5f/5f\n";
+ print " 168 :d7/5f/87\n";
+ print " 169 :d7/5f/af\n";
+ print " 170 :d7/5f/d7\n";
+ print " 171 :d7/5f/ff\n";
+ print " 172 :d7/87/00\n";
+ print " 173 :d7/87/5f\n";
+ print " 174 :d7/87/87\n";
+ print " 175 :d7/87/af\n";
+ print " 176 :d7/87/d7\n";
+ print " 177 :d7/87/ff\n";
+ print " 178 :d7/af/00\n";
+ print " 179 :d7/af/5f\n";
+ print " 180 :d7/af/87\n";
+ print " 181 :d7/af/af\n";
+ print " 182 :d7/af/d7\n";
+ print " 183 :d7/af/ff\n";
+ print " 184 :d7/d7/00\n";
+ print " 185 :d7/d7/5f\n";
+ print " 186 :d7/d7/87\n";
+ print " 187 :d7/d7/af\n";
+ print " 188 :d7/d7/d7\n";
+ print " 189 :d7/d7/ff\n";
+ print " 190 :d7/ff/00\n";
+ print " 191 :d7/ff/5f\n";
+ print " 192 :d7/ff/87\n";
+ print " 193 :d7/ff/af\n";
+ print " 194 :d7/ff/d7\n";
+ print " 195 :d7/ff/ff\n";
+ print " 196 :ff/00/00\n";
+ print " 197 :ff/00/5f\n";
+ print " 198 :ff/00/87\n";
+ print " 199 :ff/00/af\n";
+ print " 200 :ff/00/d7\n";
+ print " 201 :ff/00/ff\n";
+ print " 202 :ff/5f/00\n";
+ print " 203 :ff/5f/5f\n";
+ print " 204 :ff/5f/87\n";
+ print " 205 :ff/5f/af\n";
+ print " 206 :ff/5f/d7\n";
+ print " 207 :ff/5f/ff\n";
+ print " 208 :ff/87/00\n";
+ print " 209 :ff/87/5f\n";
+ print " 210 :ff/87/87\n";
+ print " 211 :ff/87/af\n";
+ print " 212 :ff/87/d7\n";
+ print " 213 :ff/87/ff\n";
+ print " 214 :ff/af/00\n";
+ print " 215 :ff/af/5f\n";
+ print " 216 :ff/af/87\n";
+ print " 217 :ff/af/af\n";
+ print " 218 :ff/af/d7\n";
+ print " 219 :ff/af/ff\n";
+ print " 220 :ff/d7/00\n";
+ print " 221 :ff/d7/5f\n";
+ print " 222 :ff/d7/87\n";
+ print " 223 :ff/d7/af\n";
+ print " 224 :ff/d7/d7\n";
+ print " 225 :ff/d7/ff\n";
+ print " 226 :ff/ff/00\n";
+ print " 227 :ff/ff/5f\n";
+ print " 228 :ff/ff/87\n";
+ print " 229 :ff/ff/af\n";
+ print " 230 :ff/ff/d7\n";
+ print " 231 :ff/ff/ff\n";
+ print " 232 :08/08/08\n";
+ print " 233 :12/12/12\n";
+ print " 234 :1c/1c/1c\n";
+ print " 235 :26/26/26\n";
+ print " 236 :30/30/30\n";
+ print " 237 :3a/3a/3a\n";
+ print " 238 :44/44/44\n";
+ print " 239 :4e/4e/4e\n";
+ print " 240 :58/58/58\n";
+ print " 241 :62/62/62\n";
+ print " 242 :6c/6c/6c\n";
+ print " 243 :76/76/76\n";
+ print " 244 :80/80/80\n";
+ print " 245 :8a/8a/8a\n";
+ print " 246 :94/94/94\n";
+ print " 247 :9e/9e/9e\n";
+ print " 248 :a8/a8/a8\n";
+ print " 249 :b2/b2/b2\n";
+ print " 250 :bc/bc/bc\n";
+ print " 251 :c6/c6/c6\n";
+ print " 252 :d0/d0/d0\n";
+ print " 253 :da/da/da\n";
+ print " 254 :e4/e4/e4\n";
+ print " 255 :ee/ee/ee\n";
+ print "\n";
+ print "\n";
+}
+print "0m";
+exit;
diff --git a/unix/colortest.py b/unix/colortest.py
new file mode 100755
index 0000000..2d29590
--- /dev/null
+++ b/unix/colortest.py
@@ -0,0 +1,18 @@
+#!/usr/bin/env python
+#
+# http://askubuntu.com/questions/27314/script-to-display-all-terminal-colors
+
+import sys
+
+terse = "-t" in sys.argv[1:] or "--terse" in sys.argv[1:]
+
+for i in range(2 if terse else 10):
+ for j in range(30, 38):
+ for k in range(40, 48):
+ if terse:
+ print "\33[%d;%d;%dm%d;%d;%d\33[m " % (i, j, k, i, j, k),
+ else:
+ print ("%d;%d;%d: \33[%d;%d;%dm Hello, World! \33[m " %
+ (i, j, k, i, j, k, ))
+ print
+
diff --git a/unix/colortest.rb b/unix/colortest.rb
new file mode 100755
index 0000000..cc5d6d6
--- /dev/null
+++ b/unix/colortest.rb
@@ -0,0 +1,26 @@
+#!/usr/bin/env ruby
+# coding: utf-8
+
+# ANSI color scheme script
+# Author: Ivaylo Kuzev < Ivo >
+# Original: http://crunchbang.org/forums/viewtopic.php?pid=134749%23p134749#p134749
+# Modified using Ruby.
+
+CL = "\e[0m"
+BO = "\e[1m"
+
+R = "\e[31m"
+G = "\e[32m"
+Y = "\e[33m"
+B = "\e[34m"
+P = "\e[35m"
+C = "\e[36m"
+
+print <<EOF
+
+#{BO}#{R} ██████ #{CL} #{BO}#{G}██████ #{CL}#{BO}#{Y} ██████#{CL} #{BO}#{B}██████ #{CL} #{BO}#{P} ██████#{CL} #{BO}#{C} ███████#{CL}
+#{BO}#{R} ████████#{CL} #{BO}#{G}██ ██ #{CL}#{BO}#{Y}██ #{CL} #{BO}#{B}██ ██#{CL} #{BO}#{P}██████ #{CL} #{BO}#{C} █████████#{CL}
+#{R} ██ ████#{CL} #{G}██ ████#{CL}#{Y} ████ #{CL} #{B}████ ██#{CL} #{P}████ #{CL} #{C}█████ #{CL}
+#{R} ██ ██#{CL} #{G}██████ #{CL}#{Y} ████████#{CL} #{B}██████ #{CL} #{P}████████#{CL} #{C}██ #{CL}
+
+EOF
diff --git a/unix/colortest.sh b/unix/colortest.sh
new file mode 100755
index 0000000..3974d69
--- /dev/null
+++ b/unix/colortest.sh
@@ -0,0 +1,53 @@
+#!/bin/sh
+# Original Posted at http://crunchbang.org/forums/viewtopic.php?pid=126921%23p126921#p126921
+# [ESC] character in original post removed here.
+
+# ANSI Color -- use these variables to easily have different color
+# and format output. Make sure to output the reset sequence after
+# colors (f = foreground, b = background), and use the 'off'
+# feature for anything you turn on.
+
+initializeANSI()
+{
+ esc="$(echo -en '\e')"
+
+ blackf="${esc}[30m"; redf="${esc}[31m"; greenf="${esc}[32m"
+ yellowf="${esc}[33m" bluef="${esc}[34m"; purplef="${esc}[35m"
+ cyanf="${esc}[36m"; whitef="${esc}[37m"
+
+ blackb="${esc}[40m"; redb="${esc}[41m"; greenb="${esc}[42m"
+ yellowb="${esc}[43m" blueb="${esc}[44m"; purpleb="${esc}[45m"
+ cyanb="${esc}[46m"; whiteb="${esc}[47m"
+
+ boldon="${esc}[1m"; boldoff="${esc}[22m"
+ italicson="${esc}[3m"; italicsoff="${esc}[23m"
+ ulon="${esc}[4m"; uloff="${esc}[24m"
+ invon="${esc}[7m"; invoff="${esc}[27m"
+
+ reset="${esc}[0m"
+}
+
+# note in this first use that switching colors doesn't require a reset
+# first - the new color overrides the old one.
+
+#clear
+
+initializeANSI
+
+cat << EOF
+
+ ${yellowf} ▄███████▄${reset} ${redf} ▄██████▄${reset} ${greenf} ▄██████▄${reset} ${bluef} ▄██████▄${reset} ${purplef} ▄██████▄${reset} ${cyanf} ▄██████▄${reset}
+ ${yellowf}▄█████████▀▀${reset} ${redf}▄${whitef}█▀█${redf}██${whitef}█▀█${redf}██▄${reset} ${greenf}▄${whitef}█▀█${greenf}██${whitef}█▀█${greenf}██▄${reset} ${bluef}▄${whitef}█▀█${bluef}██${whitef}█▀█${bluef}██▄${reset} ${purplef}▄${whitef}█▀█${purplef}██${whitef}█▀█${purplef}██▄${reset} ${cyanf}▄${whitef}█▀█${cyanf}██${whitef}█▀█${cyanf}██▄${reset}
+ ${yellowf}███████▀${reset} ${redf}█${whitef}▄▄█${redf}██${whitef}▄▄█${redf}███${reset} ${greenf}█${whitef}▄▄█${greenf}██${whitef}▄▄█${greenf}███${reset} ${bluef}█${whitef}▄▄█${bluef}██${whitef}▄▄█${bluef}███${reset} ${purplef}█${whitef}▄▄█${purplef}██${whitef}▄▄█${purplef}███${reset} ${cyanf}█${whitef}▄▄█${cyanf}██${whitef}▄▄█${cyanf}███${reset}
+ ${yellowf}███████▄${reset} ${redf}████████████${reset} ${greenf}████████████${reset} ${bluef}████████████${reset} ${purplef}████████████${reset} ${cyanf}████████████${reset}
+ ${yellowf}▀█████████▄▄${reset} ${redf}██▀██▀▀██▀██${reset} ${greenf}██▀██▀▀██▀██${reset} ${bluef}██▀██▀▀██▀██${reset} ${purplef}██▀██▀▀██▀██${reset} ${cyanf}██▀██▀▀██▀██${reset}
+ ${yellowf} ▀███████▀${reset} ${redf}▀ ▀ ▀ ▀${reset} ${greenf}▀ ▀ ▀ ▀${reset} ${bluef}▀ ▀ ▀ ▀${reset} ${purplef}▀ ▀ ▀ ▀${reset} ${cyanf}▀ ▀ ▀ ▀${reset}
+
+ ${boldon}${yellowf} ▄███████▄ ${redf} ▄██████▄ ${greenf} ▄██████▄ ${bluef} ▄██████▄ ${purplef} ▄██████▄ ${cyanf} ▄██████▄${reset}
+ ${boldon}${yellowf}▄█████████▀▀ ${redf}▄${whitef}█▀█${redf}██${whitef}█▀█${redf}██▄ ${greenf}▄${whitef}█▀█${greenf}██${whitef}█▀█${greenf}██▄ ${bluef}▄${whitef}█▀█${bluef}██${whitef}█▀█${bluef}██▄ ${purplef}▄${whitef}█▀█${purplef}██${whitef}█▀█${purplef}██▄ ${cyanf}▄${whitef}█▀█${cyanf}██${whitef}█▀█${cyanf}██▄${reset}
+ ${boldon}${yellowf}███████▀ ${redf}█${whitef}▄▄█${redf}██${whitef}▄▄█${redf}███ ${greenf}█${whitef}▄▄█${greenf}██${whitef}▄▄█${greenf}███ ${bluef}█${whitef}▄▄█${bluef}██${whitef}▄▄█${bluef}███ ${purplef}█${whitef}▄▄█${purplef}██${whitef}▄▄█${purplef}███ ${cyanf}█${whitef}▄▄█${cyanf}██${whitef}▄▄█${cyanf}███${reset}
+ ${boldon}${yellowf}███████▄ ${redf}████████████ ${greenf}████████████ ${bluef}████████████ ${purplef}████████████ ${cyanf}████████████${reset}
+ ${boldon}${yellowf}▀█████████▄▄ ${redf}██▀██▀▀██▀██ ${greenf}██▀██▀▀██▀██ ${bluef}██▀██▀▀██▀██ ${purplef}██▀██▀▀██▀██ ${cyanf}██▀██▀▀██▀██${reset}
+ ${boldon}${yellowf} ▀███████▀ ${redf}▀ ▀ ▀ ▀ ${greenf}▀ ▀ ▀ ▀ ${bluef}▀ ▀ ▀ ▀ ${purplef}▀ ▀ ▀ ▀ ${cyanf}▀ ▀ ▀ ▀${reset}
+
+EOF
diff --git a/unix/cueape2flac.sh b/unix/cueape2flac.sh
new file mode 100755
index 0000000..7022f04
--- /dev/null
+++ b/unix/cueape2flac.sh
@@ -0,0 +1,71 @@
+#!/bin/bash
+# PS4="##### "
+# convert APE with cue file to FLAC tracks
+
+selection=`zenity --title="请选择一个.ape文件和一个.cue文件" --file-selection --multiple`
+if [ -z "$selection" ]; then exit 0; fi
+if [[ "$selection" != *.ape\|*.cue && "$selection" != *.cue\|*.ape ]]; then exit 0; fi
+if [ `echo $selection | gawk -F "|" 'END {print NF}'` -ge 3 ]; then exit 0; fi
+
+arg1=${selection%|*}; arg2=${selection#*|}
+if [[ "$arg1" == *.ape ]];then file_ape=$arg1; file_cue=$arg2
+else file_ape=$arg2; file_cue=$arg1; fi
+
+i=0
+while [ -f "temp$i" ]; do
+i=$(($i+1))
+done
+> temp$i
+iconv -f gb18030 -t utf8 "$file_cue" > "temp$i" && mv "temp$i" "$file_cue"
+rm -f "temp$i"
+
+tracks=`gawk -vRS="TRACK" 'END {print NR-1}' "$file_cue"`
+#echo $tracks
+
+all_titles=`gawk -vRS='TRACK' -vFS='\n' \
+'{j=0;for(i=1;i<=NF;i++){if($i~/TITLE/){print $i;j=1}}};j==0 {print "TITLE \"#####\""}' "$file_cue" | \
+gawk -F "\"" 'NR>=2 {printf("%s|",$2)}'`
+
+j=1; while [ -n "$all_titles" ]; do
+title=${all_titles%%|*}
+artist=${all_artists%%|*}
+num=`printf "%0${#tracks}d" $j`
+rm -f "${num}.$title.flac"
+((j++))
+all_titles=${all_titles#*|}
+all_artists=${all_artists#*|}
+done
+
+shntool split -f "$file_cue" -t '%n.%t' -o flac "$file_ape" 2>&1 | \
+gawk -vvar=$tracks 'NR>=1 {print "#正在转换...";print (NR-1)*100/var};{fflush();}' | \
+zenity --title="进度" --text="正在转换..." --progress --auto-kill --auto-close
+
+all_titles=`gawk -vRS='TRACK' -vFS='\n' \
+'{j=0;for(i=1;i<=NF;i++){if($i~/TITLE/){print $i;j=1}}};j==0 {print "TITLE \"#####\""}' "$file_cue" | \
+gawk -F "\"" 'NR>=2 {printf("%s|",$2)}'`
+
+all_artists=`gawk -vRS='TRACK' -vFS='\n' \
+'{j=0;for(i=1;i<=NF;i++){if($i~/PERFORMER/){print $i;j=1}}};\
+j==0 {print "PERFORMER \"#####\""}' "$file_cue" | gawk -F "\"" 'NR>=2 {printf("%s|",$2)}'`
+
+album=`gawk -vRS='TRACK' -vFS='\n' \
+'{j=0;for(i=1;i<=NF;i++){if($i~/TITLE/){print $i;j=1}}};j==0 {print "TITLE \"#####\""}' "$file_cue" | \
+gawk -F "\"" 'NR==1 {printf("%s",$2)}'`
+
+j=1; while [ -n "$all_titles" ]; do
+title=${all_titles%%|*}
+artist=${all_artists%%|*}
+num=`printf "%0${#tracks}d" $j`
+if [ "$title" != "#####" ]; then metaflac --set-tag=TITLE="$title" "${num}.$title.flac"; fi
+if [ "$artist" != "#####" ]; then metaflac --set-tag=ARTIST="$artist" "${num}.$title.flac"; fi
+if [ "$album" != "#####" ]; then metaflac --set-tag=ALBUM="$album" "${num}.$title.flac"; fi
+metaflac --set-tag=TRACKNUMBER="$j" "${num}.$title.flac"
+#if [ "$title" != "#####" ]; then mv "${num}.$title.flac" "${num:1}.$title.flac"
+#else mv "${num}.$title.flac" "${num:1}.NoTitle.flac"; fi
+((j++))
+all_titles=${all_titles#*|}
+all_artists=${all_artists#*|}
+done
+
+zenity --info --text="结束。"
+exit 0
diff --git a/unix/eps2pdf.sh b/unix/eps2pdf.sh
new file mode 100755
index 0000000..b803732
--- /dev/null
+++ b/unix/eps2pdf.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+# convert from eps to pdf using gs
+
+GS="`which gs`"
+BASENAME="`basename $1 .eps`"
+${GS} -sDEVICE=pdfwrite -dNOPAUSE -dQUIET -sOutputFile=${BASENAME}.pdf - < $1
+
diff --git a/unix/flac_encode.sh b/unix/flac_encode.sh
new file mode 100755
index 0000000..9f86156
--- /dev/null
+++ b/unix/flac_encode.sh
@@ -0,0 +1,97 @@
+#!/bin/sh
+#
+# encode '.wav' to '.flac' with tags
+#
+# INFO_WAV_LIST format:
+# +--------------------------
+# |# ARTIST=artist
+# |# ALBUM=album
+# |# DATE=date (YYYY-MM-DD)
+# |# GENRE=genre
+# |
+# |[TRACKNUMBER] - TITLE.wav
+# |[TRACKNUMBER] - TITLE.wav
+# |...
+# +--------------------------
+#
+# Ref:
+# FLAC: https://xiph.org/flac/
+# VorbisComment: http://wiki.xiph.org/VorbisComment
+# Vorbis Comment Field Recommendations:
+# http://age.hobba.nl/audio/mirroredpages/ogg-tagging.html
+#
+#
+# 2014-01-24
+# LiweitiaNux
+#
+
+if ! which flac > /dev/null 2>&1; then
+ echo "ERROR: 'flac' not found!"
+ exit 1
+fi
+
+if [ $# -ne 1 ]; then
+ echo "Usage:"
+ echo " `basename $0` <info_wav_list>"
+ exit 2
+fi
+
+INFO="$1"
+
+## meta data
+# ARTIST
+if grep -iq '^#.*ARTIST' $INFO; then
+ ARTIST=`grep -i '^#.*ARTIST' $INFO | sed 's/^#.*ARTIST=//'`
+else
+ ARTIST=""
+fi
+# ALBUM
+if grep -iq '^#.*ALBUM' $INFO; then
+ ALBUM=`grep -i '^#.*ALBUM' $INFO | sed 's/^#.*ALBUM=//'`
+else
+ ALBUM=""
+fi
+# DATE
+if grep -iq '^#.*DATE' $INFO; then
+ DATE=`grep -i '^#.*DATE' $INFO | sed 's/^#.*DATE=//'`
+else
+ DATE=""
+fi
+# GENRE
+if grep -iq '^#.*GENRE' $INFO; then
+ GENRE=`grep -i '^#.*GENRE' $INFO | sed 's/^#.*GENRE=//'`
+else
+ GENRE=""
+fi
+# PUBLISHER
+if grep -iq '^#.*PUBLISHER' $INFO; then
+ PUBLISHER=`grep -i '^#.*PUBLISHER' $INFO | sed 's/^#.*PUBLISHER=//'`
+else
+ PUBLISHER=""
+fi
+
+echo "ARTIST: $ARTIST"
+echo "ALBUM: $ALBUM"
+echo "DATE: $DATE"
+echo "GENRE: $GENRE"
+echo "PUBLISHER: $PUBLISHER"
+
+## process wav file list
+grep '^[/a-zA-Z0-9].*' $INFO | while read f; do
+ file=`basename "$f"`
+ TRACKNUMBER=`echo "$file" | sed 's/\ -\ .*\.wav$//'`
+ TITLE=`echo "$file" | sed -e 's/^[0-9]*\ -\ //' -e 's/\.wav$//'`
+ echo "TRACKNUMBER: $TRACKNUMBER; TITLE: $TITLE ..."
+ # encode
+ flac -T "ARTIST=${ARTIST}" -T "TITLE=${TITLE}" \
+ -T "ALBUM=${ALBUM}" -T "DATE=${DATE}" \
+ -T "TRACKNUMBER=${TRACKNUMBER}" \
+ -T "GENRE=${GENRE}" -T "PUBLISHER=${PUBLISHER}" \
+ -s "${f}"
+ if [ $? -eq 0 ]; then
+ echo " OK"
+ else
+ echo " *** ERROR ***"
+ fi
+done
+
diff --git a/unix/getopt-simple.sh b/unix/getopt-simple.sh
new file mode 100755
index 0000000..f5b06f0
--- /dev/null
+++ b/unix/getopt-simple.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+# getopt-simple.sh
+# Author: Chris Morgan
+# Used in the ABS Guide with permission.
+#
+# See also, UseGetOpt.sh, a modified version of this script.
+
+### example
+# $ sh getopt_example.sh /test=value1 /test2=value2
+
+# Parameters are '/test=value1 /test2=value2'
+# Processing parameter of: '/test=value1'
+# Parameter: 'test', value: 'value1'
+# Processing parameter of: '/test2=value2'
+# Parameter: 'test2', value: 'value2'
+# test is 'value1'
+# test2 is 'value2'
+###
+
+
+getopt_simple()
+{
+ echo "getopt_simple()"
+ echo "Parameters are '$*'"
+ until [ -z "$1" ]
+ do
+ echo "Processing parameter of: '$1'"
+ if [ ${1:0:1} = '/' ]
+ then
+ tmp=${1:1} # Strip off leading '/' . . .
+ parameter=${tmp%%=*} # Extract name.
+ value=${tmp##*=} # Extract value.
+ echo "Parameter: '$parameter', value: '$value'"
+ eval $parameter=$value
+ fi
+ shift
+ done
+}
+
+# Pass all options to getopt_simple().
+getopt_simple $*
+
+echo "test is '$test'"
+echo "test2 is '$test2'"
+
+exit 0
diff --git a/unix/gpg-agent.sh b/unix/gpg-agent.sh
new file mode 100755
index 0000000..751c2ac
--- /dev/null
+++ b/unix/gpg-agent.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+# gpg-agent.sh
+# autorun the gpg-agent
+
+envfile="${HOME}/.gnupg/gpg-agent.env"
+if test -f "$envfile" && kill -0 $(grep GPG_AGENT_INFO "$envfile" | cut -d: -f 2) 2>/dev/null; then
+ eval "$(cat "$envfile")"
+else
+ eval "$(gpg-agent --daemon --write-env-file "$envfile")"
+fi
+export GPG_AGENT_INFO # the env file does not contain the export statement
+
diff --git a/unix/id3tag.sh b/unix/id3tag.sh
new file mode 100755
index 0000000..93cd099
--- /dev/null
+++ b/unix/id3tag.sh
@@ -0,0 +1,513 @@
+#!/bin/sh
+#
+# MP3 id3tag functions
+#
+# Copyright (C) 2005 Robert, Zhang Le
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+# INTRO:
+# This file contains several functions related to mp3 file's operations.
+# I wrote them in order to ease the process of transforming the encoding
+# of mp3 file's id3tag from gbk to utf8. YOU NEED id3v2 to make these
+# functions work.
+# !!! USE THESE FUNCTIONS IN UTF-8 LOCALE !!!
+
+# TODO:
+# 1. make all the functions work both on a directory and a file
+# 2. add testing feature to all functions
+# * rename_delete_ending_artist()
+# * check_artist()
+# 3. set_artist() maybe need to be improved
+# 4. if functions are called without params, echo "usage"
+
+# USAGE:
+# 1. source this file before use
+
+
+# get_title_1() can be used to get v1 title from an mp3 file's id3tag
+# get_title_1_convernted() convert its encoding from gbk to utf8
+
+get_title_1(){
+ id3v2 -l "$1" | grep ^Title \
+ | sed -e 's/^Title : //g' -e 's/[[:space:]]*Artist: [[:print:]]*//g'
+}
+get_title_1_converted(){
+ id3v2 -l "$1" | grep ^Title \
+ | sed -e 's/^Title : //g' -e 's/[[:space:]]*Artist: [[:print:]]*//g' \
+ | iconv -f gbk -t utf8
+}
+
+# ATTENTION: if title encoding is gbk, the following function does not
+# function ideally, because "." can't match invisible/unmappd char?
+get_artist_1(){
+ id3v2 -l "$1" | grep ^Title \
+ | sed -e 's/^Title.*Artist: //g'
+}
+
+get_title_2(){
+ id3v2 -l "$1" | grep ^TIT2 | tail -n 1 | sed -e 's/^.*: //g'
+}
+get_title_2_converted(){
+ id3v2 -l "$1" | grep ^TIT2 | tail -n 1 | sed -e 's/^.*: //g' \
+ | iconv -f gbk -t utf8
+
+}
+get_artist_2(){
+ id3v2 -l "$1" | grep ^TPE1 | tail -n 1 | sed -e 's/^.*: //g'
+}
+
+
+# if only one param, it must be a dirname, and at the same time an artist's name
+# if two param, the first artist name, the second dirname
+set_artist(){
+ local artist
+
+ if [[ $# -eq 0 ]]; then
+ echo "set_artist artist [dir]"
+ return;
+ else
+ artist="$1";
+ fi
+
+ if [[ $# -eq 2 ]]; then
+ if [[ -d $2 ]]; then
+ shift;
+ else
+ echo "the 2nd param must be a dir"
+ return;
+ fi
+ elif [[ $# -eq 1 ]]; then
+ if [[ ! -d $1 ]]; then
+ echo "the sole param must be also a dir"
+ return;
+ fi
+ fi
+
+ find "$1" -name "*.mp3" -print0 | xargs -0 id3v2 -a "$artist" ;
+
+}
+
+id3_convert_set_title(){
+ local target
+ local title
+ local testing
+ local tmp
+ local i
+
+ if [[ $# -eq 0 ]]; then
+ echo "needs parameters"
+ return;
+ fi
+
+ if [[ $1 == "notest" ]]; then
+ testing=0;
+ shift;
+ else
+ testing=1;
+ fi
+
+
+ while [[ $# -gt 0 ]]; do
+ if [[ -d "$1" ]]; then
+ for i in "$1"/*.mp3;
+ do
+ title=`get_title_1_converted "$i"`
+
+ # if the last command, ie. iconv fails
+ # then probably the file's id3tag has already been converted
+ if [[ $? -ne 0 ]]; then
+ continue;
+ fi
+
+ tmp=`echo -n "$title" | sed -e 's/Track//g' -e 's/[[:space:][:digit:]]*//g'`
+
+ if [[ -z $tmp ]]; then
+ title=`get_title_2_converted "$i"`
+
+ if [[ $? -ne 0 ]]; then
+ continue;
+ fi
+
+ tmp=`echo -n "$title" | sed -e 's/Track//g' -e 's/[[:space:][:digit:]]*//g'`
+
+ if [[ -z $tmp ]]; then
+ echo "title is "$tmp" nothing need to be done"
+ continue;
+ fi
+ fi
+
+ if [[ -n $title ]]; then
+ if [[ $testing -eq 1 ]]; then
+ echo $title;
+ else
+ echo -n $title;
+ id3v2 -1 -t "$title" "$i";
+ id3v2 -2 -t "$title" "$i";
+ echo " done";
+ fi
+ fi
+ done
+ elif [[ -f "$1" ]]; then
+ title=`get_title_1_converted "$1"`
+ if [[ $? -ne 0 ]]; then
+ shift;
+ continue;
+ fi
+
+ tmp=`echo -n "$title" | sed -e 's/Track//g' -e 's/[[:space:][:digit:]]*//g'`
+
+ if [[ -z $tmp ]]; then
+ title=`get_title_2_converted "$1"`
+
+ if [[ $? -ne 0 ]]; then
+ continue;
+ fi
+
+ tmp=`echo -n "$title" | sed -e 's/Track//g' -e 's/[[:space:][:digit:]]*//g'`
+
+ if [[ -z $tmp ]]; then
+ echo "title is "$tmp" nothing need to be done"
+ shift;
+ continue;
+ fi
+ fi
+
+ if [[ -n $title ]]; then
+ if [[ $testing -eq 1 ]]; then
+ echo $title;
+ else
+ echo -n $title;
+ id3v2 -1 -t "$title" "$1";
+ id3v2 -2 -t "$title" "$1";
+ echo " done";
+ fi
+ fi
+ fi
+ shift;
+ done
+
+ if [[ $testing -eq 1 ]]; then
+ echo "testing finished, to convert use \"notest\" as the fist param"
+ fi
+}
+
+# make sure file name ends with ".mp3"
+id3_set_title_as_filename(){
+ local title
+ local testing
+ local i
+
+ if [[ $# -eq 0 ]]; then
+ echo "needs parameters";
+ return;
+ fi
+
+ if [[ $1 == "notest" ]]; then
+ testing=0;
+ shift;
+ else
+ testing=1;
+ fi
+
+ while [[ $# -gt 0 ]]; do
+ if [[ -d "$1" ]]; then
+ for i in "$1"/*.mp3; do
+ title=`basename "$i" | sed -e 's/\.mp3//g'`
+ if [[ $testing -eq 1 ]]; then
+ echo $title;
+ else
+ echo -n $title;
+ id3v2 -1 -t "${title}" "$i";
+ id3v2 -2 -t "${title}" "$i";
+ echo " done";
+ fi
+ done
+ elif [[ -f "$1" ]]; then
+ title=`basename "$1" | sed -e 's/\.mp3//g'`
+ if [[ $testing -eq 1 ]]; then
+ echo $title;
+ else
+ echo -n $title;
+ id3v2 -1 -t "$title" "$1";
+ id3v2 -2 -t "$title" "$1";
+ echo " done";
+ fi
+ fi
+ shift;
+ done
+
+ if [[ $testing -eq 1 ]]; then
+ echo "testing finished, to convert use \"notest\" as the fist param"
+ fi
+}
+
+id3_rename_MP3_to_mp3(){
+ local target
+ local i
+
+ if [[ $# -eq 0 ]]; then
+ echo "needs parameters";
+ return;
+ fi
+
+ while [[ $# -gt 0 ]]; do
+ if [[ -d "$1" ]]; then
+ for i in "$1"/*.MP3; do
+ target="$1"/`basename "$i" | sed -e 's/MP3$/mp3/g'`
+ if [[ "$i" != "$target" ]]; then
+ mv "$i" "$target";
+ echo "$i -> $target: done"
+ fi
+ done
+ elif [[ -f "$1" ]]; then
+ target=`dirname "$1"`/`basename "$1" | sed -e 's/MP3$/mp3/g'`
+ if [[ "$1" != "$target" ]]; then
+ mv "$1" "$target";
+ echo "$1 -> $target: done"
+ fi
+ fi
+ shift;
+ done
+}
+
+# use this function to remove leading garbages in the file name
+# Sometimes, the file name in the form of "artist -(1). title.mp3"
+# we just need title.mp3
+# the delim is the adjacent char before "title"
+
+id3_rename_delete_leading_garbage(){
+ local target
+ local testing
+ local orig="^0[0-9]\."
+ #local orig="^[[:alnum:]]*[-.()[:digit:][:space:]]*"
+ local delim="[[:space:]]"
+ # ATTENTION: if delimeter is ".", delim should be "\."
+ # when passing on command line, it should be "\\\."
+ local new=""
+ local i
+
+ if [[ $# -eq 0 ]]; then
+ echo "needs parameters";
+ return;
+ fi
+
+ if [[ $1 == "notest" ]]; then
+ testing=0;
+ shift;
+ else
+ testing=1;
+ fi
+
+ if [[ "${1/=*/}" == "delim" ]]; then
+ delim="${1/*=/}";
+ echo $delim;
+ shift;
+ fi
+
+ while [[ $# -gt 0 ]]; do
+ if [[ -d "$1" ]]; then
+ echo $1
+ for i in "$1"/*.mp3; do
+ target="$1"/`basename "$i" | sed -e "s/$orig$delim/$new/g"`
+ if [[ "$i" != "$target" ]]; then
+ echo -n "$target";
+ if [[ $testing -eq 0 ]]; then
+ mv "$i" "$target";
+ fi
+ echo " done"
+ else
+ echo "$target";
+ fi
+ done
+ elif [[ -f "$1" ]]; then
+ target=`dirname "$1"`/`basename "$1" | sed -e "s/$orig$delim/$new/g"`
+ if [[ "$1" != "$target" ]]; then
+ echo -n "$target";
+ if [[ $testing -eq 0 ]]; then
+ mv "$1" "$target";
+ fi
+ echo " done";
+ else
+ echo $target;
+ fi
+ fi
+ shift;
+ done
+
+ if [[ $testing -eq 1 ]]; then
+ echo "testing finished, to convert use \"notest\" as the fist param"
+ fi
+}
+
+# use this function after conversion
+id3_rename_as_title(){
+ local target
+ local title
+ local testing
+ local i
+
+ if [[ $# -eq 0 ]]; then
+ echo "needs parameters";
+ return;
+ fi
+
+ if [[ $1 == "notest" ]]; then
+ testing=0;
+ shift;
+ else
+ testing=1;
+ fi
+
+ while [[ $# -gt 0 ]]; do
+ if [[ -d "$1" ]]; then
+ for i in "$1"/*.mp3; do
+ title=`get_title_1 "$(basename $i)"`
+
+ # if the last command, ie. iconv fails
+ # then probably the file's id3tag has already been converted
+ if [[ $? -ne 0 ]]; then
+ continue;
+ fi
+
+ title=`echo -n "$title" | sed -e 's/[[:space:][:punct:]]*//g'`
+
+ if [[ -z $title ]]; then
+ title=`get_title_2_converted "$(basename $i)"`
+ if [[ $? -ne 0 ]]; then
+ continue;
+ fi
+ fi
+
+ target="$1"/`get_title_2 "$i"`.mp3
+
+ if [[ -a "$target" ]]; then
+ echo "$target exists, skiping"
+ continue;
+ fi
+
+ if [[ "$i" != "$target" ]] ; then
+ if [[ $testing -eq 0 ]]; then
+ mv "$i" "$target";
+ fi
+ echo "$i -> $target: done";
+ fi
+ done
+ elif [[ -f "$1" ]]; then
+ target=`dirname "$1"`/`get_title_2 "$1"`.mp3
+
+ if [[ -a "$target" ]]; then
+ echo "$target exists, skiping"
+ shift;
+ continue;
+ fi
+
+ if [[ "$1" != "$target" ]]; then
+ if [[ $testing -eq 0 ]]; then
+ mv "$1" "$target";
+ fi
+ echo "$1 -> $target: done";
+ fi
+ fi
+ shift;
+ done
+
+ if [[ $testing -eq 1 ]]; then
+ echo "testing finished, to convert use \"notest\" as the fist param"
+ fi
+}
+
+id3_check_title(){
+ local target
+ local i
+ local title1
+ local title2
+
+ if [[ $# -eq 0 ]]; then
+ echo "needs parameters";
+ return;
+ fi
+
+ while [[ $# -gt 0 ]]; do
+ if [[ -d "$1" ]]; then
+ echo $1
+ for i in "$1"/*.mp3
+ do
+ title1=`get_title_1 "$i"`;
+ title2=`get_title_2 "$i"`;
+ printf "%s \tv1: %s \tv2: %s\n" "$i" "$title1" "$title2";
+ done
+ elif [[ -f "$1" ]]; then
+ title1=`get_title_1 "$1"`;
+ title2=`get_title_2 "$1"`;
+ printf "%s \tv1: %s \tv2: %s\n" "$1" "$title1" "$title2";
+
+ fi
+ shift;
+ done
+}
+
+id3_check_title_converted(){
+ local target
+ local i
+ local title1
+ local title2
+
+ if [[ $# -eq 0 ]]; then
+ echo "needs parameters";
+ return;
+ fi
+
+ while [[ $# -gt 0 ]]; do
+ if [[ -d "$1" ]]; then
+ echo $1
+ for i in "$1"/*.mp3
+ do
+ title1=`get_title_1_converted "$i"`;
+ title2=`get_title_2_converted "$i"`;
+ printf "%s \tv1: %s \tv2: %s\n" "$i" "$title1" "$title2";
+ done
+ elif [[ -f "$1" ]]; then
+ title1=`get_title_1_converted "$1"`;
+ title2=`get_title_2_converted "$1"`;
+ printf "%s \tv1: %s \tv2: %s\n" "$1" "$title1" "$title2";
+
+ fi
+ shift;
+ done
+}
+
+id3_check_artist(){
+ for i in *.mp3;
+ do
+ artist1=`get_artist_1 "$i"`;
+ artist2=`get_artist_2 "$i"`;
+ printf "%s \tv1: %s \tv2: %s\n" "$i" "$artist1" "$artist2";
+ done
+}
+# if filename ends with "_artist", use this one to remove the suffix
+id3_rename_delete_ending_artist(){
+
+ if [[ $# -eq 0 ]]; then
+ echo "needs parameters";
+ return;
+ fi
+
+ for i in "$1"/*.mp3; do
+ mv "$i" "${i/_*./.}";
+ done
+}
+
diff --git a/unix/iptables_portforwarding_nat.sh b/unix/iptables_portforwarding_nat.sh
new file mode 100644
index 0000000..5b38ade
--- /dev/null
+++ b/unix/iptables_portforwarding_nat.sh
@@ -0,0 +1,57 @@
+#!/bin/sh
+#
+# Port forwarding from one address to another address in the same network,
+# using source and destination network address translation (SNAT & DNAT).
+#
+# The machine A performs this port forwarding to the target machine B,
+# which is in the same network as A.
+# The machine A behaves like a proxy, which allows e.g., external machine
+# access the services (e.g., SSH) on machine B which only allow access
+# from the internal network.
+#
+#
+# References:
+# [1] How to do the port forwarding from one ip to another ip in the same network?
+# https://serverfault.com/a/586553/387898
+# [2] Source and Destination Network Address Translation with iptables
+# https://thewiringcloset.wordpress.com/2013/03/27/linux-iptable-snat-dnat/
+# [3] How to List and Delete IPtables Firewall Rules
+# https://www.digitalocean.com/community/tutorials/how-to-list-and-delete-iptables-firewall-rules
+#
+#
+# Weitian LI
+# 2016-11-29
+#
+
+
+# Enable IP forwarding
+sysctl net.ipv4.ip_forward=1
+
+# Save current rules
+iptables-save > iptables_rules.txt
+
+# Set default chain policy
+iptables -P INPUT ACCEPT
+iptables -P FORWARD ACCEPT
+iptables -P OUTPUT ACCEPT
+
+# Flush existing rules
+iptables -t nat -F
+iptables -t nat -X
+iptables -t mangle -F
+iptables -t mangle -X
+iptables -F
+iptables -X
+
+# Port forwarding using SNAT & DNAT
+THIS_IP="192.168.1.234"
+THIS_PORT="21127"
+TARGET_IP="192.168.1.248"
+TARGET_PORT="9999"
+echo "Port forwarding: ${THIS_IP}:${THIS_PORT} <-> ${TARGET_IP}:${TARGET_PORT}"
+iptables -t nat -A PREROUTING \
+ -p tcp --dport ${THIS_PORT} \
+ -j DNAT --to-destination ${TARGET_IP}:${TARGET_PORT}
+iptables -t nat -A POSTROUTING \
+ -p tcp -d ${TARGET_IP} --dport ${TARGET_PORT} \
+ -j SNAT --to-source ${THIS_IP}:${THIS_PORT}
diff --git a/unix/jpegs2pdf.sh b/unix/jpegs2pdf.sh
new file mode 100755
index 0000000..ac992af
--- /dev/null
+++ b/unix/jpegs2pdf.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+#
+#############################################################################
+#
+# Shellscript to convert a set of JPEG files to a multipage PDF.
+#
+# Requirements: (1) Ghostscript needs to be installed on the local system.
+# (2) ImageMagick needs to be installed on the local system.
+#
+# Usage: jpegs2pdf.sh output.pdf file1.jpeg [file2.jpeg [file2.jpeg [...]]]
+#
+# Copyright (c) 2007, <pipitas@gmail.com>
+# Use, distribute and modify without any restrictions.
+#
+# Versions:
+# v1.0.0, Jul 12 2007: initial version
+# v1.0.1, Jan 07 2011: set viewJPEG.ps path (self-compiled GS 9.02)
+#
+#############################################################################
+
+outfile=$1
+shift
+
+param=""
+for i in "$@" ; do
+ dimension=$(identify -format "%[fx:(w)] %[fx:(h)]" "${i}")
+ param="${param} <</PageSize [${dimension}]>> setpagedevice (${i}) viewJPEG showpage"
+done
+
+gs \
+ -sDEVICE=pdfwrite \
+ -dPDFSETTINGS=/prepress \
+ -o "$outfile" \
+ viewjpeg.ps \
+ -c "${param}"
+
diff --git a/unix/lightsOn.sh b/unix/lightsOn.sh
new file mode 100644
index 0000000..99de6a9
--- /dev/null
+++ b/unix/lightsOn.sh
@@ -0,0 +1,217 @@
+#!/bin/bash
+# lightsOn.sh
+
+# Copyright (c) 2011 iye.cba at gmail com
+# url: https://github.com/iye/lightsOn
+# This script is licensed under GNU GPL version 2.0 or above
+
+# Description: Bash script that prevents the screensaver and display power
+# management (DPMS) to be activated when you are watching Flash Videos
+# fullscreen on Firefox and Chromium.
+# Can detect mplayer and VLC when they are fullscreen too but I have disabled
+# this by default.
+# lightsOn.sh needs xscreensaver, kscreensaver or gnome-screensaver to work.
+
+# HOW TO USE: Start the script with the number of seconds you want the checks
+# for fullscreen to be done. Example:
+# "./lightsOn.sh 120 &" will Check every 120 seconds if Mplayer,
+# VLC, Firefox or Chromium are fullscreen and delay screensaver and Power Management if so.
+# You want the number of seconds to be ~10 seconds less than the time it takes
+# your screensaver or Power Management to activate.
+# If you don't pass an argument, the checks are done every 50 seconds.
+
+
+# Modify these variables if you want this script to detect if Mplayer,
+# VLC or Firefox Flash Video are Fullscreen and disable
+# xscreensaver/kscreensaver/gnome-screensaver and PowerManagement.
+mplayer_detection=0
+vlc_detection=0
+firefox_flash_detection=1
+chromium_flash_detection=1
+html5_detection=1 #checks if the browser window is fullscreen; will disable the screensaver if the browser window is in fullscreen so it doesn't work correctly if you always use the browser (Firefox or Chromium) in fullscreen
+
+
+# YOU SHOULD NOT NEED TO MODIFY ANYTHING BELOW THIS LINE
+
+
+# enumerate all the attached screens
+displays=""
+while read id
+do
+ displays="$displays $id"
+done< <(xvinfo | sed -n 's/^screen #\([0-9]\+\)$/\1/p')
+
+# Detect screensaver been used (xscreensaver, kscreensaver, gnome-screensaver or none)
+if [ `pgrep -l xscreensaver | grep -wc xscreensaver` -ge 1 ];then
+ screensaver=xscreensaver
+elif [ `pgrep -l gnome-screensav | grep -wc gnome-screensav` -ge 1 ];then
+ screensaver=gnome-screensav
+elif [ `pgrep -l kscreensaver | grep -wc kscreensaver` -ge 1 ];then
+ screensaver=kscreensaver
+else
+ screensaver=None
+ echo "No screensaver detected"
+fi
+
+
+checkFullscreen()
+{
+ # loop through every display looking for a fullscreen window
+ for display in $displays
+ do
+ #get id of active window and clean output
+ activ_win_id=`DISPLAY=:0.${display} xprop -root _NET_ACTIVE_WINDOW`
+ #activ_win_id=${activ_win_id#*# } #gives error if xprop returns extra ", 0x0" (happens on some distros)
+ activ_win_id=${activ_win_id:40:9}
+
+ # Skip invalid window ids (commented as I could not reproduce a case
+ # where invalid id was returned, plus if id invalid
+ # isActivWinFullscreen will fail anyway.)
+ #if [ "$activ_win_id" = "0x0" ]; then
+ # continue
+ #fi
+
+ # Check if Active Window (the foremost window) is in fullscreen state
+ isActivWinFullscreen=`DISPLAY=:0.${display} xprop -id $activ_win_id | grep _NET_WM_STATE_FULLSCREEN`
+ if [[ "$isActivWinFullscreen" = *NET_WM_STATE_FULLSCREEN* ]];then
+ isAppRunning
+ var=$?
+ if [[ $var -eq 1 ]];then
+ delayScreensaver
+ fi
+ fi
+ done
+}
+
+
+
+
+
+# check if active windows is mplayer, vlc or firefox
+#TODO only window name in the variable activ_win_id, not whole line.
+#Then change IFs to detect more specifically the apps "<vlc>" and if process name exist
+
+isAppRunning()
+{
+ #Get title of active window
+ activ_win_title=`xprop -id $activ_win_id | grep "WM_CLASS(STRING)"` # I used WM_NAME(STRING) before, WM_CLASS more accurate.
+
+
+
+ # Check if user want to detect Video fullscreen on Firefox, modify variable firefox_flash_detection if you dont want Firefox detection
+ if [ $firefox_flash_detection == 1 ];then
+ if [[ "$activ_win_title" = *unknown* || "$activ_win_title" = *plugin-container* ]];then
+ # Check if plugin-container process is running
+ flash_process=`pgrep -l plugin-containe | grep -wc plugin-containe`
+ #(why was I using this line avobe? delete if pgrep -lc works ok)
+ #flash_process=`pgrep -lc plugin-containe`
+ if [[ $flash_process -ge 1 ]];then
+ return 1
+ fi
+ fi
+ fi
+
+
+ # Check if user want to detect Video fullscreen on Chromium, modify variable chromium_flash_detection if you dont want Chromium detection
+ if [ $chromium_flash_detection == 1 ];then
+ if [[ "$activ_win_title" = *exe* ]];then
+ # Check if Chromium Flash process is running
+ if [[ `pgrep -lfc "chromium-browser --type=plugin --plugin-path=/usr/lib/adobe-flashplugin"` -ge 1 || `pgrep -lfc "chromium-browser --type=plugin --plugin-path=/usr/lib/flashplugin-installer"` -ge 1 ]];then
+ return 1
+ fi
+ fi
+ fi
+
+ #html5 (Firefox or Chromium full-screen)
+ if [ $html5_detection == 1 ];then
+ if [[ "$activ_win_title" = *chromium-browser* || "$activ_win_title" = *Firefox* ]];then
+ #check if firefox or chromium is running.
+ if [[ `pgrep -l firefox | grep -wc firefox` -ge 1 || `pgrep -l chromium-browse | grep -wc chromium-browse` -ge 1 ]]; then
+ return 1
+ fi
+ fi
+ fi
+
+
+ #check if user want to detect mplayer fullscreen, modify variable mplayer_detection
+ if [ $mplayer_detection == 1 ];then
+ if [[ "$activ_win_title" = *mplayer* || "$activ_win_title" = *MPlayer* ]];then
+ #check if mplayer is running.
+ #mplayer_process=`pgrep -l mplayer | grep -wc mplayer`
+ mplayer_process=`pgrep -lc mplayer`
+ if [ $mplayer_process -ge 1 ]; then
+ return 1
+ fi
+ fi
+ fi
+
+
+ # Check if user want to detect vlc fullscreen, modify variable vlc_detection
+ if [ $vlc_detection == 1 ];then
+ if [[ "$activ_win_title" = *vlc* ]];then
+ #check if vlc is running.
+ #vlc_process=`pgrep -l vlc | grep -wc vlc`
+ vlc_process=`pgrep -lc vlc`
+ if [ $vlc_process -ge 1 ]; then
+ return 1
+ fi
+ fi
+ fi
+
+
+return 0
+}
+
+
+delayScreensaver()
+{
+
+ # reset inactivity time counter so screensaver is not started
+ if [ "$screensaver" == "xscreensaver" ]; then
+ #This tells xscreensaver to pretend that there has just been user activity. This means that if the screensaver is active (the screen is blanked), then this command will cause the screen to un-blank as if there had been keyboard or mouse activity. If the screen is locked, then the password dialog will pop up first, as usual. If the screen is not blanked, then this simulated user activity will re-start the countdown (so, issuing the -deactivate command periodically is one way to prevent the screen from blanking.)
+ xscreensaver-command -deactivate > /dev/null
+ elif [ "$screensaver" == "gnome-screensav" ]; then
+ dbus-send --session --type=method_call --dest=org.gnome.ScreenSaver --reply-timeout=20000 /org/gnome/ScreenSaver org.gnome.ScreenSaver.SimulateUserActivity > /dev/null
+ elif [ "$screensaver" == "kscreensaver" ]; then
+ qdbus org.freedesktop.ScreenSaver /ScreenSaver SimulateUserActivity > /dev/null
+ fi
+
+
+ #Check if DPMS is on. If it is, deactivate and reactivate again. If it is not, do nothing.
+ dpmsStatus=`xset -q | grep -ce 'DPMS is Enabled'`
+ if [ $dpmsStatus == 1 ];then
+ xset -dpms
+ xset dpms
+ fi
+
+}
+
+
+
+delay=$1
+
+
+# If argument empty, use 50 seconds as default.
+if [ -z "$1" ];then
+ delay=50
+fi
+
+
+# If argument is not integer quit.
+if [[ $1 = *[^0-9]* ]]; then
+ echo "The Argument \"$1\" is not valid, not an integer"
+ echo "Please use the time in seconds you want the checks to repeat."
+ echo "You want it to be ~10 seconds less than the time it takes your screensaver or DPMS to activate"
+ exit 1
+fi
+
+
+while true
+do
+ checkFullscreen
+ sleep $delay
+done
+
+
+exit 0
+
diff --git a/unix/link_dup.sh b/unix/link_dup.sh
new file mode 100755
index 0000000..ec54530
--- /dev/null
+++ b/unix/link_dup.sh
@@ -0,0 +1,93 @@
+#!/bin/sh
+#
+# Replace duplicate files with symbolic links.
+#
+# <dup_list> format (dup* will be removed and linked to FILE):
+# FILE dup1 dup2 ...
+#
+# NOTE:
+# * Filename cannot contain spaces.
+#
+# Weitian LI
+# 2015/03/06
+#
+
+err_msg() {
+ echo "$@" > /dev/stderr
+}
+
+usage() {
+ err_msg "Usage:"
+ err_msg " $1 <dup_list>"
+}
+
+md5() {
+ file="$1"
+ os=`uname -s`
+ case "${os}" in
+ Linux)
+ MD5=`md5sum ${file} | awk '{ print $1 }'`
+ ;;
+ FreeBSD)
+ MD5=`md5 ${file} | awk '{ print $NF }'`
+ ;;
+ *)
+ err_msg "ERROR: Unsupported OS: ${os}"
+ exit 255
+ esac
+ echo ${MD5}
+}
+
+mk_link_args() {
+ # Convert a dup_line of
+ # 'FILE dup1 dup2 ...'
+ # into format of
+ # 'FILE dup1'
+ # 'FILE dup2'
+ # '...'
+ # for use in link
+ echo "$@" | awk '{
+ for (i=2; i<=NF; i++) {
+ printf("%s %s\n", $1, $i);
+ }
+ }'
+}
+
+md5_link() {
+ # Link file if its md5 is equal to the original FILE.
+ # Args: 'FILE dup'
+ file="$1"
+ dup="$2"
+ file_path=`readlink -f "${file}"`
+ dup_path=`readlink -f "${dup}"`
+ if [ "${file_path}" = "${dup_path}" ]; then
+ err_msg "WARNING: '${file}' and '${dup}' are the same file"
+ else
+ md5_file=`md5 ${file}`
+ md5_dup=`md5 ${dup}`
+ if [ "${md5_file}" = "${md5_dup}" ]; then
+ #err_msg "rm -v \"${dup}\""
+ #err_msg "ln -sv \"${file}\" \"${dup}\""
+ rm -v "${dup}"
+ ln -sv "${file}" "${dup}"
+ else
+ err_msg "WARNING: '${file}' different to '${dup}'"
+ fi
+ fi
+}
+
+
+if [ $# -ne 1 ]; then
+ usage `basename $0`
+ exit 1
+fi
+
+dup_list="$1"
+cat "${dup_list}" | while read line; do
+ err_msg "${line}"
+ mk_link_args "${line}" | while read lk; do
+ err_msg " => " ${lk}
+ md5_link ${lk}
+ done
+done
+
diff --git a/unix/m4a_to_mp3.sh b/unix/m4a_to_mp3.sh
new file mode 100755
index 0000000..5d06cd9
--- /dev/null
+++ b/unix/m4a_to_mp3.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+bitrate=192
+
+for i in *.m4a; do
+ faad -o - "$i" | lame -h -b $bitrate - "${i%m4a}mp3"
+done
+
diff --git a/unix/pdfmerge.sh b/unix/pdfmerge.sh
new file mode 100755
index 0000000..aef72db
--- /dev/null
+++ b/unix/pdfmerge.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+#
+# Merge multiple PDFs with pdftk.
+#
+# Ref:
+# Merging Multiple PDFs under GNU/Linux
+# https://blog.dbrgn.ch/2013/8/14/merge-multiple-pdfs/
+#
+# Weitian LI
+# 2015/01/23
+#
+
+if [ $# -lt 2 ]; then
+ printf "Usage: `basename $0` out.pdf in1.pdf ...\n"
+ exit 1
+fi
+
+outpdf="$1"
+shift
+
+echo "Input files: $@"
+pdftk "$@" cat output "${outpdf}"
+
diff --git a/unix/shrinkpdf.sh b/unix/shrinkpdf.sh
new file mode 100755
index 0000000..56acef3
--- /dev/null
+++ b/unix/shrinkpdf.sh
@@ -0,0 +1,50 @@
+#!/bin/sh
+
+case "$1" in
+ -[hH]*|--[hH]*)
+ printf "usage:\n"
+ printf " `basename $0` in=<input.pdf> out=<output.pdf> quality=<screen|ebook|printer|prepress> imgdpi=<img_dpi>\n"
+ exit 1
+ ;;
+esac
+
+getopt_keyval() {
+ until [ -z "$1" ]
+ do
+ key=${1%%=*} # extract key
+ val=${1#*=} # extract value
+ keyval="${key}=\"${val}\""
+ echo "## getopt: eval '${keyval}'"
+ eval ${keyval}
+ shift # shift, process next one
+ done
+}
+getopt_keyval "$@"
+
+if [ -z "${in}" ] || [ -z "${out}" ]; then
+ printf "Error: 'in' or 'out' not specified\n"
+ exit 2
+fi
+quality=${quality:-ebook}
+imgdpi=${imgdpi:-120}
+
+printf "# in: ${in}
+# out: ${out}
+# quality: ${quality}
+# imgdpi: ${imgdpi}\n"
+
+gs -dNOPAUSE -dBATCH -dSAFER \
+ -sDEVICE=pdfwrite \
+ -dCompatibilityLevel=1.4 \
+ -dPDFSETTINGS="/${quality}" \
+ -dEmbedAllFonts=true \
+ -dSubsetFonts=true \
+ -dColorImageDownsampleType=/Bicubic \
+ -dColorImageResolution=${imgdpi} \
+ -dGrayImageDownsampleType=/Bicubic \
+ -dGrayImageResolution=${imgdpi} \
+ -dMonoImageDownsampleType=/Bicubic \
+ -dMonoImageResolution=${imgdpi} \
+ -sOutputFile=${out} \
+ ${in}
+
diff --git a/unix/term_color.sh b/unix/term_color.sh
new file mode 100755
index 0000000..f10f916
--- /dev/null
+++ b/unix/term_color.sh
@@ -0,0 +1,28 @@
+#!/usr/bin/env bash
+#
+# This file echoes a bunch of color codes to the
+# terminal to demonstrate what's available. Each
+# line is the color code of one forground color,
+# out of 17 (default + 16 escapes), followed by a
+# test use of that color on all nine background
+# colors (default + 8 escapes).
+#
+# Ref: https://wiki.archlinux.org/index.php/X_resources
+#
+
+T='gYw' # The test text
+
+echo -e "\n 40m 41m 42m 43m\
+ 44m 45m 46m 47m";
+
+for FGs in ' m' ' 1m' ' 30m' '1;30m' ' 31m' '1;31m' ' 32m' \
+ '1;32m' ' 33m' '1;33m' ' 34m' '1;34m' ' 35m' '1;35m' \
+ ' 36m' '1;36m' ' 37m' '1;37m';
+ do FG=${FGs// /}
+ echo -en " $FGs \033[$FG $T "
+ for BG in 40m 41m 42m 43m 44m 45m 46m 47m;
+ do echo -en "$EINS \033[$FG\033[$BG $T \033[0m";
+ done
+ echo;
+done
+echo
diff --git a/unix/term_color_2.sh b/unix/term_color_2.sh
new file mode 100755
index 0000000..4dc2ef2
--- /dev/null
+++ b/unix/term_color_2.sh
@@ -0,0 +1,32 @@
+#!/usr/bin/env bash
+# Original: http://frexx.de/xterm-256-notes/
+# http://frexx.de/xterm-256-notes/data/colortable16.sh
+# Modified by Aaron Griffin
+# and further by Kazuo Teramoto
+FGNAMES=(' black ' ' red ' ' green ' ' yellow' ' blue ' 'magenta' ' cyan ' ' white ')
+BGNAMES=('DFT' 'BLK' 'RED' 'GRN' 'YEL' 'BLU' 'MAG' 'CYN' 'WHT')
+
+echo " ┌──────────────────────────────────────────────────────────────────────────┐"
+for b in {0..8}; do
+ ((b>0)) && bg=$((b+39))
+
+ echo -en "\033[0m ${BGNAMES[b]} │ "
+
+ for f in {0..7}; do
+ echo -en "\033[${bg}m\033[$((f+30))m ${FGNAMES[f]} "
+ done
+
+ echo -en "\033[0m │"
+ echo -en "\033[0m\n\033[0m │ "
+
+ for f in {0..7}; do
+ echo -en "\033[${bg}m\033[1;$((f+30))m ${FGNAMES[f]} "
+ done
+
+ echo -en "\033[0m │"
+ echo -e "\033[0m"
+
+ ((b<8)) &&
+ echo " ├──────────────────────────────────────────────────────────────────────────┤"
+done
+echo " └──────────────────────────────────────────────────────────────────────────┘"
diff --git a/unix/term_color_3.sh b/unix/term_color_3.sh
new file mode 100755
index 0000000..85b499a
--- /dev/null
+++ b/unix/term_color_3.sh
@@ -0,0 +1,33 @@
+#!/usr/bin/env bash
+# Original: http://frexx.de/xterm-256-notes/
+# http://frexx.de/xterm-256-notes/data/colortable16.sh
+# Modified by Aaron Griffin
+# and further by Kazuo Teramoto
+
+
+FGNAMES=(' black ' ' red ' ' green ' ' yellow' ' blue ' 'magenta' ' cyan ' ' white ')
+BGNAMES=('DFT' 'BLK' 'RED' 'GRN' 'YEL' 'BLU' 'MAG' 'CYN' 'WHT')
+echo " ----------------------------------------------------------------------------"
+for b in $(seq 0 8); do
+ if [ "$b" -gt 0 ]; then
+ bg=$(($b+39))
+ fi
+
+ echo -en "\033[0m ${BGNAMES[$b]} : "
+ for f in $(seq 0 7); do
+ echo -en "\033[${bg}m\033[$(($f+30))m ${FGNAMES[$f]} "
+ done
+ echo -en "\033[0m :"
+
+ echo -en "\033[0m\n\033[0m : "
+ for f in $(seq 0 7); do
+ echo -en "\033[${bg}m\033[1;$(($f+30))m ${FGNAMES[$f]} "
+ done
+ echo -en "\033[0m :"
+ echo -e "\033[0m"
+
+ if [ "$b" -lt 8 ]; then
+ echo " ----------------------------------------------------------------------------"
+ fi
+done
+echo " ----------------------------------------------------------------------------"
diff --git a/unix/unzip-gbk.py b/unix/unzip-gbk.py
new file mode 100755
index 0000000..423e10f
--- /dev/null
+++ b/unix/unzip-gbk.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# unzip-gbk.py
+#
+# http://note.ninehills.info/linux-gbk.html
+#
+
+import os
+import sys
+import zipfile
+
+print "Processing File " + sys.argv[1]
+
+file=zipfile.ZipFile(sys.argv[1],"r");
+for name in file.namelist():
+ utf8name=name.decode('gbk')
+ print "Extracting " + utf8name
+ pathname = os.path.dirname(utf8name)
+ if not os.path.exists(pathname) and pathname!= "":
+ os.makedirs(pathname)
+ data = file.read(name)
+ if not os.path.exists(utf8name):
+ fo = open(utf8name, "w")
+ fo.write(data)
+ fo.close
+file.close()