sh Gen Self Sign Cert

Gen Self Sign Cert

gencert.sh
#!/bin/sh

# create self-signed server certificate:

read -p "Enter your domain [www.example.com]: " DOMAIN

echo "Create server key..."

openssl genrsa -des3 -out $DOMAIN.key 1024

echo "Create server certificate signing request..."

SUBJECT="/C=US/ST=Mars/L=iTranswarp/O=iTranswarp/OU=iTranswarp/CN=$DOMAIN"

openssl req -new -subj $SUBJECT -key $DOMAIN.key -out $DOMAIN.csr

echo "Remove password..."

mv $DOMAIN.key $DOMAIN.origin.key
openssl rsa -in $DOMAIN.origin.key -out $DOMAIN.key

echo "Sign SSL certificate..."

openssl x509 -req -days 3650 -in $DOMAIN.csr -signkey $DOMAIN.key -out $DOMAIN.crt

echo "TODO:"
echo "Copy $DOMAIN.crt to /etc/nginx/ssl/$DOMAIN.crt"
echo "Copy $DOMAIN.key to /etc/nginx/ssl/$DOMAIN.key"
echo "Add configuration in nginx:"
echo "server {"
echo "    ..."
echo "    listen 443 ssl;"
echo "    ssl_certificate     /etc/nginx/ssl/$DOMAIN.crt;"
echo "    ssl_certificate_key /etc/nginx/ssl/$DOMAIN.key;"
echo "}"

sh RCS deobf

RCS deobf

unobfuscate.js
var fs = require('fs')
var esprima = require('esprima')
var escodegen = require('escodegen')
var estraverse = require('estraverse')
var esrefactor = require('esrefactor')

var origFile = process.argv[2] || 'rs.min.js'
var outFile = origFile.replace(/\.min\.js$/, '.js')

var signatures = {}
try {
  signatures = parseSignatures(fs.readFileSync('rcs-method-signatures.txt', 'utf8'))
}
catch (e) {}

fs.readFile(origFile, { encoding: 'utf8' }, function (e, content) {
  var ast = esprima.parse(content, { range: true, comment: false })
  ast = removeEval(ast)
  var decl = getObfuscatedDeclaration(ast)
  var name = decl.id.name
  var map = decl.init.elements

  
  
  // replace a['b'] with a.b
  estraverse.replace(ast, {
    enter: function (node) {
      if (node.type === 'MemberExpression' && node.object.name === name) {
        return node.property && map[node.property.value] || node
      }
    },
    leave: function (node) {
      if (node.type === 'MemberExpression' && node.computed &&
          typeof node.property.value === 'string' &&
          /^[a-z_$][0-9a-z_$]*$/i.test(node.property.value)) {
        node.property = $smallRange({ type: 'Identifier', name: node.property.value })
        node.computed = false
      }
    }
  })

  ast = cleanAst(ast)

  if (signatures) {
    var getName = function (node) {
      if (node.type === 'Identifier') return node.name
      if (node.type === 'MemberExpression') {
        return getName(node.object) + '.' + getName(node.property)
      }
    }
    var renames = []
    estraverse.traverse(ast, {
      enter: function (node) {
        var name, fn
        if (node.type === 'FunctionDeclaration') {
          name = getName(node.id)
          fn = node
        }
        if (node.type === 'AssignmentExpression' &&
            node.right.type === 'FunctionExpression') {
          name = getName(node.left)
          fn = node.right
        }
        if (node.type === 'Property' &&
            node.value.type === 'FunctionExpression') {
          name = getName(node.key)
          fn = node.value
        }
        if (name && fn && name in signatures) {
          var params = signatures[name]
          params.forEach(function (newName, i) {
            if (fn.params[i])
            renames.push({
              idx: fn.params[i].range[0],
              to: newName
            })
          })
        }
        else {
          
        }
      }
    })
    processRenames(ast, renames)
  }

  var better = escodegen.generate(ast, {
    format: { indent: { style: '  ' } },
    comment: true
  })
  fs.writeFile(outFile, better, function (e) {
    console.log(e)
  })
})

function removeEval(ast) {
  var body = ast.body;
  if (body[0].type === 'ExpressionStatement') {
    body = body[0].expression.arguments[0]
  }
  //console.log(body);
  var data = escodegen.generate(body, {
    format: { indent: { style: '  ' } },
    comment: true
  });

  var code = eval("("+data+")")

  return esprima.parse(code, { range: true, comment: false })
}

function getObfuscatedDeclaration(ast) {
  var first
  var body = ast.body

  if (body[0].type === 'ExpressionStatement') {
    body = body[0].expression.argument.callee.body.body
  }
  // remove the obfuscated var map
  first = body.shift()
  if (first.type === 'VariableDeclaration') {
    var res = first.declarations.shift()

    var code = escodegen.generate(res.init, {
      format: { indent: { style: '  ' } },
      comment: true
    });
    var vals = esprima.parse(JSON.stringify(eval("("+code+")")))

    res.init = vals.body[0].expression

    // some scripts have more declarations bunched together, so we
    // should put the extra decls back in
    if (first.declarations.length > 0) {
      body.unshift(first)
    }
    return res
  }
}

function parseSignatures(string) {
  return string
    .split('\n')
    .filter(function (x) { return /^[a-z._0-9]+\((?:[a-z_0-9, ]*)\)$/i.test(x) })
    .map(function (line) { return /^([a-z._0-9]+)\((.*?)\)$/i.exec(line).slice(1) })
    .reduce(function (signatures, line) {
      var name = line[0], args = line[1].split(',').map(function (arg) { return arg.trim() })
      signatures[name] = args
      return signatures
    }, {})
}

function $id(name) {
  return $smallRange({ type: 'Identifier', name: name })
}
function $literal(value) { return { type: 'Literal', value: value } }
function $comment(ast, type, value) {
  ast.trailingComments = ast.trailingComments || []
  ast.trailingComments.push({
    type: type,
    value: value
  })
  return ast
}
function $largeRange(ast) { return ast.range = [ 0, Infinity ], ast }
function $smallRange(ast, n) {
  return ast.range = [ n || 0, n || 0 ], ast
}
function $statement(expr) {
  return {
    type: 'ExpressionStatement',
    expression: expr,
    range: expr.range
  }
}
function $block(stmt) {
  return stmt.type === 'BlockStatement' ? stmt : {
    type: 'BlockStatement',
    body: [ stmt ],
    range: stmt.range
  }
}

// expand ternary expression statements into if(){}else{} blocks
function expandTernary(expr) {
  return {
    type: 'IfStatement',
    range: expr.range,
    test: expr.test,
    consequent: $block($statement(expr.consequent)),
    alternate: expr.alternate.type === 'ConditionalExpression'
      ? expandTernary(expr.alternate)
      : $block($statement(expr.alternate))
  }
}

function wrapIfBranches(node) {
  if (node.consequent.type !== 'BlockStatement') {
    node.consequent = $block(node.consequent)
  }
  if (node.alternate && node.alternate !== 'BlockStatement') {
    node.alternate = $block(node.alternate)
  }
  return node
}
function wrapBody(node) {
  if (node.body.type !== 'BlockStatement') {
    node.body = $block(node.body)
  }
}
function expandAndOr(node) {
  if (node.expression.operator === '&&') {
    return {
      type: 'IfStatement',
      range: node.range,
      test: node.expression.left,
      consequent: $block($statement(node.expression.right))
    }
  }
  else if (node.expression.operator === '||') {
    return {
      type: 'IfStatement',
      range: node.range,
      test: {
        type: 'UnaryExpression',
        operator: '!',
        range: node.expression.left.range,
        argument: node.expression.left,
        prefix: true
      },
      consequent: $statement(node.expression.right)
    }
  }
  return node
}

var unyodaOperators = {
  '>': '<',
  '<': '>',
  '>=': '<=',
  '<=': '>='
}
function unyoda(node) {
  if (node.left.type === 'Literal' && node.right.type !== 'Literal') {
    var tmp = node.right
    node.right = node.left
    node.left = tmp
    if (node.operator in unyodaOperators) {
      node.operator = unyodaOperators[node.operator]
    }
  }
  return node
}

function findReturnVar(ast) {
  var lastSt = ast.body[ast.body.length - 1]
  if (lastSt && lastSt.type === 'ReturnStatement') {
    var retVal = lastSt.argument
    return retVal.type === 'NewExpression'
      ? retVal.callee
      : retVal.type === 'Identifier'
      ? retVal
      : null
  }
}

function cleanAst(ast) {
  estraverse.replace(ast, {
    enter: function (node) {
      // add braces around branch/loop constructs if they are not yet present
      if (node.type === 'IfStatement') {
        wrapIfBranches(node)
      }
      else if (node.type === 'ForStatement' ||
               node.type === 'WhileStatement') {
        wrapBody(node)
      }
      // turn !0, !1 into true, false
      else if (node.type === 'UnaryExpression' &&
               node.operator === '!' &&
               node.argument.type === 'Literal') {
        if (node.argument.value === 0) {
          return { type: 'Literal', value: true, raw: 'true' }
        }
        else if (node.argument.value === 1) {
          return { type: 'Literal', value: false, raw: 'false' }
        }
      }
      else if (node.type === 'BinaryExpression') {
        return unyoda(node)
      }
      // expand ternary ?: statements to if/else statements
      else if (node.type === 'ExpressionStatement' &&
               node.expression.type === 'ConditionalExpression') {
        return expandTernary(node.expression)
      }
      // expand compressed &&, || expressions into if/else statements
      else if (node.type === 'ExpressionStatement' &&
               node.expression.type === 'LogicalExpression') {
        return expandAndOr(node)
      }
      // expand some expressions into multiple statements
      else if (node.type === 'BlockStatement') {
        node.body = node.body.reduce(function (newBody, node) {
          // expand comma-separated expressions on a single line to multiple statements
          if (node.type === 'ExpressionStatement' &&
              node.expression.type === 'SequenceExpression') {
            return newBody.concat(node.expression.expressions.map($statement))
          }
          // expand comma-separated expressions in a return statement to multiple statements
          else if (node.type === 'ReturnStatement' &&
                   node.argument &&
                   node.argument.type === 'SequenceExpression') {
            var exprs = node.argument.expressions
            node.argument = exprs.pop()
            return newBody.concat(exprs.map($statement)).concat([ node ])
          }
          else if (node.type === 'EmptyStatement') {
            return newBody
          }
          return newBody.concat([ node ])
        }, [])
      }
    },
    leave: function (node) {
      // remove braces from else statements that contain only an if statement
      // (i.e. else if statements)
      if (node.type === 'IfStatement' &&
          node.alternate && node.alternate.type === 'BlockStatement' &&
          node.alternate.body.length === 1 && node.alternate.body[0].type === 'IfStatement') {
        node.alternate = node.alternate.body[0]
      }
      return node
    }
  })

  return ast
}

function processRenames(ast, renames) {
  var renaming = new esrefactor.Context(ast)
  renames.forEach(function (r) {
    var id = renaming.identify(r.idx)
    if (id) {
      // rename manually.
      // esrefactor renames things "in-place" in the source code,
      // which means that you have to parse the source again every
      // time you rename a variable. Since we don't need to retain
      // formatting (it's minified code at this point, after all)
      // we can manually rename all variables at once without ever
      // parsing the source again.
      if (id.identifier) id.identifier.name = r.to
      if (id.declaration) id.declaration.name = r.to
      id.references.forEach(function (node) { node.name = r.to })
    }
  })
  return ast
}
rcs-method-signatures.txt
iterate(spec, object)
getModule(spec)
API.getUserByName(name)
f(command)
validURL(url)
htmlspecialchars(string)
striphtml(string)
isNumber(string)
sendSocket(action, param)
weirdEscape(string)
spawnNotification(title, message)
secondsToTimeClean(seconds)
addChatLog(className, iconClass, title, message)
addChatLogSmall(className, iconClass, title, message)
addRawChatLog(className, iconClass, title, message)
addRawChatLogSmall(className, iconClass, title, message)
addChatReceive(className, user, message)
contextClass(user)
getSpecialRank(uid)
getUserFromArgs(string)
langVar(string, values)
getFiles(done)
setCookie(name, value)
getCookie(name)
cleanASCII(string)
rsDelete(cid)
rsDebugMode(log)
parseDescription(description)
avatar(avatarId)
badge(badgeId)
language(langId)
rsCheckUpdates(__)
rsCheckUpdatesForced(__)
rsCheckLocation(__)
getSessionData(uid, key, defaultValue)
setSessionData(uid, key, value)
__onWaitlistUpdate(update)
__onWait_list_update(update)
__onDJAdvance(advance)
__autoJoin(advance)
__onChat(message)
rs.socket.onmessage(message)
__getPlaylists(force)
__onVoteUpdate(vote)
__onUserJoin(user)
__onUserLeave(user)
__onGrabUpdate(grab)
__onChatCommand(text)
__onScoreUpdate(score)
__onSkip(__)
__roomState(state)
__autoMute(advance)
__voteRecording(vote)
__grabRecording(grab)
__argumentParser(string)
__commandController(string)
__lengthAlert(advance)
__smartVote(advance)
__castVote(advance)
__userJoin(user)
__userLeave(user)
__userWoot(vote)
__userMeh(vote)
__userGrab(grab)
__chatLog(message)
__autoRespond(message)
__chatCMD(message)
__chatNotifications(message)
__mentionNotification(message)
__chatHistory(message)
__historyCheck(advance)
__getPermission(user)
__songStats(advance)
__mehRow(advance)
__nowPlaying(advance)
__inlineImages(message)
__customEmotes(message)
__checkImages(url, messageEl, __href)
__checkEmotes(url, messageEl, name)
__baBanUID(uid)
__baMuteUID(uid)
__baTrollUID(uid)
__baDelTrollUID(uid)
__userInformation(user, __)
__uiSkipButton(user)
__etaInfo(isSelf)
__checkLocked(message)
__onChatReceived(message)
package.json
{
  "dependencies": {
    "escodegen": "",
    "esprima": "",
    "esrefactor": "",
    "estraverse": ""
  }
}
get-rcs.sh
#!/bin/sh

mkdir rcs/$(date '+%m%d')

curl https://code.radiant.dj/rs.min.js -o rcs/$(date '+%m%d')/rs.min.js
node unobfuscate rcs/$(date '+%m%d')/rs.min.js

sh OS X 10.10 Yosemite升级检查

OS X 10.10 Yosemite升级检查

upgrade_check.sh
#!/bin/bash
# OS X 10.10 Yosemite Upgrade
#
# Prerequisites for this upgrade:
# (this computer already checked and passed)
# - OS X 10.6.8+ already installed
# - 2 GB or more of memory
# - 8 GB or more of available disk space
# - 64-bit CPU
# - Supported Mac hardware model

os_upgrade_version="OS X 10.10 Yosemite"

######################
# Check Operating System Version
######################
product_version=$(sw_vers -productVersion)
os_vers=$(echo $product_version | cut -d "." -f1)
os_vers_major=$(echo $product_version | cut -d "." -f2)
os_vers_minor=$(echo $product_version | cut -d "." -f3)
echo "Current OS:       ${os_vers}.${os_vers_major}.${os_vers_minor}"

if [ $os_vers==10 ] && [ ${os_vers_major} -ge 10 ]; then
    echo "Current Operating System is ${os_upgrade_version} or newer already. Quitting."
    exit 1
fi

case $os_vers_major in
    [7-9])
        echo "Current Operating System is eligible for an upgrade to ${os_upgrade_version}."
        ;;
    6)
        if [[ $os_vers_minor == 8 ]]; then
            echo "Current Operating System is eligible for an upgrade to ${os_upgrade_version}."
        else
            echo "Current Operating System is too old to upgrade to ${os_upgrade_version}."
            exit 1
        fi
        ;;
    *)
        echo "Unable to determine if your system is eligible for an upgrade to ${os_upgrade_version}"
        exit 1
        ;;
esac

# Check CPU Architecture
# Only 64-bit is Supported
hwcpu64bit=$(sysctl -n hw.cpu64bit_capable)
if [[ $hwcpu64bit ]]; then
        echo "64-bit processor detected."
else
        echo "64-bit processor not detected. Quitting."
        exit 1
fi

######################
# Check hardware model
######################
hwmodel=$(sysctl -n hw.model)
hwmodel_name=$(echo ${hwmodel} | sed 's/[[:digit:]].*//')
hwmodel_num=$(echo ${hwmodel} | sed 's/[^[:digit:]]*//' | cut -d, -f1)
hwmodel_rev=$(echo ${hwmodel} | sed 's/[^[:digit:]]*//' | cut -d, -f2)
hwmodel_pass=0

# iMac
# Macmini
# MacPro
# MacBook
# MacBookPro
# MacBookAir
# Xserve
# http://www.everymac.com/mac-answers/os-x-yosemite-faq/os-x-yosemite-compatible-macs-system-requirements.html

if [[ "${hwmodel_name}" == "iMac" ]]; then
    if [[ ${hwmodel_num} -ge 7 ]]; then
        hwmodel_pass=1
    fi
elif [[ "${hwmodel_name}" == "MacBook" ]]; then
    if [[ ${hwmodel_num} -ge 5 ]]; then
        hwmodel_pass=1
    fi
elif [[ "${hwmodel_name}" == "MacBookAir" ]]; then
    if [[ ${hwmodel_num} -ge 2 ]]; then
        hwmodel_pass=1
    fi
elif [[ "${hwmodel_name}" == "MacBookPro" ]]; then
    if [[ ${hwmodel_num} -ge 3 ]]; then
        hwmodel_pass=1
    fi
elif [[ "${hwmodel_name}" == "Macmini" ]]; then
    if [[ ${hwmodel_num} -ge 3 ]]; then
        hwmodel_pass=1
    fi
elif [[ "${hwmodel_name}" == "MacPro" ]]; then
    if [[ ${hwmodel_num} -ge 3 ]]; then
        hwmodel_pass=1
    fi
fi

if [[ ${hwmodel_pass} ]]; then
    echo "Model Identifier: ${hwmodel}"
else
    echo "This computer does not meet the hardware model requirements for ${os_upgrade_version}. Quitting."
    exit 1
fi

######################
# Check system specs
######################
# RAM
hwmemsize=$(sysctl -n hw.memsize)
# 1024**3 = GB
ramsize=$(expr $hwmemsize / $((1024**3)))

if [[ ${ramsize} -ge "2" ]]; then
    echo "System Memory:    ${ramsize} GB"
    hwmemsize_pass=1
else
    echo "Less than 2GB of RAM detected. Quitting."
    exit 1
fi

# Disk Space
diskutil_plist="$(mktemp -t "diskutil").plist"
diskutil info -plist / > ${diskutil_plist}
freespace=$(defaults read "${diskutil_plist}" FreeSpace)
rm "${diskutil_plist}"
# 1024**3 = GB
freespace=$(expr $freespace / $((1024**3)))

if [[ $freespace -ge "8" ]]; then
    echo "Free Space:       ${freespace} GB"
else
    echo "Less than 8GB of free disk space detected. Quitting."
    exit 1
fi

echo "This computer has passed all checks and is eligible for an upgrade to ${os_upgrade_version}."
exit 0

sh Mac模型标识符

Mac模型标识符

hw.model.sh
hwmodel=$(sysctl -n hw.model)
hwmodel_name=$(echo ${hwmodel} | sed 's/[[:digit:]].*//')
hwmodel_num=$(echo ${hwmodel} | sed 's/[^[:digit:]]*//' | cut -d, -f1)
hwmodel_rev=$(echo ${hwmodel} | sed 's/[^[:digit:]]*//' | cut -d, -f2)

sh 在Fedora或RHEL上安装ElasticSearch

在Fedora或RHEL上安装ElasticSearch

es.sh
cd ~
sudo yum update
sudo yum install java-1.7.0-openjdk.x86_64 -y
sudo yum install wget

wget https://download.elastic.co/elasticsearch/elasticsearch/elasticsearch-1.7.2.tar.gz -O elasticsearch.tar.gz

tar -xf elasticsearch.tar.gz
rm elasticsearch.tar.gz
mv elasticsearch-* elasticsearch
sudo mv elasticsearch /usr/local/share

curl -L http://github.com/elasticsearch/elasticsearch-servicewrapper/tarball/master | tar -xz
sudo mv *servicewrapper*/service /usr/local/share/elasticsearch/bin/
rm -Rf *servicewrapper*
sudo /usr/local/share/elasticsearch/bin/service/elasticsearch install
sudo /etc/init.d/elasticsearch start

# can test with:
# curl http://localhost:9200 

sh golang工具设置

golang工具设置

golang.sh
#!/usr/bin/env bash

// dependencies
go get github.com/tools/godep
// go get github.com/constabulary/gb/...

// testing
go get github.com/onsi/ginkgo/ginkgo
go get github.com/onsi/gomega

// building
go get github.com/pilu/fresh

sh Linux的常用命令

Linux的常用命令

other.sh
#查找. 常用命令,让我们来找一下10MB以上的文件吧
find . -type f -size +10000k -exec ls -lh {} \; | awk '{ print $5 ": " $9 }' |sort -n

#Grep, 手里握着大西瓜 
ls -alh | grep ooxx
#只显示含有ooxx的那几列,当然你在cat的时候配合这个用找文件里的某些字段很方便

#分页 (Less/More)
less miao.php
#如果源代码很长,则会分页显示,上下箭头滚动,输入q退出
tail -n 1000 /var/log/httpd/error_log | more
#可以用 | more 参数来滚动显示页面或行
file.sh
#显示磁盘使用率
df

#列表文件/子目录使用率 (du)
du
#会列出所有文件以及子目录的大小,不是人看的...
du -sh
#-s就是summary,只输出当前文件夹总容量
#-h一般在linux就是human给人看的意思,会把1048580b转换为1mb显示
du -h --max-depth=1
#嘿,只列出当前文件夹和第一级子目录占用大小

#删除文件 Remove files (rm) 少儿不宜的命令,总是需要确认
rm -vf miao.in
#强制删除miao.in这个文件并不需确认,列出删除文件列表

#强制删除,不要执行,除非你知道你在干嘛...
#-v一般v参数都是显示过程的意思
#-f 强奸的单词会不会拼? F-U-C-K的缩写,不确认直接F-word了
rm -rf ooxx
#删除ooxx这个文件夹,包含它的子文件和子文件夹

#删除文件用上面的命令,但删除文件夹的时候就需要跑下遍历了
#-r 比较本土化,是"日"的缩写,在所有命令里都是 recursive 的意思,有些命令是大写的 R 需要注意

#拷贝文件 (cp)
cp bigc.at miao.in
#复制bigc.at这个文件并重命名为miao.in

#移动文件/重命名 (mv)
mv bigc.at miao.in

#创建空文件 (touch)
touch miao.in
chmod.sh
#更改文件权限 (chmod)
chmod 777 miao.in
#默认文件为644,文件夹为755

#TIP:
#1st digit=Owner; 2nd=Group; 3rd=Other
#(-rwxrwxwrx = 777, -rwxr-xr-x = 755, -rw-r--r-- = 644, etc.)
#7 = Read + Write + Execute
#6 = Read + Write
#5 = Read + Execute
#4 = Read
#3 = Write + Execute
#2 = Write
#1 = Execute
#0 = All access denied
base.sh
#显示文件源代码
cat ooxx.php

#查看当前目录
pwd


#更改目录 Change Directory (cd)
cd /path/to/directory/

#列出文件/子目录 Listing Files/SubFolders(ls)
ls
#默认只显示文件名,你也可以带个参数玩,比如
ls -alh
#带 -alh 输出会很爽... 自己试试, 大猫喜欢把 ls -alh 颜射为 ll
#-a显示全部文件
#-l比较详细的列表
#-h人类能看懂的比如把1024显示为1K

#获取远程文件 wget
wget http://bigc.at/me.jpg

#压缩解压缩
unzip wordpress.zip
#如果文件是zip形式的,比如刚从wordpress主站wget了一个压缩包过来,只需要输入unzip 文件名,就可以解压缩到当前目录了
tar -czvf ooxx.tar.gz * .[!.]*
#把当前目录所有文件以tar命令打包为ooxx.tar.gz文件
#-c创建
#-z用gzip压缩方式
#-v显示压缩过程
#-f搞成一坨file
tar -xzvf ooxx.tar.gz
#解压缩 ooxx.tar.gz 里的文件到当前目录
#-x解压缩
#-z用gzip压缩方式
#-v显示压缩过程
#-f搞成一坨file

sh 脚本

脚本

jpg_folder2gif.sh
#!/usr/bin/env bash

video2gif.sh
#!/usr/bin/env bash

# ffmpeg -i ${1}  -vf scale=320:-1,format=rgb8,format=rgb24 ${1%.*}.gif
# ffmpeg -i ${1}  -r 1 -vf format=rgb24 ${1%.*}.gif
# ffmpeg -i ${1}  -r 1 -f image2pipe -vcodec ppm - | convert -delay 0 -loop 0  gif:- | convert -layers Optimize - output.gif

ffmpeg -i ${1} -r 3 -f image2pipe -vcodec ppm - | convert -delay 5 -loop 0 - gif: - | convert -layers Optimize - output.gif

# - o.gif # ${1%.*}.gif
video_to_gif.sh
#!/usr/bin/env bash


f=${$1%.*}
mkdir -p $f

mplayer -ao null ${1} -vo jpeg:outdir=${f}
video_to_jpeg.sh
#!/usr/bin/env bash


f=${1%.*}
mkdir -p $f

mplayer -ao null ${1} -vo jpeg:outdir=${f}

sh 最常用的是Android keytool命令

最常用的是Android keytool命令

list_android_keystore_aliases.sh
# Listing Aliases Inside an Android Keystore File With Keytool
keytool -list -v -keystore /location/of/your/com.example.keystore
generate_android_keystore.sh
# Generate a private key using Android keytool
keytool -genkeypair -v -keystore <KEYSTORE_FILE_PATH> -alias <ALIAS_NAME> -keyalg RSA -sigalg SHA1withRSA -keysize 2048 -validity 10000
delete_android_keystore_entry.sh
keytool -delete -alias <ALIAS> -keystore <KEYSTORE>
change_android_keystore_entry_password.sh
keytool -keypasswd -alias <ALIAS> -keystore <KEYSTORE>

sh 进行无头硒测试。

进行无头硒测试。

headless_selenium.bash
Xvfb :1 -ac
DISPLAY=":1" && java -jar ~/path/to/selenium-server-standalone-2.46.0.jar