Quantcast
Channel: Linux –俺的備忘録 〜なんかいろいろ〜
Viewing all 743 articles
Browse latest View live

scriptコマンドで記録するターミナルログにタイムスタンプを付与する(ワンライナー編)

$
0
0

前にscriptコマンドで取得するターミナルログにタイムスタンプを付与するというスクリプトを書いたことがあるのだが、また必要になって調べてみたところ、そもそもこれワンライナーで書けるなと気づいたので書き直しをした。
具体的には、以下のように記述する。

script -fq >(awk '{print strftime("%F %T ") $0}{fflush() }'>> PATH)

これで、scriptコマンドの一時ファイルも存在させずにタイムスタンプが付与されたターミナルログができあがる。
実際に記録したログは以下。

[root@BS-PUB-CENT7-02 ~]# cat session.log
2017-02-02 11:06:26 スクリプトは 2017年02月02日 11時06分26秒
2017-02-02 11:06:26  に開始しました[root@BS-PUB-CENT7-02 ~]#
2017-02-02 11:06:27 [root@BS-PUB-CENT7-02 ~]#
2017-02-02 11:06:27 [root@BS-PUB-CENT7-02 ~]# ls -al
2017-02-02 11:06:27 合計 56
2017-02-02 11:06:27 dr-xr-x---.  6 root root 4096  2月  2 11:06 .
2017-02-02 11:06:27 dr-xr-xr-x. 17 root root 4096  1月 29 23:47 ..
2017-02-02 11:06:27 -rw-------.  1 root root 4115  2月  2 11:00 .bash_history
2017-02-02 11:06:27 -rw-r--r--.  1 root root   18 12月 29  2013 .bash_logout
2017-02-02 11:06:27 -rw-r--r--.  1 root root  176 12月 29  2013 .bash_profile
2017-02-02 11:06:27 -rw-r--r--.  1 root root  176 12月 29  2013 .bashrc
2017-02-02 11:06:27 drwxr-xr-x.  6 root root   89  1月 30 22:59 .cpan
2017-02-02 11:06:27 -rw-r--r--.  1 root root  100 12月 29  2013 .cshrc
2017-02-02 11:06:27 drwxr-xr-x.  3 root root   18  1月 31 23:28 .gem
2017-02-02 11:06:27 drwxr-----.  3 root root   18  1月 30 22:58 .pki
2017-02-02 11:06:27 -rw-r--r--.  1 root root  129 12月 29  2013 .tcshrc
2017-02-02 11:06:27 -rw-------.  1 root root 4492  2月  1 08:05 .viminfo
2017-02-02 11:06:27 -rw-------.  1 root root  986  1月  2  2016 anaconda-ks.cfg
2017-02-02 11:06:27 drwxr-xr-x. 10 root root 4096  1月 30 22:58 dategrep
2017-02-02 11:06:27 -rw-r--r--.  1 root root  334  2月  2 11:06 session.log
2017-02-02 11:06:28 [root@BS-PUB-CENT7-02 ~]#
2017-02-02 11:06:29 [root@BS-PUB-CENT7-02 ~]# exit
2017-02-02 11:06:29 exit

 

タイムスタンプのフォーマットは、awkのstrftimeのとこで指定しているので、変更したい場合はそこを書き換えてやればよい。
ちなみに、syslogに飛ばす場合は以下のように記述する(ただ、バックスペースなども含めて送信してしまうのであまり良くないかも…?改善の必要あり)。

script -fq >(logger)

 

Mac OS Xの場合だと都度書き込みのオプションが「-f」ではなく「-F」になるので注意。
ちなみに、scriptコマンドで”特定のコマンドの結果をタイムスタンプ付きで記録”する場合だと、Linux/Mac OS X(というかBSD)別で以下のように実行する。

# Linux
script -fq -c "コマンド" >(awk '{print strftime("%F %T ") $0}{fflush() }'>> PATH)

# Mac OS X
script -Fq >(awk '{print strftime("%F %T ") $0}{fflush() }'>> PATH) コマンド("などで囲まない)

 

「シェル芸」に効く!AWK処方箋 「シェル芸」に効く!AWK処方箋

諸事情でパイプが使えないコンソールで同じような処理を行わせる

$
0
0

ターミナルの使用キーボードが違うなどで、パイプが使えない(入力できない)という場合もある。
そんなときはキーボードの種類を切り替えるのがいいのだが、諸事情でそれもできないこともあるだろう。

そんな時は、以下のようにすることでパイプと同じような処理をさせることができる。

コマンド1 | コマンド2 # パイプを使った場合
コマンド2 <(コマンド1)
[root@BS-PUB-CENT7-01 ~]# cat test
AAA 111
BBB 222
AAA 333
BBB 444
CCC 555
[root@BS-PUB-CENT7-01 ~]# grep AAA test | sed 's/111/999/g'
AAA 999
AAA 333
[root@BS-PUB-CENT7-01 ~]# sed 's/111/999/g' <(grep AAA test)
AAA 999
AAA 333

 

入門者のLinux 素朴な疑問を解消しながら学ぶ (ブルーバックス) 入門者のLinux 素朴な疑問を解消しながら学ぶ (ブルーバックス)

Linuxでフルパスからファイル名のみ取り出す方法

$
0
0

LinuxやUNIXで、コンソール上でフルパスからファイル名のみを抽出する場合、以下のような方法がある。

1.basenameコマンドを用いる

基本はこれ。
basenameという、ファイル名のみ(ディレクトリを指定したら最後)を求めるコマンドがあるので、これを利用する。
パイプで渡す場合はxargsを使う必要があるので注意。

basename PATH
[root@BS-PUB-CENT7-02 ~]# ls -1ad /opt/td-agent/*
/opt/td-agent/LICENSE
/opt/td-agent/LICENSES
/opt/td-agent/bin
/opt/td-agent/embedded
/opt/td-agent/etc
/opt/td-agent/usr
/opt/td-agent/version-manifest.json
/opt/td-agent/version-manifest.txt
[root@BS-PUB-CENT7-02 ~]# ls -1ad /opt/td-agent/* | xargs -n1 basename
LICENSE
LICENSES
bin
embedded
etc
usr
version-manifest.json
version-manifest.txt

 

なお、basenameコマンドの場合スペースを含んだPATHを渡す場合はエスケープなり、ダブルクォーテーションなりでくくってやる必要があるので注意。

[root@BS-PUB-CENT7-02 ~]# basename /opt/td-agent/space test
space
[root@BS-PUB-CENT7-02 ~]# basename /opt/td-agent/space\ test
space test
[root@BS-PUB-CENT7-02 ~]# basename "/opt/td-agent/space test"
space test

 

xargsで渡す場合は、-Iと組み合わせてやるといいだろう。

[root@BS-PUB-CENT7-02 ~]# ls -1ad /opt/td-agent/space*
/opt/td-agent/space test
[root@BS-PUB-CENT7-02 ~]# ls -1ad /opt/td-agent/space* | xargs basename
space
[root@BS-PUB-CENT7-02 ~]# ls -1ad /opt/td-agent/space* | xargs -I{} basename "{}"
space test

 

一応、拡張子(.txtなど)を指定することで、その拡張子を排除して出力させることもできる…のだが、ベタ打ちなのであまり使い勝手はよくないかも。

[root@BS-PUB-CENT7-02 ~]# ls -1ad /opt/td-agent/*
/opt/td-agent/LICENSE
/opt/td-agent/LICENSES
/opt/td-agent/bin
/opt/td-agent/embedded
/opt/td-agent/etc
/opt/td-agent/space test
/opt/td-agent/usr
/opt/td-agent/version-manifest.json
/opt/td-agent/version-manifest.txt
[root@BS-PUB-CENT7-02 ~]# ls -1ad /opt/td-agent/* | xargs -I{} basename {} .txt
LICENSE
LICENSES
bin
embedded
etc
space test
usr
version-manifest.json
version-manifest

 

2.awkを用いる

awkでディレクトリ部分を除外する場合は、区切り文字を「/」にしてやり、$NF(最後の列)をprintしてやればよい。

awk -F/ '{print $NF}'
[root@BS-PUB-CENT7-02 ~]# ls -1ad /opt/td-agent/*
/opt/td-agent/LICENSE
/opt/td-agent/LICENSES
/opt/td-agent/bin
/opt/td-agent/embedded
/opt/td-agent/etc
/opt/td-agent/space test
/opt/td-agent/usr
/opt/td-agent/version-manifest.json
/opt/td-agent/version-manifest.txt
[root@BS-PUB-CENT7-02 ~]# ls -1ad /opt/td-agent/* | awk -F/ '{print $NF}'
LICENSE
LICENSES
bin
embedded
etc
space test
usr
version-manifest.json
version-manifest.txt

拡張子も除外する場合は、awk内でgsubを使って置換してやるといいだろう。
記述例は以下。

awk -F/ '{gsub (/\.[^/.]*$/,"",$NF);print $NF}'
[root@BS-PUB-CENT7-02 ~]# ls -1ad /opt/td-agent/*
/opt/td-agent/LICENSE
/opt/td-agent/LICENSES
/opt/td-agent/bin
/opt/td-agent/embedded
/opt/td-agent/etc
/opt/td-agent/space test
/opt/td-agent/usr
/opt/td-agent/version-manifest.json
/opt/td-agent/version-manifest.txt
[root@BS-PUB-CENT7-02 ~]# ls -1ad /opt/td-agent/* | awk -F/ '{gsub (/\.[^/.]*$/,"",$NF);print $NF}'
LICENSE
LICENSES
bin
embedded
etc
space test
usr
version-manifest
version-manifest

 

3.sedを用いる

awkと同様の処理を、sedを用いるパターン。
後方参照をすることで実現する。

sed -E 's/^(\/.*\/)*(.*)/\2/'
sed -E 's/^([\/]?.*\/)*(.*)\..*$/\2/' # 拡張子もけずるパターン
[root@BS-PUB-CENT7-02 ~]# ls -1ad /opt/td-agent/*.*
/opt/td-agent/version-manifest.json
/opt/td-agent/version-manifest.txt
[root@BS-PUB-CENT7-02 ~]# ls -1ad /opt/td-agent/*.* | sed -E 's/^(\/.*\/)*(.*)/\2/'
version-manifest.json
version-manifest.txt
[root@BS-PUB-CENT7-02 ~]# ls -1ad /opt/td-agent/*.* | sed -E 's/^([\/]?.*\/)*(.*)\..*$/\2/'
version-manifest
version-manifest

 

4.bashのパラメータ展開を用いる

一度変数に代入する必要はあるが、bashのパラメータ展開を用いる方法もある。

${VAR##*/}
[root@BS-PUB-CENT7-02 ~]# TEST_PATH=/opt/td-agent/version-manifest.json
[root@BS-PUB-CENT7-02 ~]# echo $TEST_PATH
/opt/td-agent/version-manifest.json
[root@BS-PUB-CENT7-02 ~]# echo ${TEST_PATH##*/}
version-manifest.json

 

拡張子の削除は同時に行えないので、awkやsedと組み合わせるとよいだろう。

 

番外編 ~出力元がfindの場合~

そもそも、変換元のPATHの出力をfindで行っているのであれば、「-printf」でファイル名だけを指定すればよい。

find ./ -printf "%f\n"

 

拡張子削除については、awkやsedを用いるとよいだろう。

 

 

[改訂第3版]シェルスクリプト基本リファレンス ──#!/bin/shで、ここまでできる (WEB+DB PRESS plus) [改訂第3版]シェルスクリプト基本リファレンス ──#!/bin/shで、ここまでできる (WEB+DB PRESS plus)

CentOS 7にRabbitMQをクラスタ構成で構築する

$
0
0

Graylogでログ取得に使うキューイングシステムとしてKafkaをちょこちょこいじってたのだが、ちょっと用途に合ってないことが分かった(暗号化まわり)。
で、ほかに何か使えるのないかなと思って調べてたところ、GraylogはRabbitMQににも対応しているようだ。なので、今回はRabbit MQを2台構成のクラスタで構築をする(ここでは、MasterをBS-PUB-RABBITMQ01、SlaveをBS-PUB-RABBITMQ02で表現する)。OSにはCentOS 7を用いる。
なお、RabbitMQのクラスタ構成には互いを名前解決できる必要があるので注意。

1.RabbitMQのインストール

まず、以下のコマンドをインストールして、RappidMQのインストールをする。

yum install -y epel-release
yum install -y erlang
yum install -y https://www.rabbitmq.com/releases/rabbitmq-server/v3.6.6/rabbitmq-server-3.6.6-1.el7.noarch.rpm

 

これで、RabbitMQのインストールができた。
以下のコマンドでサービスを起動する。

systemctl start rabbitmq-server

 

firewalldで必要なポートを開放する。

firewall-cmd --permanent --add-port=4369/tcp
firewall-cmd --permanent --add-port=5672/tcp
firewall-cmd --permanent --add-port=15672/tcp
firewall-cmd --permanent --add-port=25672/tcp
firewall-cmd --reload

 

2.クラスタの構成

次に、RabbitMQをクラスタ構成にする。
RabbitMQでクラスタ構成にするには、各ノードの「/var/lib/rabbitmq/.erlang.cookie」の内容が一致している必要がある。
とりあえず、Master側の内容をSlaveにコピーしてやればいいだろう(なお、catで見るとわかるのだが改行は含めないので注意。エディタで編集するよりは、以下のようにコマンドで書き換えてやるほうがいいだろう)。
Slave側で以下のコマンドを実行する(cookieの内容を書き換えてからサービス起動しないと後の行程でこける)。

systemctl stop rabbitmq-server
printf MasterのCookieの内容 > /var/lib/rabbitmq/.erlang.cookie
systemctl start rabbitmq-server
[root@BS-PUB-RABBITMQ02 ~]# systemctl stop rabbitmq-server
[root@BS-PUB-RABBITMQ02 ~]# printf ZGZAAPNSMLNKMGCQMRXO > /var/lib/rabbitmq/.erlang.cookie
[root@BS-PUB-RABBITMQ02 ~]# systemctl start rabbitmq-server

Master/SlaveでCookieの内容をそろえた状態でサービス起動させたら、Slave側で以下のコマンドを実行する。

rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster --ram rabbit@Master
rabbitmqctl start_app
[root@BS-PUB-RABBITMQ02 ~]# rabbitmqctl stop_app
Stopping node 'rabbit@BS-PUB-RABBITMQ02' ...
[root@BS-PUB-RABBITMQ02 ~]# rabbitmqctl reset
Resetting node 'rabbit@BS-PUB-RABBITMQ02' ...
[root@BS-PUB-RABBITMQ02 ~]# rabbitmqctl join_cluster --ram rabbit@BS-PUB-RABBITMQ01
Clustering node 'rabbit@BS-PUB-RABBITMQ02' with 'rabbit@BS-PUB-RABBITMQ01' ...
[root@BS-PUB-RABBITMQ02 ~]# rabbitmqctl start_app
Starting node 'rabbit@BS-PUB-RABBITMQ02' ...

 

これでクラスタ化ができた。
以下のコマンドで、RabbitMQクラスタのステータス確認をしてみよう。

rabbitmqctl cluster_status
[root@BS-PUB-RABBITMQ02 ~]# rabbitmqctl cluster_status
Cluster status of node 'rabbit@BS-PUB-RABBITMQ02' ...
[{nodes,[{disc,['rabbit@BS-PUB-RABBITMQ01']},
         {ram,['rabbit@BS-PUB-RABBITMQ02']}]},
 {running_nodes,['rabbit@BS-PUB-RABBITMQ01','rabbit@BS-PUB-RABBITMQ02']},
 {cluster_name,<<"rabbit@BS-PUB-RABBITMQ02.BLACKNON.LOCAL">>},
 {partitions,[]},
 {alarms,[{'rabbit@BS-PUB-RABBITMQ01',[]},{'rabbit@BS-PUB-RABBITMQ02',[]}]}]

 

3.キューのミラーリング

次に、各クラスタでキューのミラーリング設定(Mirrored Queue)を行う。
ミラーリング設定ではポリシーの設定が必要のようだ。基本は「all(全ノードでキューの同期をする)」でいいだろう。

  • all … 全ノードでキューの同期を行う
  • exactly … 指定した数のノードでキューの同期を行う
  • nodes … 指定したノードでキューの同期を行う

 

以下のコマンドをMasterで実行し、ミラーリングの設定を行う。

rabbitmqctl set_policy "ポリシー名" "キュー名" '{"ha-mode":"all"}'
[root@BS-PUB-RABBITMQ01 ~]# rabbitmqctl set_policy "mirror-test" "test.queue" '{"ha-mode":"all"}'
Setting policy "mirror-test" for pattern "test.queue" to "{\"ha-mode\":\"all\"}" with priority "0" ...

 

コマンド実行後、実際にキューを作成してミラーリングされることを確認しよう。
ただ、デフォルトでインストールされてるコマンドだけだとキューを作成できないので、以下のコマンドを実行して「rabbitmqadmin」をインストールしよう。
(インストールについては、Master/Slaveどちらでも行っておこう)

rabbitmq-plugins enable rabbitmq_management
wget http://127.0.0.1:15672/cli/rabbitmqadmin -O /usr/lib/rabbitmq/bin/rabbitmqadmin
chmod +x /usr/lib/rabbitmq/bin/rabbitmqadmin
ln -s /usr/lib/rabbitmq/bin/rabbitmqadmin /usr/sbin/rabbitmqadmin

 

「rabbitmqadmin」をインストール後、以下のコマンドを実行してテスト用のキューを作成する。

rabbitmqadmin list queues name slave_nodes synchronised_slave_nodes
rabbitmqadmin declare queue name=test.queue
rabbitmqadmin list queues name slave_nodes synchronised_slave_nodes
[root@BS-PUB-RABBITMQ01 ~]# rabbitmqadmin list queues name slave_nodes synchronised_slave_nodes
No items
[root@BS-PUB-RABBITMQ01 ~]# rabbitmqadmin declare queue name=test.queue
queue declared
[root@BS-PUB-RABBITMQ01 ~]# rabbitmqadmin list queues name slave_nodes synchronised_slave_nodes
+------------+------------------------------+------------------------------+
|    name    |         slave_nodes          |   synchronised_slave_nodes   |
+------------+------------------------------+------------------------------+
| test.queue | ["rabbit@BS-PUB-RABBITMQ02"] | ["rabbit@BS-PUB-RABBITMQ02"] |
+------------+------------------------------+------------------------------+

 

これで、無事RabbitMQをクラスタ構成で構築できた。

 

4.管理画面へのログイン・設定

さて、とりあえずこれでクラスタの構築は終わったのだが、ルーティングキーの設定もできてないので、このままだと利用できない。
ルーティングキー設定などは管理画面から行えるので、管理画面にログインするためのユーザを作成する。

rabbitmqctl add_user ユーザ名 パスワード
rabbitmqctl set_permissions -p / ユーザ名 ".*" ".*" ".*"
rabbitmqctl set_user_tags ユーザ名 administrator
[root@BS-PUB-RABBITMQ01 ~]# rabbitmqctl add_user test P@ssw0rd
Creating user "test" ...
[root@BS-PUB-RABBITMQ01 ~]# rabbitmqctl set_permissions -p / test ".*" ".*" ".*"
Setting permissions for user "test" in vhost "/" ...
[root@BS-PUB-RABBITMQ01 ~]# rabbitmqctl list_users
Listing users ...
test    []
guest   [administrator]
[root@BS-PUB-RABBITMQ01 ~]# rabbitmqctl set_user_tags test administrator
Setting tags for user "test" to [administrator] ...
[root@BS-PUB-RABBITMQ01 ~]# rabbitmqctl list_users
Listing users ...
test    [administrator]
guest   [administrator]

 

ユーザができたら、あとはブラウザから「http://サーバのIPアドレスorホスト名:15672」へ接続する。

 

ログイン後は、「Exchanges」タブもしくは「Queues」タブから対象のQueueを選択し、Routing Keyの設定をしてやるとよいだろう。

 

【参考】

 

Splunkではじめるビッグデータ分析 基本操作からTwitterのログ分析まで Splunkではじめるビッグデータ分析 基本操作からTwitterのログ分析まで

Golangの勉強でsshのラッパーコマンド『lssh』というのを作ってみた

$
0
0

最近ちょこちょこGOを勉強するようにしてたのだが、せっかくなので何か作ってみようと考えた。
で、なんかないかなと考えたところ、結構前にPythonでsshのラッパー書いてたのを思い出した。今回はそれをGolangで書き直してみた。sshのラッパーなので、基本Linux/Mac OS Xでしか動かない(Windowsは対象外)になってる。

 https://github.com/blacknon/lssh

 

作り直しなので前作ったPythonのラッパーと基本は変更せず、「~/.lssh.conf」というtomlファイルにログイン情報を記述してコマンドを実行するだけにした。
(オプションとかちゃんと作りたいけど、まだ出来てない。設定ファイルくらいは「-f」オプションで指定させられるようにしたい。)

コマンドを実行すると以下のようにサーバ情報をリストにしてくれるので、ログインしたいサーバをカーソルキーで選択してEnterかスペースでログインさせる。
一応、pecoっぽい簡易的なフィルター機能はつけたので、サーバ数が多いときはそれで台数を絞る(全列を対象にフィルターされる)。

設定ファイルでlogを有効にすることで、(scriptコマンドではあるけど)TeraTermのログっぽいターミナルログを記録する。
フォーマットは指定できないけど、一応タイムスタンプを付与するようにしている。

 

「/etc/passwd」やsshdのauthorized_keysと組み合わせることで、ssh接続と同時に立ち上がるようにすることで踏み台としても利用できるようになっている。
(なお、SELinuxが有効になっている場合だと/etc/passwdに記述しての実行はうまくいかないかも…)

 

まだエラー処理などが不十分だったりオプションついてなかったりするので、ちょこちょこ更新してこうと思う。

 

みんなのGo言語[現場で使える実践テクニック] みんなのGo言語[現場で使える実践テクニック]

fluentdでRabbitMQにログを送信する

$
0
0

今回は、前回作成したRabbitMQクラスタにfluentdでログを送信する。

1.RabbitMQ側の設定

まず、事前にRabbitMQ側でvHostsなどの作成をしておこう。
ユーザは新規に「logger」ユーザを作成する。

■vHostsの作成(「logs」)

rabbitmqadmin declare vhost name=/logs
rabbitmqctl set_permissions -p /logs guest ".*" ".*" ".*"
[root@BS-PUB-RABBITMQ01 ~]# rabbitmqadmin declare vhost name=/logs
vhost declared
[root@BS-PUB-RABBITMQ01 ~]# rabbitmqadmin list vhosts
+-------+----------+
| name  | messages |
+-------+----------+
| /     | 0        |
| /logs |          |
+-------+----------+
[root@BS-PUB-RABBITMQ01 ~]# rabbitmqctl set_permissions -p /logs guest ".*" ".*" ".*"
Setting permissions for user "guest" in vhost "/logs" ...

 

■ユーザの作成

rabbitmqctl add_user logger パスワード
rabbitmqctl set_permissions -p /logs logger ".*" ".*" ".*"
rabbitmqctl set_permissions -p / logger ".*" ".*" ".*"
rabbitmqctl set_user_tags logger administrator
[root@BS-PUB-RABBITMQ01 ~]# rabbitmqctl add_user logger password
Creating user "logger" ...
[root@BS-PUB-RABBITMQ01 ~]# rabbitmqctl set_permissions -p /logs logger ".*" ".*" ".*"
Setting permissions for user "logger" in vhost "/logs" ...
[root@BS-PUB-RABBITMQ01 ~]# rabbitmqctl set_permissions -p / logger ".*" ".*" ".*"
Setting permissions for user "logger" in vhost "/" ...
[root@BS-PUB-RABBITMQ01 ~]# rabbitmqctl set_user_tags logger administrator
Setting tags for user "logger" to [administrator] ...

 

■queue/exchangeの作成(ミラーリング設定あり)

rabbitmqadmin declare queue name=syslog.queue --vhost=/logs # queueの作成
rabbitmqadmin declare exchange name=syslog.topic type=topic --vhost=/logs #exchangeの作成
rabbitmqctl list_queues -p /logs
rabbitmqctl set_policy "mirror-test" "syslog.queue" '{"ha-mode":"all"}' -p /logs
rabbitmqadmin list queues name slave_nodes synchronised_slave_nodes
[root@BS-PUB-RABBITMQ01 ~]# rabbitmqadmin declare queue name=syslog.queue --vhost=/logs
queue declared
[root@BS-PUB-RABBITMQ01 ~]# rabbitmqadmin declare exchange name=syslog.topic type=topic --vhost=/logs
exchange declared
[root@BS-PUB-RABBITMQ01 ~]# rabbitmqctl list_queues -p /logs
Listing queues ...
syslog.queue    0
[root@BS-PUB-RABBITMQ01 ~]# rabbitmqctl set_policy "mirror-test" "syslog.queue" '{"ha-mode":"all"}' -p /logs
Setting policy "mirror-test" for pattern "syslog.queue" to "{\"ha-mode\":\"all\"}" with priority "0" ...
[root@BS-PUB-RABBITMQ01 ~]# rabbitmqadmin list queues name slave_nodes synchronised_slave_nodes
+--------------+------------------------------+------------------------------+
|     name     |         slave_nodes          |   synchronised_slave_nodes   |
+--------------+------------------------------+------------------------------+
| syslog.queue | ["rabbit@BS-PUB-RABBITMQ02"] | ["rabbit@BS-PUB-RABBITMQ02"] |
| test.queue   | ["rabbit@BS-PUB-RABBITMQ02"] | ["rabbit@BS-PUB-RABBITMQ02"] |
+--------------+------------------------------+------------------------------+

 

■Routing Keyの設定

fluentdからRabbitMQにログを転送するにあたり、Routing Keyの設定が必要になる。
今回使用するプラグインではfluentdのタグがRouting Keyとして使用される。とりあえず「syslog」で送信されるので、それをRabbitMQのWeb管理画面から設定する。
Exchangesタブから、先ほど作成したExchangesを開いて、そこからRouting Keyを設定しておく。

 

 

ひとまず、これでRabbitMQ側の設定は完了。

2.fluentd側の設定

fluentdからRabbitMQにログを送信する場合、別途プラグインが必要になるので、以下のコマンドでインストールする。

/opt/td-agent/embedded/bin/gem install fluent-plugin-amqp2

 

プラグインをインストール後、設定ファイルで以下のように定義してやればよい。

●/etc/td-agent/td-agent.conf

<match *.**>
  type amqp

  # Set broker host and port
  host ホスト名(同居させるならlocalhost)
  port 5672

  # Set user and password for authentication
  user logger(同居させるならguest)
  password password(同居させるならguest)

  # Configure amqp entities vhost, exchange id and type
  vhost /logs
  exchange Exchange名(今回の場合syslog.topic)
  exchange_type topic
  exchange_durable true # optionally set exchange durability - default is true.
  payload_only false # optional - default is false. if true, only the payload will be sent. if false, data format is { "key" => tag, "timestamp" => time, "payload" => record }.
  content_type application/octet-stream # optional - default is application/octet-stream. some amqp consumers will expect application/json.
</match>

 

設定ファイルを編集したら、サービスを再起動しよう。

systemctl restart td-agent

 

サービス再起動後、適当にログを送ってみると、無事syslog.queueにログが転送された。

rabbitmqadmin list queues
[root@BS-PUB-RABBITMQ01 ~]# rabbitmqadmin list queues
+--------------+----------+
|     name     | messages |
+--------------+----------+
| syslog.queue | 557      |
| test.queue   | 0        |
+--------------+----------+

 

RabbitMQのWeb管理画面からもキューの中身を確認することができる。

 

サーバー管理者のためのイベントログ運用の基本 サーバー管理者のためのイベントログ運用の基本

第27回シェル芸勉強会に参加してきました(復習)

$
0
0

第27回シェル芸勉強会に行ってきたので、その復習。
今回はsedコマンドの機能について学ぼうということで、sed縛りとなっていた。sedコマンドというと基本は置換にしか使わないが、今回はラベルだったりパターンスペース・ホールドスペースを使ったりする。正直、今回は全然ついていけてなかった…(´・ω・`)。ラベルやパターンスペース・ホールドスペースの存在は知っていたのだが、それらをうまく利用できなかったと思う。sedは奥が深い…。
問題・模範解答はこちら。使用するファイルは1個だけなのだが、以下のコマンドでダウンロードしておこう。

git clone https://github.com/ryuichiueda/ShellGeiData.git

Q1.

Q1は、echoで取得した文字列の偶数番目のみ大文字にするというもの。
後方参照を使って偶数のみを大文字にする。

echo abcdefghijklmn | sed 's/\(.\)\(.\)/\1\u\2/g'
echo abcdefghijklmn | sed -r 's/(.)(.)/\1\u\2/g' # -rで拡張正規表現対応になる
blacknon@BS-PUB-UBUNTU-01:~$ echo abcdefghijklmn | sed 's/\(.\)\(.\)/\1\u\2/g'
aBcDeFgHiJkLmN
blacknon@BS-PUB-UBUNTU-01:~$ echo abcdefghijklmn | sed -r 's/(.)(.)/\1\u\2/g'
aBcDeFgHiJkLmN

Q2.

seqで1~100までを出力し、sedでFizzBuzz(数字が3の倍数ならFizz、5の倍数ならBuzz、3×5=15の倍数ならFizzBuzzと置換する数字遊び)をしてみる、という問題。
なんの気なしに「sed FizzBuzz」で検索してみたところ、ebanさんの過去のブログが普通にヒット。考える前に理想的な解答見ちゃったような気持ちになったが、気を取り直して解答。sで置換を行うパターンとcで行ごと置き換えるパターン、2通りが考えられた。

seq 1 100 | sed -e '3~3s/^.*$/Fizz/' -e '5~5s/^.*$/Buzz/g' -e '15~15s/^.*$/FizzBuzz/g'
seq 1 100|sed -e '15~15cFizzBuzz' -e '5~5cBuzz' -e '3~3cFizz' # 置き換え版

 

sedでは、実行コマンド(sとかcとか)の前に’first~step’を記述することで、指定された行ごとに処理が行われるようにできる。
例えば「15~15」だと15行ごとに処理が行われるので、それを利用してやるとFizzBuzzが行える。

Q3.

seqで1~10まで出力して、3行目を7行目に代入する、という問題。
ここでホールドスペース・パターンスペースの話が出てくる。これについては、@gin_135さんの記述したこちらが詳しいと思う。
(実は見たときにホールドスペース・パターンスペースなしで解けないかと思ったのだが、どうあがいても使ったほうが短くかける)

seq 1 10 | sed '3h;3d;7G'
seq 1 10 | sed '3{h;d};7G' # 「3h;3d;」もこう記述して省略できるらしい…
blacknon@BS-PUB-UBUNTU-01:~$ seq 1 10 | sed '3h;3d;7G'
1
2
4
5
6
7
3
8
9
10
blacknon@BS-PUB-UBUNTU-01:~$ seq 1 10 | sed '3{h;d};7G' # 「3h;3d;」もこう記述して省略できるらしい…
1
2
4
5
6
7
3
8
9
10

 

それぞれの記述だが、以下のような意味がある。

  • 3h … 3行目をパターンスペース(あまり意識しないが、いつも使ってるとこ)からホールドスペースにコピーする
  • 3d … 3行目をパターンスペースから削除する
  • 7G … ホールドスペースに入ってる内容を7行目に追記する(7gだと7行目を入れ替える)

 

イメージ的には、クリップボードに近いだろうか。

Q4.

C++のコードについて、関数の位置を入れ替えてコンパイル、実行するという問題(たまにあるな、このコンパイルするって問題)。
関数自体の位置を入れ替える必要があるので、複数行に対して位置の差し替えをする必要がある。模範解答より。

cat aho.cc | sed '/ main(/,/^}/H;/ main(/,/^}/d;$G'
cat aho.cc | sed '/ main(/,/^}/H;/ main(/,/^}/d;$G' | g++ -x c++ - && ./a.out # そのままコンパイルして実行するパターン
blacknon@BS-PUB-UBUNTU-01:~/ShellGeiData/vol.27$ cat aho.cc
#include
using namespace std;

int main(int argc, char const* argv[])
{
        aho();
        return 0;
}

void aho(void)
{
        cout << "aho" << endl;
}
blacknon@BS-PUB-UBUNTU-01:~/ShellGeiData/vol.27$ cat aho.cc | sed '/ main(/,/^}/H;/ main(/,/^}/d;$G'
#include
using namespace std;


void aho(void)
{
        cout << "aho" << endl;
}

int main(int argc, char const* argv[])
{
        aho();
        return 0;
}

 

で、「なにやってるのコレ?」っていうのが、↑の状態だと正直よくわからないので分解。
記号だらけなのでぱっと見だと分からないのだが、分解してしまえば結構単純だ。

cat aho.cc | \
sed '/main(/,/^}/H; # sedでは「/開始位置/,/終了位置/」 で、対象範囲を指定できるので、それを使って「main(」~「^}」までをホールドスペースにコピー(^で行頭を意味する)
     /main(/,/^}/d; # 「main(」~「^}」までを削除
     $G' # $(最終行)にホールドスペースの内容を追記

Q5.

「seq 1 10 |」から始めて、奇数行と偶数行を入れ替えるという問題。
ここでもパターンスペース・ホールドスペースが用いられる。

seq 1 10 | sed '1~2{h;d};G'
blacknon@BS-PUB-UBUNTU-01:~/ShellGeiData/vol.27$ seq 1 10 | sed '1~2{h;d};G'
2
1
4
3
6
5
8
7
10
9

Q6.

「echo 1」からはじめて、行の文字数が10になるまで1を増加させていくという内容。
ラベルを用いるのだが、よくコードゴルフだと”a”とかで一文字になってる(一応以下でも”A”というラベルを用いている)。

echo 1 | sed -r ':A;p;s/./&&/;/.{10}/!b A'
blacknon@BS-PUB-UBUNTU-01:~/ShellGeiData/vol.27$ echo 1 | sed -r ':A;p;s/./&&/;/.{10}/!b A'
1
11
111
1111
11111
111111
1111111
11111111
111111111
1111111111

 

分解した内容は以下。

echo 1 | \
sed -r '# Aラベル開始(宣言)
        :A;
        p;
        s/./&&/; # 条件に一致した文字を増やす(1個のみ)
        # Aラベルの処理終了
        /.{10}/!b A' # 文字数が10個ではない場合、Aラベルに戻る

Q7.

aというファイルを作って、それをコピーしてa1~a10というファイルを作成するという問題。
ただし、

  • 使うコマンドはseq、cp、sedだけ
  • ワンライナー中で数字を使わない

という縛りあり(両立しなくてもいいらしい)。
で、ここでかなり刺激があった解答が以下。


上記回答には、個人的な学びポイントが色々と組み込まれていた。

aというファイルに関しては、/dev/nullからコピーして生成してやればcpコマンドしか使わない。

cp /dev/null ./a &&seq inf | sed '/../q' | sed 's/.*/cp a a&/e'
blacknon@BS-PUB-UBUNTU-01:/tmp/test$ ls
blacknon@BS-PUB-UBUNTU-01:/tmp/test$ cp /dev/null ./a &&seq inf | sed '/../q' | sed 's/.*/cp a a&/e'










blacknon@BS-PUB-UBUNTU-01:/tmp/test$ ls
a  a1  a10  a2  a3  a4  a5  a6  a7  a8  a9

Q8.

Q6の内容について、さらに今度は逆順の出力を得るという問題(今度は10個じゃなくて5個だけど)。
tacが使えると楽なのだが、実はsedだけでtacのような処理も行えるらしい。なので、それを使ってやるとよいようだ。

echo 1 | sed -r ':A;p;s/./&&/;/.{5}/!b A' | sed 'p;1!G;h;$!d'
blacknon@BS-PUB-UBUNTU-01:~$ echo 1 | sed -r ':A;p;s/./&&/;/.{5}/!b A' | sed 'p;1!G;h;$!d'
1
11
111
1111
11111
11111
1111
111
11
1

 

今回は全体的に難しい…というより、sedのパターンスペース・ホールドスペースとラベルを理解しているかどうかで明暗が分かれた気がする。
普段使いだと触ってなかったのだが、今後はこの辺の機能も触っておこうかな。

[改訂第3版]シェルスクリプト基本リファレンス ──#!/bin/shで、ここまでできる (WEB+DB PRESS plus) [改訂第3版]シェルスクリプト基本リファレンス ──#!/bin/shで、ここまでできる (WEB+DB PRESS plus)

Linuxコンソール上でXX点台の件数を集計する

$
0
0

コンソール上で、awkを使ってテストの点数などを10点台が何件、30点台が何件といった集計を行ってみる。
ある程度汎用性のあるように記述すると、以下のようにすることで〇桁(以下の例では2桁)での件数集計を行う。

yes 'n=100;echo $(( (RANDOM % ( $n + 1 )) + 0 ))' | bash | head -1000 > test.txt # 1-100までのランダムな数字を1000件出力
awk '{sub(/.$/,0,$NF);print $NF}' test.txt | sort -n | uniq -c
blacknon@BS-PUB-UBUNTU-01:~$ yes 'n=100;echo $(( (RANDOM % ( $n + 1 )) + 0 ))' | bash | head -1000 > test.txt
blacknon@BS-PUB-UBUNTU-01:~$ awk '{sub(/.$/,0,$NF);print $NF}' test.txt | sort -n | uniq -c
     98 0
     90 10
     86 20
    119 30
    100 40
    100 50
     75 60
     97 70
    111 80
    112 90
     12 100

1-800までの数字に対して、100点台・200点といった風に集計する場合は、桁数の問題があるので以下のように記述するとよいだろう。

yes 'n=800;echo $(( (RANDOM % ( $n + 1 )) + 0 ))' | bash | head -10000 > test.txt # 1-800までのランダムな数字を10000件出力
awk '{sub(/^.$/,0,$NF);sub(/..$/,0,$NF);printf("%d\n",($NF*10))}' test.txt | sort -n | uniq -cz
blacknon@BS-PUB-UBUNTU-01:~$ yes 'n=800;echo $(( (RANDOM % ( $n + 1 )) + 0 ))' | bash | head -10000 > test.txt # 1-800までのランダムな数字を10000件出力
blacknon@BS-PUB-UBUNTU-01:~$ awk '{sub(/^.$/,0,$NF);sub(/..$/,0,$NF);printf("%d\n",($NF*10))}' test.txt | sort -n | uniq -c
   1220 0
   1236 100
   1263 200
   1275 300
   1250 400
   1286 500
   1258 600
   1206 700
      6 800

 

「シェル芸」に効く!AWK処方箋 「シェル芸」に効く!AWK処方箋

コンソール上で単語の文字組み合わせパターンすべてを取得する

$
0
0

ふと、コンソール上で特定の単語の文字組み合わせを取得するにはどうすればよいのかなと思ったので、ちょっと調べてみた。
ブレース展開を増殖させる方法でどうにか…と思ったけど、無駄に長くなったうえに、文字すべての組み合わせになってしまう。これをどうにかする方法は見つけることができなかった…。

TEST=$(echo test) && eval echo  $(eval echo $(echo $TEST | xargs -I@ sh -c 'echo \"{$(echo @ | sed "s/./&,/g;s/.$//g")}\"{$(echo @ | sed "s/./,/g;s/.$//g")}') | tr -d ' ' ) | tr ' ' '\n' | sort | uniq
blacknon@BS-PUB-UBUNTU-01:~$ TEST=$(echo test) && eval echo  $(eval echo $(echo $TEST | xargs -I@ sh -c 'echo \"{$(echo @ | sed "s/./&,/g;s/.$//g")}\"{$(echo @ | sed "s/./,/g;s/.$//g")}') | tr -d ' ' ) | tr ' ' '\n' | sort | uniq | wc -l
81

 

1.crunchコマンドを用いる

ペネトレーションテストに用いる辞書ファイルの生成ツール。
たぶんこれが一番楽。使用する文字列を指定する前に「-p」でpermutationフラグを立てることで、文字列を入れ替えたもののみ生成してくれる。

インストール方法は以下。ダウンロードのリンクはこちらから最新のものを確認するとよいだろう。
なお、Debian/Ubuntu系ならaptで、OS Xであればbrewでインストールできる。

wget https://downloads.sourceforge.net/project/crunch-wordlist/crunch-wordlist/crunch-3.6.tgz
tar xzvf crunch-3.6.tgz
cd crunch-3.6
make && make install

 

●その他

sudo apt install -y crunch # Debian/Ubuntu系の場合
brew install crunch # OS Xの場合

 

実行方法は以下。

crunch 0 0 -p Strings

2.Rubyを用いる方法

Rubyを使うと結構簡単に書けるようだ。
crunchが入れられない環境でも、Rubyなら使えることが多いだろう。

echo Keyword | ruby -ne '$_.chomp.chars.to_a.permutation{|x| puts x.join}'

 

3.Pythonを用いる場合

一応、Pythonでも同様の処理が可能だ。
Pythonであればバンドルされていることも多いので、Rubyも入れられないならこちらを使うとよいだろう。

echo test | python -c "import sys;from itertools import permutations as p; print('\n'.join([''.join(item) for item in p(sys.stdin.read()[:-1])]))"

 

Linuxカーネル「ソースコード」を読み解く (I・O BOOKS) Linuxカーネル「ソースコード」を読み解く (I・O BOOKS)

Emacsで標準入力を受け付ける

$
0
0

シェル芸界隈でVimシェル芸なるVimをワンライナーで使う代物が流行ってたので、そろそろEmacsで解いてくる猛者が出てくるかなーとか考えていた。
で、なんか標準入力受け付けられないという話だったので調べてみたところ、「–insert」で/dev/stdinを指定すれば標準入力を受け付けられるらしい。

echo abcd | emacs -Q --batch --insert /dev/stdin --eval='(princ (replace-regexp-in-string "a" "1" (buffer-string)))'

blacknon@BS-PUB-UBUNTU-01:~$ echo abcd | emacs -Q --batch --insert /dev/stdin --eval='(princ (replace-regexp-in-string "a" "1" (buffer-string)))'
1bcd

 

さらに、@kuwashimaさんがEmacsでシェル芸の問題を解いてみてくれた。


はー…(゚д゚ )。
さすがに、標準入力の読み込み時点でVimシェル芸ほどの短さでは書けないようだが、出来ないことは無いんだなー…とか考えていたところ、数か月前に先駆者がいたようだ。


世の中は広い。

 

Emacs実践入門 ~思考を直感的にコード化し、開発を加速する (WEB+DB PRESS plus) Emacs実践入門 ~思考を直感的にコード化し、開発を加速する (WEB+DB PRESS plus)

コンソール上でrenameコマンドが無い環境でファイル名を一括置換する

$
0
0

ターミナル上で一括でファイルのリネームをする場合によく利用されるrenameコマンドだが、もしそれがない場合はどうやって一括置換すれば楽かなと思って調べみた。
で、以下のようにコマンドを実行すれば一括で置換ができる。
(とりあえず、カレントディレクトリでa~のファイルを対象にしている)

ls a* | xargs -n1 | sed 'p;s/\.txt/\.faq.txt/g' | xargs -n 2 mv

blacknon@BS-PUB-UBUNTU-01:~/test2$ ls -al
合計 8
drwxrwxr-x  2 blacknon blacknon 4096  2月 16 22:13 .
drwxr-xr-x 11 blacknon blacknon 4096  2月 16 22:12 ..
-rw-rw-r--  1 blacknon blacknon    0  2月 16 22:13 a_01.txt
-rw-rw-r--  1 blacknon blacknon    0  2月 16 22:13 a_02.txt
-rw-rw-r--  1 blacknon blacknon    0  2月 16 22:13 a_03.txt
-rw-rw-r--  1 blacknon blacknon    0  2月 16 22:13 a_04.txt
-rw-rw-r--  1 blacknon blacknon    0  2月 16 22:13 a_05.txt
-rw-rw-r--  1 blacknon blacknon    0  2月 16 22:13 a_06.txt
-rw-rw-r--  1 blacknon blacknon    0  2月 16 22:13 a_07.txt
-rw-rw-r--  1 blacknon blacknon    0  2月 16 22:13 a_08.txt
-rw-rw-r--  1 blacknon blacknon    0  2月 16 22:13 a_09.txt
-rw-rw-r--  1 blacknon blacknon    0  2月 16 22:13 a_10.txt
blacknon@BS-PUB-UBUNTU-01:~/test2$ ls a* | xargs -n1 | sed 'p;s/\.txt/\.faq.txt/g' | xargs -n 2 mv
blacknon@BS-PUB-UBUNTU-01:~/test2$ ls -al
合計 8
drwxrwxr-x  2 blacknon blacknon 4096  2月 16 22:13 .
drwxr-xr-x 11 blacknon blacknon 4096  2月 16 22:12 ..
-rw-rw-r--  1 blacknon blacknon    0  2月 16 22:13 a_01.faq.txt
-rw-rw-r--  1 blacknon blacknon    0  2月 16 22:13 a_02.faq.txt
-rw-rw-r--  1 blacknon blacknon    0  2月 16 22:13 a_03.faq.txt
-rw-rw-r--  1 blacknon blacknon    0  2月 16 22:13 a_04.faq.txt
-rw-rw-r--  1 blacknon blacknon    0  2月 16 22:13 a_05.faq.txt
-rw-rw-r--  1 blacknon blacknon    0  2月 16 22:13 a_06.faq.txt
-rw-rw-r--  1 blacknon blacknon    0  2月 16 22:13 a_07.faq.txt
-rw-rw-r--  1 blacknon blacknon    0  2月 16 22:13 a_08.faq.txt
-rw-rw-r--  1 blacknon blacknon    0  2月 16 22:13 a_09.faq.txt
-rw-rw-r--  1 blacknon blacknon    0  2月 16 22:13 a_10.faq.txt

 

renameコマンドがあるなら素直にそっち使ったほうがいいと思うが、まぁこんなやり方もあるということで。

 

[改訂新版]プロのためのLinuxシステム構築・運用技術 (Software Design plus) [改訂新版]プロのためのLinuxシステム構築・運用技術 (Software Design plus)

sshログイン前にコマンドを実行させる

$
0
0

sshdで、ログイン前に特定のコマンドを実行させたい場合がある(例:svnなどでsshトンネルでのログインをする際に$SSH_CLIENTをどっかのファイルに書き出す場合など)。
こういった場合には、「/etc/ssh/sshrc」もしくは「~/.ssh/rc」に処理内容を記述することで、ログイン前にその内容を実行させることができる。実行する処理はシェルスクリプトと同じ書き方なので、まぁ特に問題はないだろう。

なお、実行されるのはどちらか片方だけ(ファイルが両方ある場合、「~/.ssh/rc」が優先される)なので注意。

 

OpenSSH[実践]入門 (Software Design plus) OpenSSH[実践]入門 (Software Design plus)

fish shellで$(コマンド)と同じような差し込みをする

$
0
0

bashやzshでは、コマンドの結果を差し込みする場合、以下のように任意の箇所に「$(コマンド)」を記述してコマンドを実行することで、(サブシェル展開にはなるのだが)コマンドの実行結果を差し込む。
結構よく利用される方法だ。

コマンド ...$(コマンド)...
blacknon@BS-PUB-UBUNTU-01:~$ echo $0
-bash
blacknon@BS-PUB-UBUNTU-01:~$ echo $(date +%Y%m%d)_test
20170216_test

で、fishでこれと同じ記述をした場合、残念ながら動作しない。
fishで同様の処理を行う場合は、以下のように「$」を付与せずただカッコ()で閉じるだけでいいようだ。

コマンド ...(コマンド)
blacknon@BS-PUB-UBUNTU-01 ~> echo $FISH_VERSION
2.2.0
blacknon@BS-PUB-UBUNTU-01 ~> echo (date +%Y%m%d)_test
20170216_test

 

zshの本 (エッセンシャルソフトウェアガイドブック) zshの本 (エッセンシャルソフトウェアガイドブック)

fish shellでbashなどの「command && ok || ng」と同じ処理をさせる

$
0
0

bashやzshだと、以下のようにコマンドを実行することで、そのコマンドの実行結果に応じた処理を指定することができる。

コマンド && コマンドが正常終了の場合の処理 || コマンドが正常終了出ない場合の処理
blacknon@BS-PUB-DEVELOP:~$ ls test*
test.txt  test1.txt
blacknon@BS-PUB-DEVELOP:~$ ls test.txt && echo OK || echo NG
test.txt
OK
blacknon@BS-PUB-DEVELOP:~$ ls test.txt_ && echo OK || echo NG
ls: 'test.txt_' にアクセスできません: そのようなファイルやディレクトリはありません
NG

これと同様の処理をfishで行う場合、「&&」や「||」だとエラーになる。
じゃどうするのかというと、以下のように「;and」や「;or」で同様の処理が行える。

コマンド ;and echo ok ;or echo ng

blacknon@BS-PUB-DEVELOP ~> ls test*
test.txt  test1.txt
blacknon@BS-PUB-DEVELOP ~> ls test.txt ;and echo ok ;or echo ng
test.txt
ok
blacknon@BS-PUB-DEVELOP ~> ls test.txt_ ;and echo ok ;or echo ng
ls: 'test.txt_' にアクセスできません: そのようなファイルやディレクトリはありません
ng
blacknon@BS-PUB-DEVELOP ~> ls test.txt_ && echo ok ;or echo ng
Unsupported use of '&&'. In fish, please use 'COMMAND; and COMMAND'.
fish: ls test.txt_ && echo ok ;or echo ng
                    ^
blacknon@BS-PUB-DEVELOP ~> ls test.txt_ ;and echo ok || echo ng
Unsupported use of '||'. In fish, please use 'COMMAND; or COMMAND'.
fish: ls test.txt_ ;and echo ok || echo ng
                                 ^
blacknon@BS-PUB-DEVELOP ~>

 

まぁ、間違えても↑みたいにヒントとして出してくれるので、特に問題ないかとは思うのだが。

zsh最強シェル入門 zsh最強シェル入門

zshで『zsh-syntax-highlighting』を使ってコマンドラインにSyntax Highlightをさせる

$
0
0

zshで実行するコマンドのSyntax Highlightをさせる場合、『zsh-syntax-highlighting』というプラグインを導入するのが良いようだ。
インストールは簡単で、以下のコマンドを実行するだけだ。

git clone https://github.com/zsh-users/zsh-syntax-highlighting.git
echo "source ${(q-)PWD}/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" >> ${ZDOTDIR:-$HOME}/.zshrc
source ./zsh-syntax-highlighting/zsh-syntax-highlighting.zsh

 

以後は、コマンド実行時に存在しないコマンドだった場合に赤字になってくれる。

zsh最強シェル入門 zsh最強シェル入門

オンアクセスでのファイル改ざん検知を行える『Samhain』をCentOS 7にインストールする

$
0
0

オンアクセスでのファイルの改ざん検知(ファイルが改ざんされたと同時に検知)を行えるツールというと、OSSECとかTripwire(有償版)あたりかと思うのだが、この『Samhain』もオンアクセスでのファイル改ざん検知が行えるようだ。厳密にはホスト型のIDSなので、改ざん検知の他に以下のような機能を提供している。

  • 完全性チェック(チェックサムで変更を検知)
  • ログの集中監視
  • データベース、設定ファイルへの署名
  • ログファイルやメールへの署名

 

今回は、この『Samhain』をCentOS 7にインストールしてみる。
ただ、結論から言うとオンアクセスでの改ざん検知設定までは持っていけなかったので、今後も調査が必要かも…。

1.インストール

パッケージは無いので、普通にソースからインストールする。
せっかくなので、参考元のようにrpmパッケージも作ってみる。

yum install -y gcc rpm-build libacl-devel libattr-devel pcre-devel zlib-devel wget
echo "%_topdir $HOME/rpmbuild" > ~/.rpmmacros
wget http://www.la-samhna.de/samhain/samhain-current.tar.gz
tar xzvf samhain-current.tar.gz
tar xzvf samhain-[0-9]*.tar.gz
cd samhain-*
./configure \
  --enable-selinux \
  --enable-posix-acl \
  --enable-login-watch \
  --enable-mounts-check \
  --enable-logfile-monitor \
  --enable-process-check \
  --enable-port-check \
  --enable-userfiles \
  --enable-suidcheck
make rpm
yum install -y samhain-4.2.0.rpm

 

これでインストールができた。

2.初期化及び起動

次に、Samhainのデータベース初期化及びサービスの起動を行う。
(インストール時点ですでに自動起動設定は有効になっているので、そこについては変更をしない)

samhain -t init
/etc/init.d/samhain start

 

これでサービスが起動した。
ただ、この時点ではまだ改ざんが行われても検知されないようだ(実際に設定ファイル「/etc/samhainrc」をいじってみたりしたのだが、どうも検知されなかった)。
設定が悪かったのか不明だが、ログには何も吐き出されずだったので、また時間をみてちょこちょこいじっていくことにする。

 

【参考】

 

Managing Security with Snort & IDS Tools: Intrusion Detection with Open Source Tools Managing Security with Snort & IDS Tools: Intrusion Detection with Open Source Tools

tmuxでセッション開始時に特定のコマンドを実行させる

$
0
0

tmuxで、セッション開始時に特定のプログラムを起動させたい場合。
その場合は、ユーザのホームディレクトリ直下にある「~/.tmux.conf」に以下の一行を追加してやればよい。

●~/.tmux.conf

set-option -g default-command コマンドPATH

 

これで、tmuxの起動と同時に指定されたコマンドが実行される。

ターミナルマルチプレクサ tmux 入門 ターミナルマルチプレクサ tmux 入門

ワードリストの生成コマンド『crunch』を使ってみる

$
0
0

John the Ripperとかでパスワードクラックをする際に使われる辞書ファイルなのだが、ある程度パスワードに使われている文字が推測できている状況の場合、通常の辞書ファイルだと余分なパスワードもいっぱいあって処理に時間がかかる。「ある程度推測できているパスワードだけど、文字の順番入れ替えたりしてるだけのリストがほしい」という時は、パスワードなどのワードリスト生成用のツールである『crunch』コマンドというものを使うといいようだ。

1.インストール

ペネトレーションテスト時に使われるものなので、KaliLinuxには最初から入っている様子。CentOS などにインストールをする場合は、以下のコマンドを実行する。

wget https://downloads.sourceforge.net/project/crunch-wordlist/crunch-wordlist/crunch-3.6.tgz
tar xzvf crunch-3.6.tgz
cd crunch-3.6
make && make install

 

Debian/UbuntuやOS Xの場合は、以下でもインストールできる。

sudo apt install -y crunch # Debian/Ubuntu系の場合
brew install crunch # OS Xの場合

2.使い方

使い方は簡単で、以下のようにコマンドを実行する。

crunch <出力文字列の最短の長さ> <出力文字列の最長の長さ> [options] [<使用する文字列>]

 

主なオプションは以下。

  • -b … -oで出力先ファイルが指定されている場合、出力ファイルのサイズを指定する
  • -c … -oで出力先ファイルが指定されている場合、出力ファイルの行数を指定する
  • -d … 重複する文字の数を制限する
  • -f … charset.lstファイルを指定して文字列を生成する
  • -i … 単語リストの文字の順序を逆転させる
  • -I … -t使用時に、@%^をそのまま解釈できるようになる
  • -o PATH … 生成した文字列を指定されたPATHに出力する
  • -p … 繰り返し文字を含まずに生成する(-sとの併用不可)
  • -q … 指定されたファイルから文字列を生成する(-pと同様、一度使用した文字は使わない)
  • -r … 前回実行した際のコマンドを再開する(-sとの併用不可)
  • -s … ワードリストを開始する特定の文字列を指定する
  • -t … @、%^の特定のパターンを設定する
  • -z … 出力ワードリストファイルを-oと一緒に圧縮する

 

基本的には、-pあたりを覚えておけばよいだろう。
例えば、-pを使うことで文字の順序を入れ替えただけの値を得ることができる。

[root@BS-PUB-CENT7-01 ~]# crunch 3 3 -p abc
Crunch will now generate approximately the following amount of data: 24 bytes
0 MB
0 GB
0 TB
0 PB
Crunch will now generate the following number of lines: 6
abc
acb
bac
bca
cab
cba

 

これがないと、渡した文字すべての組み合わせを総当たりで出力してしまう。
以下のようなワンライナーで、ブレース展開使って無理やりやるのと変わらなくなるので注意。

 

TEST=$(echo test) && eval echo  $(eval echo $(echo $TEST | xargs -I@ sh -c 'echo \"{$(echo @ | sed "s/./&,/g;s/.$//g")}\"{$(echo @ | sed "s/./,/g;s/.$//g")}') | tr -d ' ' ) | tr ' ' '\n' | sort | uniq | wc -l

 

新しいLinuxの教科書 新しいLinuxの教科書

コンソール上で色々なシステム情報を出力できる『Inxi』コマンド

$
0
0

ネットで調べものをしていたところ、Linuxのシステムやハードウェアの情報についてわかりやすく出力してくれる『Inxi』コマンドなるものを見かけたので、ちょっとインストールしてみることにした。
インストールコマンドは以下。yumやaptからインストール可能だ。

sudo yum install inxi
sudo apt install inxi

 

インストール後は、普通にコマンドを実行してやればよい。
オプションなしでコマンドを実行することで、CPUやメモリ容量など、基本的なハードウェア情報を得ることができる。

inxi
blacknon@BS-PUB-UBUNTU-01:~$ inxi
CPU~Dual core Common KVM (-MCP-) speed~2266 MHz (max) Kernel~4.4.0-57-generic x86_64 Up~6 days Mem~264.7/1998.2MB HDD~42.9GB(12.6% used) Procs~144 Client~Shell inxi~2.2.35

その他、以下のようなオプションを付与することで諸々のハードウェア情報を得ることができる。

  • -A … オーディオ・サウンドカード
  • -S … Linuxカーネルやディストリビューションの情報
  • -M … PCのモデルなど
  • -C … CPU情報
  • -I … メモリの利用状況
  • -G … グラフィックカード情報
  • -N … ネットワークカード情報
  • -D … HDDなどのディスク情報
  • -F … すべての情報を出力する
  • -p … ディスクのパーティション情報
  • -b … サマリを出力する
  • -t c … CPU使用率の高いプロセスTOP5を出力する
  • -t m … メモリ使用率の高いプロセスTOP5を出力する
  • -w … お天気情報を取得する(-W Tokyo,Japanで都市を指定できる)
  • -s … CPUの温度・ファンの速度情報を取得する

出力情報を見る限り、個人的にはdmidecodeよりは見やすいと思う。

 

入門者のLinux 素朴な疑問を解消しながら学ぶ (ブルーバックス) 入門者のLinux 素朴な疑問を解消しながら学ぶ (ブルーバックス)

コンソール上でランダムな数字(乱数)を出力させる方法8個

$
0
0

コンソール上で、ランダムな数字を出力させたいというのがあったので、少し調べてみた。
結構いろいろな方法があるようだ。

1.環境変数「$RANDOM」を用いる

bashでは、環境変数「$RANDOM」を用いることで0~32767までの数字をランダムに出力させることができる。
0から数えるので、+100とかで指定すると0~99までしか出力しないので注意。

echo $RANDOM # 0~32767までの範囲で出力する
echo $((RANDOM%+101)) # 0~100までの範囲で出力する
echo $((RANDOM%100+101)) # 100~200までの範囲で出力する
[root@BS-PUB-CENT7-01 ~]# echo $RANDOM # 0~32767までの範囲で出力する
1885
[root@BS-PUB-CENT7-01 ~]# echo $RANDOM # 0~32767までの範囲で出力する
10607
[root@BS-PUB-CENT7-01 ~]# echo $((RANDOM%+101)) # 0~100までの範囲で出力する
76
[root@BS-PUB-CENT7-01 ~]# echo $((RANDOM%+101)) # 0~100までの範囲で出力する
22
[root@BS-PUB-CENT7-01 ~]# echo $((RANDOM%100+101)) # 100~200までの範囲で出力する
107
[root@BS-PUB-CENT7-01 ~]# echo $((RANDOM%100+101)) # 100~200までの範囲で出力する
138

 

複数の数字を得る場合は、以下のようにコマンドを実行することで指定回数繰り返し、ランダムな数字を複数出力させることができる。

yes 'echo $((RANDOM%+101))' | head -10 | bash # headで実行回数を指定
[root@BS-PUB-CENT7-01 ~]# yes 'echo $((RANDOM%+101))' | head -10 | bash # headで実行回数を指定
42
48
51
8
77
54
60
2
14
97

 

2./dev/urandom or /dev/randomを用いる

「$RANDOM」に比べるとちょっと扱いづらいけど、「/dev/urandom」もしくは「/dev/random」を読み込むことで、ランダムな文字列・値を取得することができる。そのままcatなどで開いても扱えないので、odで加工するのが一般的。2のべき乗の範囲の値が取得されるようなので、範囲をちゃんと指定する場合はさらに加工が必要になりそう。
とりあえず、以下のようにコマンドを実行することで0~100までの値を取得できる。

echo $(($(od -vAn -N1 -tu < /dev/urandom) % 101 ))
[root@BS-PUB-CENT7-01 ~]# yes 'echo $(($(od -vAn -N1 -tu < /dev/urandom) % 101 ))' | head -10 | bash
70
31
0
44
30
30
29
7
14
68

 

3.jotコマンドを用いる

seqのように利用できるBSD系のコマンドでjotというのがあるが、これには「-r」というランダムな値を出力するオプションが付いている。Debian/Ubuntu系であればaptでインストールできる。
以下のようにjotコマンドを実行することで、0~100までのランダムな値を10個出力させている。

jot -r 10 0 100
blacknon@BS-PUB-UBUNTU-01:~$ jot -r 10 0 100
61
50
44
54
55
88
77
5
20
71

 

4.seq + shufで頑張る

jotがないorインストールできない場合、とりあえずseqとshufで似たようなことはできる(処理効率悪いと思うけど)。
とりあえず、以下のようにコマンドを実行することで0~100のランダムな値を1個得ることができる。

seq 0 100 | shuf | head -1
blacknon@BS-PUB-UBUNTU-01:~$ seq 0 100 | shuf | head -1
42
blacknon@BS-PUB-UBUNTU-01:~$ yes 'seq 0 100 | shuf | head -1' | head -10 | bash
20
60
14
3
20
64
24
0
33
64

5.awkを用いる

awkのrand関数を用いることで、ランダムな数字を取得できる。srand()で初期化が必要なのだが、これは現在時刻(秒)を元に計算しているため、1秒経過しないとランダムな値でも同じ値が出力されてしまうので注意。

awk 'BEGIN{srand(1);print int(rand()*100)}'
blacknon@BS-PUB-UBUNTU-01:~$ awk 'BEGIN{srand();print int(rand()*100)}'
88
blacknon@BS-PUB-UBUNTU-01:~$ awk 'BEGIN{srand();print int(rand()*100)}'
60
blacknon@BS-PUB-UBUNTU-01:~$ # 連続で実行しても、秒が経過するまでは同じ値が出力される。
blacknon@BS-PUB-UBUNTU-01:~$ yes "awk 'BEGIN{srand();print int(rand()*100)}'" | head -10 | bash
70
70
70
70
70
70
70
70
70
70

 

6.Perlで出力する

Perlで出力する場合はこんな感じ。

perl -e 'printf ("%d\n",int(rand($MAX - $MIN)))'
perl -e 'foreach $i (1..n) {printf ("%d\n",int(rand(MAX - MIN)))}'
blacknon@BS-PUB-UBUNTU-01:~$ perl -e 'printf ("%d\n",int(rand(100 - 0)))'
82
blacknon@BS-PUB-UBUNTU-01:~$ perl -e 'foreach $i (1..10) {printf ("%d\n",int(rand(100 - 0)))}'
6
90
53
1
25
68
93
97
9
82

 

7.Rubyで出力する

Rubyでやる場合はこんなん。

ruby -e 'printf("%d\n",Random.rand(MIN...MAX))'
ruby -e 'ran= 0..n;ran.each{printf("%d\n",Random.rand(MIN...MAX))}'
blacknon@BS-PUB-UBUNTU-01:~$ ruby -e 'printf("%d\n",Random.rand(0...100))'
71
blacknon@BS-PUB-UBUNTU-01:~$ ruby -e 'ran= 0..10;ran.each{printf("%d\n",Random.rand(0...100))}'
78
71
18
12
49
92
32
7
72
35
73

 

8.Pythonで出力する

Pythonの場合。

python -c 'from random import randint; print(randint(MIN,MAX))'
python -c 'from random import randint; print "\n".join(map(str,[randint(MIN,MAX) for p in range(0,n)]))'
blacknon@BS-PUB-UBUNTU-01:~$ python -c 'from random import randint; print(randint(0,100))'
91
blacknon@BS-PUB-UBUNTU-01:~$ python -c 'from random import randint; print "\n".join(map(str,[randint(0,100) for p in range(0,10)]))'
93
49
23
9
29
72
23
53
34
53

 

コマンドラインではじめるデータサイエンス ―分析プロセスを自在に進めるテクニック コマンドラインではじめるデータサイエンス ―分析プロセスを自在に進めるテクニック
Viewing all 743 articles
Browse latest View live