ためすう
unix で自作コマンドの設定をする方法
2018-10-08目的
unix で自作コマンドを使えるようにしてみます
やってみる
# vim hello
ファイルを作成します
#!/bin/sh
echo "Hello!"
権限を与えます
# chmod a+x hello
# cp hello /usr/bin/hello
コマンドを実行します
# hello
実行結果
Hello
参考URL
jQuery の map を試す
2018-10-07目的
jQuery の map の挙動を試しました。
やってみる
var list = [
{id: 't1', name: "abc"},
{id: 't2', name: "def"},
{id: 't3', name: "ghi"},
{id: 't4', name: "jkl"},
{id: 't5', name: "mn"},
{id: 't6', name: "xyz"}
];
var t = $.map(list, function(val, i) {
// console.log(i, val);
return val.name.toUpperCase();
});
console.log(t);
// 結果
["ABC", "DEF", "GHI", "JKL", "MN", "XYZ"]
オブジェクトの name を大文字にして配列にします
参考URL
jQuery の grep を試す
2018-10-06目的
jQuery の grep の挙動を試しました。
やってみる
var list = [
{id: 't1', name: "ABC"},
{id: 't2', name: "DEF"},
{id: 't3', name: "GHI"},
{id: 't4', name: "JKL"},
{id: 't5', name: "MN"},
{id: 't6', name: "XYZ"}
];
var t = $.grep(list, function(val, i) {
return i > 3;
});
console.log(t);
// 結果
[
{id: 't5', name: "MN"},
{id: 't6', name: "XYZ"}
];
grep の第 2 引数に渡した関数で、インデックスが 3 より大きい要素を取り出します。
参考URL
memcached でアクセス回数を調べる
2018-09-30目的
Web アプリ経由で memcached を利用している箇所があり、memcached に対して不要なアクセスをしていそうな処理がありました。
実際に memcached へのアクセスがどうなっているのかを調べることになりました。
方法
telnet で接続
$ telnet localhost 11211
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
stats コマンドで確認
stats
STAT pid 2734
STAT uptime 19319
STAT time 1529845762
STAT version 1.4.15
STAT libevent 2.0.21-stable
STAT pointer_size 64
STAT rusage_user 0.000000
STAT rusage_system 0.476000
STAT curr_connections 10
STAT total_connections 72
STAT connection_structures 13
STAT reserved_fds 20
STAT cmd_get 145
STAT cmd_set 40
STAT cmd_flush 0
STAT cmd_touch 0
STAT get_hits 85
STAT get_misses 60
STAT delete_misses 0
STAT delete_hits 0
STAT incr_misses 0
STAT incr_hits 0
STAT decr_misses 0
STAT decr_hits 0
STAT cas_misses 0
STAT cas_hits 0
STAT cas_badval 0
... 省略
END
リクエスト数に関係ありそうな項目を抜き出してみました。
- get_hits: Cumulative number of retrieval reqs
- cmd_get: Number of keys that have been requested and found present
ここでは、get コマンドを発行した回数の cmd_get の増減を調査しました。
stats の結果の各項目について
下記に記載されていました。
確認後、memcached を終了する
quit
Connection closed by foreign host.
参考
Mac のスクリーンショットの保存場所を変更する方法
2018-09-30目的
Mac で撮影したスクリーンショットの保存場所を変更します。
方法
$ defaults write com.apple.screencapture location ~/Pictures/
SystemUIserver について
> SystemUIserverとは、メニューバーの通知アイコンを制御してるプロセス
SystemUIserver を再起動します。
$ killall SystemUIServer ```
参考
PHP でデザインパターン (Template Method)
2018-09-29Template Method パターンとは
スーパークラスで処理の枠組みを定め、サブクラスでその具体的内容を定めるようなデザインパターン
クラスの振る舞いに注目したパターンで、サブクラスで具体的な振る舞いを決定させることを目的としています。
Template Method パターンのメリット
スーパークラスのテンプレートメソッドでアルゴリズムが記述されており、サブクラス側では アルゴリズムを記述する必要がなくなる
親クラス視点で見ると、「抽象メソッドとして定義したメソッドの実装が「保証される」
子クラス視点で見ると、クライアント側のコードを変更することなく、利用する処理を切り替えることができる。
実装例
<?php
abstract class AbstractDisplay
{
private $data;
public function __construct($data)
{
if (!is_array($data)) {
$data = [$data];
}
$this->data = $data;
}
public function getData()
{
return $this->data;
}
/**
* 処理のアルゴリズムがまとまっている
*
*/
public function display()
{
$this->displayHeader();
$this->displayBody();
$this->displayFooter();
}
protected abstract function displayHeader();
protected abstract function displayBody();
protected abstract function displayFooter();
}
class ListDisplay extends AbstractDisplay
{
protected function displayHeader()
{
echo 'ListDisplay.displayHeader()' . "\n";
}
protected function displayBody()
{
echo 'ListDisplay.displayBody()' . "\n";
foreach ($this->getData() as $key => $val) {
echo $val . "\n";
}
}
protected function displayFooter()
{
echo 'ListDisplay.displayFooter()' . "\n";
}
}
class TableDisplay extends AbstractDisplay
{
protected function displayHeader()
{
echo 'TableDisplay.displayHeader()' . "\n";
}
protected function displayBody()
{
echo 'TableDisplay.displayBody()' . "\n";
foreach ($this->getData() as $key => $val) {
echo sprintf("***%s***\n", $val);
}
}
protected function displayFooter()
{
echo 'TableDisplay.displayFooter()' . "\n";
}
}
$data = [
'Design Pattern',
'Gang of Four',
'Template Method Sample1',
'Template Method Sample2',
];
$display1 = new ListDisplay($data);
$display2 = new TableDisplay($data);
$display1->display();
echo "------\n";
$display2->display();
おまけ
リスコフの置換原則(LSP:The Liskov Substituion Principle): 「サブクラスの型はその親クラスの型と置換可能」
ハリウッドの原則(The Hollywood Principle:「Don’t call us. We’ll call you.」「我々を呼び出すな。必要なときは、我々が君を呼び出す」
参考
PHP でデザインパターン (Facade)
2018-09-29Facade の目的
Facade 役は、システムの外側に対してはシンプルなインターフェース( API )を見せます。 また、Facade 役はシステムの内側にある各クラスの役割や依存関係を考えて、正しい順番でクラスを利用します。
Facade のメリット
- サブシステムの構成要素を隠蔽する
- サブシステムとクライアントの結びつきをゆるくする
実装例
<?php
class ArrDatabase
{
private function __construct()
{
}
public static function getProperties()
{
return [
'abc@xxx' => 'abc ABC',
'def@xxx' => 'def DEF',
'xyz@xxx' => 'xyz XYZ',
];
}
}
class HtmlWriter
{
private $writer;
public function __construct($writer)
{
$this->writer = $writer;
}
public function title($title)
{
$this->writer->open();
$this->writer->write("title始まり\n");
$this->writer->write($title . "\n");
$this->writer->write("title終わり\n");
}
public function paragraph($message)
{
$this->writer->write("paragraph始まり\n");
$this->writer->write($message . "\n");
$this->writer->write("paragraph終わり\n");
}
public function close()
{
$this->writer->close();
}
}
/*
* ファイルの書き出す
*
*/
class FileWriter
{
private $filename;
private $file_handler;
public function __construct($filename)
{
$this->filename = $filename;
}
public function open()
{
$this->file_hanlder = fopen($this->filename, 'w');
}
public function write($content)
{
fwrite($this->file_hanlder, $content);
}
public function close()
{
return fclose($this->file_hanlder);
}
}
class PageMaker
{
private function __construct()
{
}
public static function makeWelcomePage($mailaddr, $filename)
{
$mailprop = ArrDatabase::getProperties();
$username = $mailprop[$mailaddr];
$writer = new HtmlWriter(new FileWriter($filename));
$writer->title("Welcome to " . $username . "'s page!");
$writer->paragraph($username . "のページへようこそ");
}
}
PageMaker::makeWelcomePage('xyz@xxx', '/tmp/welcome.html');
参考
PHP でデザインパターン (Factory Method)
2018-09-25Factory Method の目的
インスタンスを生成する工場を Template Method パターンで構成したもの
Factory Methodパターンを利用することで、オブジェクトの利用側はどのインスタンスが生成されるのかを知る必要がなくなります。
Factory Method パターンのメリット
- オブジェクトの生成処理と使用処理を分離できる
- オブジェクトの利用側とオブジェクトのクラスの結びつきを低くする
実装例
<?php
interface Reader
{
public function read();
public function display();
}
class CSVFileReader implements Reader
{
private $filename;
public function __construct($filename)
{
$this->filename = $filename;
}
public function read()
{
echo "CSVファイルの読み込み\n";
}
public function display()
{
echo "CSVの各行を表示\n";
}
}
class XMLFileReader implements Reader
{
private $filename;
public function __construct($filename)
{
$this->filename = $filename;
}
public function read()
{
echo "XMLファイルの読み込み\n";
}
public function display()
{
echo "XMLの各行を表示\n";
}
}
class ReaderFactory
{
public function create($filename)
{
$reader = $this->createReader($filename);
return $reader;
}
private function createReader($filename)
{
if (preg_match('/.+\.csv$/', $filename)) {
return new CSVFileReader($filename);
} elseif (preg_match('/.+\.xml$/', $filename)) {
return new XMLFileReader($filename);
}
throw new Exception('サポートしていない');
}
}
// 呼び出し元
$filename = 'abc.xml';
$factory = new ReaderFactory();
$data = $factory->create($filename);
$data->read();
$data->display();
参考
apache ユーザーが root ユーザーとして処理を実行する方法
2018-09-24目的
Web サーバー (apache) で php を実行すると、
実行ユーザーは apache ユーザーとなります。
処理の中で root 権限が必要な処理がありました。
方法
- abc.py
print(30)
- test.php
$a = exec('sudo -u root /usr/bin/python /var/www/html/abc.py', $d);
というように、root ユーザーでコマンドを実行できるようにします。
今のままではできないので、下記ファイルを編集します。
# vim /etc/sudoers
下記行を追加してください。
apache ALL=(root) NOPASSWD: ALL
これで root ユーザーで実行することができるようになりました。
参考
pip でインストール先を指定する方法
2018-09-24目的
pip でインストールをする時、権限がなくインストールできないことがありました。
なので、インストール先を任意の場所に変更する方法を調べました。
方法
例えば、下記を実行すると
1. インストール先のディレクトリを指定する
pycrypto ライブラリを /tmp ディレクトリにインストールします
$ pip install pycrypto -t /tmp/
2. ~/.local/ へインストールする
また、下記のように指定すると ~/.local/ へインストールすることができます
$ pip install pycrypto --user