ゆるゆるエンジニアの技術メモ

神奈川在住のITエンジニアの忘備録です。主にプログラミング(Perl, Java など)やネットワーク技術について、学んだことを自分の中で整理するために書いています。書いたことが誰かのご参考になれば幸いです。

gitでコミットする前にステージする理由

gitでは、リポジトリにコミットする前に、作業ディレクトリからステージング領域にファイルを上げる(addする)。つまり、以下のようなイメージ。

作業ディレクトリ ---add---> ステージング領域 ---commit---> リポジトリ

コミットすると、gitはステージング領域にあるファイルをリポジトリにコミットする。

ここで、何故ステージング領域が必要かと言うと、例えば、しばらくコミットし忘れて、作業ディレクトリ内の多数のファイルを編集した後、編集したファイルのうち一部だけをコミットしたい場合があると思う。この時、コミットしたいファイルだけをaddしておけば、作業ディレクトリに対してコミットした時に、事前にaddしたファイルのみがリポジトリに追加される。まあ、コミットする単位を作業ディレクトリではなく、対象のファイルのみにすれば、ステージング領域は経由しなくても良いのだが。

簡単に纏めると、gitに対して、「作業ディレクトリ内のこのファイルとこのファイルをリポジトリへの追加対象にして下さい」と伝えるために、ステージング領域があるのだと思う。

perlで文字列から1文字ずつ取得

perl で文字列から1文字ずつ取得して配列に格納するには、以下のように split 関数を使うのが楽。

splitString.pl

use strict;
use warnings;
use Encode;

my $inputStr = shift;
my $decodedInputStr = decode('Shift_JIS', $inputStr); # SJISの文字列から内部文字列に変換
my @chars = getCharsArray($decodedInputStr);

foreach my $char (@chars) {
    my $encodedChar = encode('Shift_JIS', $char); # 内部文字からSJISの文字に変換
    print "$encodedChar\n";
}

sub getCharsArray {
    my $str = shift;
    my @chars = split(//, $str); # ★ここ!
    return @chars;
}


上記のスクリプトを、

splitString.pl abcあいう

として実行すると、一文字ずつ分けられて、

a
b
c


と出力される。

なお、上記のスクリプトSJIS 環境で実行したので、SJIS の文字列から内部文字列(≒UTF-8)にデコードする処理と、内部文字からSJISの文字にエンコードする処理が入っている。(マルチバイト文字対策)

内部文字コードを意識する時

プログラミング言語には、内部文字列の文字コード(以下、内部文字コードと呼ぶ)がある。

外部から読み込んだデータをそのままで扱う場合は内部文字コードを意識することはないが、読み取ったデータを文字列として扱ってゴニョニョする場合は、一旦、内部文字コードに変換されることになる。なので、外部から読み込んだデータの文字コード⇒内部文字コードへの変換の処理(デコード処理)を書かないといけないことが多い。この処理がないと、誤った変換が行われてデータが解釈不能なものになってしまうことがある。

また、内部文字コードに変換したら、それを出力する時は、出力先で扱える文字コードに合わせて、内部文字コードから外部文字コードに適切にエンコードする必要がある。

tasklistコマンドで表示されるメモリ量

Windows上で tasklistコマンドを実行すると、例えば以下のように、プロセスのメモリ量が表示される。

chrome.exe 11060 Console 1 ★22,748 K 

一方で、タスクマネージャーでは、 メモリ量に関係する項目として以下を表示することができる。

  • ワーキング セット
  • プライベート ワーキング セット
  • 共有ワーキング セット

 

tasklistコマンドで表示されるメモリ量が、タスクマネージャーの表示するどのメモリ量に該当するか調べてみたところ、「ワーキング セット」に該当していた。

なお、「ワーキング セット」の定義は、

ワーキング セット = プライベート ワーキング セット(プロセス固有のメモリ量) + 共有ワーキング セット(他プロセスと共有しているメモリ量)

となっていた。この辺の関係は、以下のMicrosoftのページに説明がある。

メモリ管理と重要なメモリ測定値について理解する

 

つまり、tasklistコマンドが表示するメモリ量は、

プロセス固有のメモリ量 + 他プロセスと共有しているメモリ量

ということになる。

定期的にメモリ量を取得する。

引数で指定されたPIDを持つプロセスのメモリ量を定期的に出力するbatファイルを作成した。

getMem.bat

@echo off

set pid=%1

:loop
    set /p=%date% %time% <nul,
    tasklist /fo csv /fi "pid eq %pid%" /nh
    timeout 60 > nul
 
goto :loop

メモリ量を取得したいプロセスのPIDを引数にして、例えば、

getMem.bat 9928

と実行すると、以下のように60秒間隔で対象プロセスのメモリ量を取得する。(メモリ値は最後のカラム)

2018/09/17 19:14:51.17 ,"chrome.exe","9928","Console","1","198,056 K"
2018/09/17 19:15:51.16 ,"chrome.exe","9928","Console","1","198,864 K"
2018/09/17 19:16:51.15 ,"chrome.exe","9928","Console","1","198,452 K"
2018/09/17 19:17:03.80 ,"chrome.exe","9928","Console","1","198,784 K"
・・・

上記ようにcsv 形式で出力しているので、これをエクセルで開けばグラフが簡単に描ける。メモリリークの調査などに使用すると便利だと思う。

改行しないechoコマンドもどき

Windowsで改行しないechoを行うための方法について書く。

Windowsで、例えば現在時刻を表示するために、

echo %date% %time%

と実行すると、時刻の後に改行が表示されるので、時刻とそれに続く内容を一行で表示したい時に困る。

これを解決するには、set /p コマンドを使用する。set /p コマンドは、

set /p 入力情報を入れる変数=コマンド実行時の表示文字列

という形式で使用する。この「コマンド実行時の表示文字列」の後には改行が付かないので、それを利用し以下のようにする。

set /p x=%date% %time% <nul

「<nul」は、入力文字列は必要なく、これがないと入力待ちになってしまうので付けている。ちなみに上記では、便宜上、変数 x を使用したが、これを省略した以下でもOKだった。(Windows10で検証済み)

set /p=%date% %time% <nul
set /p<nul=%date% %time%

 

ただ、この方法は、Windows(Microsoft)側が意図した使い方ではないような気がするので、Windowsのバージョンが挙がった際に挙動が変わって使えなくなる可能性もあるかもしれない。

yumコマンドとrpmコマンド

Linux上にパッケージをインストールするには、yumコマンドを使用する方法とrpmコマンドを使用する方法がある。yumコマンドはrpmコマンドの上位コマンドになっており、内部でrpmコマンドを呼んでいる。

また、yumコマンドは、目的のパッケージをインストールする際に、それに必要となるパッケージ(依存パッケージ)もインターネット上のレポジトリから自動的にダウンロードしてインストールしてくれる。この機能はrpmコマンドにはない。

 

ここまで読むと、Linux上にパッケージをインストールする時はyumコマンド一択ではないかと思ってしまうが、例えば、(セキュリティ上の理由により) インターネットから遮断されているイントラ内のLinuxに CD/DVDからパッケージをインストールする時にrpmコマンドを使用するという使い方があると思う。