_RJ 技術メモ

人生を豊かにする技術を提供する、筋肉

tarコマンドが覚えられないので、簡単に指定できるエイリアス(圧縮のみ)

Bash alias Linux Terminal Mac

概要

圧縮しようとするたびに感じるのが、tarコマンドを覚えようとしても引数が多かったり、拡張子と引数が頭の中でリンクしなかったりなど、覚えるのには少しハードルが高いと感じる。zipコマンドのようにzip fileのように指定するだけで圧縮したいと思い、以下のエイリアスを設定した。圧縮形式も選択できる。

コマンドの使い方

  • 引数により圧縮形式を選べる (low=-l, middle=-m, high=-h)
  • ディレクトリの指定可 (/dir/fileなど)
  • 圧縮拡張子は自動で付与
  • etarはeasy-tarの略 (解凍の時はunetarにしたい)

通常の圧縮(tar.gz)

$ etar file1
file1.tar.gz

出力ファイルを指定して通常の圧縮(tar.gz)

出力ファイルの拡張子の指定はいらない

$ etar file1 file2
file2.tar.gz

高圧縮(tar.gz2)

-m(middle)を引数にする

$ etar -m file1 file2
file2.tar.gz2

超高圧縮(tar.xz)

-h(high)を引数にする

$ etar -h file1 file2
file2.tar.xz

導入方法

.bash_profileに追記か、別ファイルの作ってsourceを通す プログレスの表示のためpvコマンドを使用しているので、pvのインストールが必要

$ brew install pv #mac osx
$ yum install pv #centos
$ yum install pv #debian
$ vim ~/.bash_profile
#以下のソースコードを.bash_profileに追記する
function etar(){
  #使い方
  function etarUsage(){
    echo 'etar: usage:
    etar [input file] [output file]
    etar -l [input file] [output file]
    etar -m [input file] [output file]
    etar -h [input file] [output file]'
  }

  #引数がない場合
  if [ $# == 0 ]; then
    etarUsage
    return
  fi
  
  #引数がある場合
  if [ ${1:0:1} = '-' ]; then  #-からの引数がある場合
    if [ $1 == '-h' ]; then #超高圧縮(tar.xz)
      if [ $# == 3 ]; then
        tar Jcf - $2 | pv > $3.tar.xz
      else
        tar Jcf - $2 | pv > ${2%.*}.tar.xz
      fi
    elif [ $1 = '-m' ]; then #高圧縮(tar.gz2)
      if [ $# == 3 ]; then
        tar jcf - $2 | pv > $3.tar.gz2
      else
        tar jcf - $2 | pv > ${2%.*}.tar.gz2
      fi
    elif [ $1 = '-l' ]; then  #通常圧縮(tar.gz)
      if [ $# == 3 ]; then
        tar zcf - $2 | pv > $3.tar.gz
      else
        tar zcf - $2 | pv > ${2%.*}.tar.gz
      fi
    else  #引数が存在しない
      etarUsage
    fi
  else #引数がファイルのみ tar.gz
    if [ $# == 2 ]; then
      tar zcf - $1 | pv > $2.tar.gz
    else
      tar zcf - $1 | pv > ${1%.*}.tar.gz
    fi
  fi
}

alias etar=etar

今後について

解凍のコマンドも作りたい (unetar)

簡易的にWebサーバーを監視して、停止時にSlackに投稿する

GoogleAppsScript Slack httpd slackbot JavaScript

概要

Webサーバーが落ちていないかを簡易的に監視するツールをGASで作成。 Dockerのコンテナで複数サーバーを運用しているが、別コンテナでSeleniumを動かしていたため、最近の話だがメモリ不足でサーバーが半日ほど停止し、検索順位が大幅に落ちるという恐怖を味わったので、GASに監視を代行させる。

スクリーンショット 2017-03-12 2.50.47.png

事前準備

  1. SlackのAPIキーを取得する
  2. Slackのチャンネルにserver-monitorを追加する
  3. GASのトリガーを、5分から15分くらいに設定する

ソースコード

  1. UrlFetchApp.fetch(url)でソースを取得
  2. try-catchによりエラーを捕捉()
  3. エラー捕捉時、スラックに投稿する
function myFunction() {
  var url = 'WebサーバーのURL';
  
  try{
    UrlFetchApp.fetch(url);
    Logger.log('Success'); 
  }catch(e){
    postSlack('server-monitor', 'httpd-server-monitor', 'ウェブサーバーが障害により停止している可能性があります。 \n' + url);
    Logger.log('Failure'); 
  }
}


function postSlack(channelname, username, message){
  //Get channels
  var slackApp = SlackApp.create('APIキー');
  var channels = slackApp.channelsList().channels;
  
  Logger.log(channels);
  
  //Channel check
  var channel = null;
  channels.forEach(function(v, i){
    if(v.name == channelname){
     channel = v; 
    }
  });

  //Post Message
  slackApp.postMessage(channel.id, message, {
    username : username
  }); 
}

補足

あくまで簡易的なので、アクセス集中時のエラーページなどの判定は行わない。

Amazonのコンビニ受け取りメールの受け取り番号をSlackで通知する

GoogleAppsScript gmail JavaScript Slack

概要

Slack投稿は外部ライブラリのSlackAppを使用 コンビニ受け取りを多く使用するかつ、Gmailを開くのが面倒だったから作成

ソースコード

未読のAmazonのコンビニ受け取りメールの受け取り番号をSlackで通知する。 そしてメールを既読にする。

function myFunction() {
  var strTerms = '店舗到着済:受取方法をご案内します is:unread';
 
  var myThreads = GmailApp.search(strTerms, 0, 30); 
  var myMessages = GmailApp.getMessagesForThreads(myThreads); 
 
  for(var i=0;i < myMessages.length;i++){
    var message = myMessages[i][0];
    Logger.log(message.getSubject());  
    //Logger.log(myMessages[i][0].getPlainBody().slice(0,1000)); 
    
    var text = message.getPlainBody().slice(0,1000);
    var start = text.indexOf('お問い合わせ番号:');
    
    var number = text.slice(start, start + 37);
    postSlack('amazon-delivery-mail', 'amazon-delivery', number);
    
    message.markRead();
  }
}


function postSlack(channelname, username, message){
  //Get channels
  var slackApp = SlackApp.create('xoxp-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx');
  var channels = slackApp.channelsList().channels;
  
  Logger.log(channels);
  
  //Channel check
  var channel = null;
  channels.forEach(function(v, i){
    if(v.name == channelname){
     channel = v; 
    }
  });

  //Post Message
  slackApp.postMessage(channel.id, message, {
    username : username
  }); 
}

cd(Change Directory)をaliasで省略する

Bash alias Linux Mac Dvorak

ホームポジションから考えると、 左手人差し指のfをcdとして使う。

$ alias f='cd'
$ f /var/www

左人差指(F)→親指(Space)…→小指(Enter) で移動できる。

打鍵後のスペースの手間も省くなら、 スペースの真上のvをcdとして使う。

$ alias v='cd'
$ v /var/www

指をスライドさせてスペースも同時に打てるので、 左人差指(V)→左人差指を下へスライド(Spage)…→小指(Enter) で移動できる。

自分自身の環境ならば~/.bash_profileなどに追記する。 人の環境だったら、aliasで毎回設定する。

ちなみに自分はDvorakなので、

$ alias u='cd'

ターミナルのホスト名を消して時刻とディレクトリを表示

Bash bashrc bash_profile Terminal

test3.gif

~/.bash_profileなどに記述する。

コマンド

$ PS1="\t \w $"

オプション

Chrome拡張でGoogleのサイト翻訳の原文と翻訳を同時表示したい(失敗)

Chrome chrome-extension google translation JavaScript

スクリーンショット 2016-12-20 19.51.18.png

経緯

Googleのサイトの翻訳で原文と翻訳後の文章を同時表示すれば、英語学習とか原文を確認する手間が省けるのでは思い、Chrome拡張機能を作ってみて同時表示を試してみたが、翻訳後の文章はiframeを使用していたため、cross-originに引っかかり結果失敗。

手法

Google翻訳では要素の文章の前に、.google-src-textという原文の要素が挿入されるので、このクラスを削除して、改行を追加すればいけるのではと考えた。

<span class="google-src-text" style="direction: ltr; text-align: left">Services</span>
サービス
<span style="direction: ltr; text-align: left">Services<br></span>
サービス

実装

以下3つのファイルを一つのディレクトリにまとめる。

  • manifest.json(Chrome拡張の設定)
  • jquery-1.12.3.min.js(manifest.jsonに記述したバージョン)
  • script.js(メイン)
{
  "name": "ShowOriginalTextOnGoogleTranslate",
  "version": "0.0.1",
  "manifest_version": 2,
  "description": "",
  "permissions":[],
  "content_scripts": [
    {
      "matches": ["https://translate.google.com/translate*"],
      "js": ["jquery-1.12.3.min.js","script.js"],
      "run_at": "document_start"
    }
  ]
}
console.log('Show Original Text On Google Translate');

$(function () {
    _$anno1 = $('#anno1');
    _$anno2 = $('#anno2');

    //同時表示ボタン
    $anno3 = _$anno1.clone().attr('id', 'anno3').text('原文と翻訳').css('border-left', 'none');
    _$anno2.before($anno3);

    //ここから下で失敗
    $anno3.on('click', function(){
        var $iframe = $('#contentframe>iframe').contents();

        $iframe.find('.google-src-text').each(function(v){
            $(v).removeClass('google-src-text').append('<br />');
        });
    });
});

ディレクトリごとChrome拡張機能の設定にて読み込む。

結果

iframeのせいで、結局cross-originで失敗。

スクリーンショット 2016-12-20 19.53.11.png

Chrome拡張でframeを突破する方法があればなあ。