【CentOS6】鍵認証によるssh接続
ローカルのMacからリモートのCentOSへ鍵認証でssh接続するための手順をメモっておきます。
公開鍵および秘密鍵は予め作成が済んでいるものとします。
環境
鍵の設定
まずはローカルMacからリモートに公開鍵の送付。
scp ~/.ssh/id_rsa.pub some_user@xxx.xxx.xxx.xxx:~/.
次にリモートのCentOSにログインし、公開鍵の設定を行う。
mkdir ~/.ssh # .sshディレクトリがない場合 mv ~/id_rsa.pub ~/.ssh/. cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys
次にsshd_config
の修正。
sudo emacs /etc/ssh/sshd_config
各行のコメントアウトを外し、AuthorizedKeysFileでは公開鍵の場所の指定をする。
RSAAuthentication yes PubkeyAuthentication yes AuthorizedKeysFile ~/.ssh/authorized_keys
またパスワード認証は不要なので、PasswordAuthentication no
に設定する。
以上終了後sshdの再起動。
sudo service sshd restart
ssh -i ~/.ssh/id_rsa some_user@xxx.xxx.xxx.xxx
無事鍵認証でssh接続成功!
ついでにローカルMacのconfigファイルにssh接続の設定を追記。
emacs ~/.ssh/config
Host some_host HostName xxx.xxx.xxx.xxx User some_user port 22 IdentityFile ~/.ssh/id_rsa
上記設定追記後、下記コマンドでssh可能。
ssh some_host
面倒な入力がなくなって便利!
参考
【CentOS6】新規ユーザーの追加とsudo権限の付与
環境
CentOS 6.6
ユーザー作成と権限付与
各コマンドはsudo権限のあるユーザーで実行する。
またsudoは、wheelグループに属しているユーザーのみ可能という方針で行う。
visudo
コマンド単体で/etc/sudoers
の編集は可能だが、/etc/sudoers
の下部に記載されている#includedir /etc/sudoers.d
によって、/etc/sudoers.d/
下のファイルが読み込まれるため、ここでは/etc/sudoers.d/
下に新規で設定ファイルを作成し、そのファイルに設定を記載する。
ちなみに#
はコメントアウト的な意味ではないので注意。
まずはユーザーの追加とパスワードの設定。
$ sudo useradd hoge $ sudo passwd hoge
次にsudo権限の付与。
$ visudo -f /etc/sudoers.d/wheel
当たり前だが、emacsではなくviで開くので注意。
下記設定を新規記載。
%wheel ALL=(ALL) ALL
wheelユーザーに権限付与。
文法ミス等してしまうと、sudoコマンドが実行不可になってしまう危険があるので注意。visudo
で開いており、警告を出してくれるはずなので大丈夫だとは思われる。
最後にユーザーをwheelグループに追加。
$ sudo usermod -G wheel hoge
新しく作ったユーザーに変更し、sudoが必要なコマンドを実行してみる。
$ su hoge
$ sudo visudo
[sudo] password for hoge
無事sudo権限を持ったユーザーの作成に成功!
参考
CentOS - sudoできるユーザを制限する。 - Qiita
CentOS - sudoers は編集せずに sudoers.d の中に設定を書こう - Qiita
【MeCab】Python3で解析時にbuiltins.UnicodeDecodeError【Flask】
Twitterから取得したデータをMeCabで処理し、Flaskを用いたWebアプリケーション上で表示しようとしたところ、下記のようなエラーが出現。
builtins.UnicodeDecodeError
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xfc in position 0: invalid start byte
もしかしたらまたハマるかもしれないので念のためメモ。
環境
解決策
原因は不明だが、エラーメッセージを見るにエンコーディングがどうので死んでしまう模様。
ちなみにMeCabの実装コードは下記のような感じ。
import MeCab mecab = MeCab.Tagger() node = mecab.parseToNode("私はルイズが好きです。なぜなら、彼女はとてもキュートだからです。") while node: print(node.surface) node = node.next
中々解決策に辿りつけなかったのだが、一行追記することでエラーの回避が可能に。
原因は正直良くわからない。
修正したコードは以下。
import MeCab mecab = MeCab.Tagger() mecab.parse('') # これを追記! node = mecab.parseToNode("私はルイズが大好きです。なぜなら、彼女はとてもとてもキュートだからです。ルイズかわいい!") while node: print(node.surface) node = node.next
元々Python3でMeCabのparseToNode
メソッドを使用すると、最初に返されるnodeが空の値というバグがあり、この解決のためにmecab.parse('')
をするらしいのだが、UnicodeDecodeErrorへも対策として効果を発揮してくれた。
原因はよく分からないが、動くようになったので取り敢えず良しとする。
参考
【Bottle】@viewデコレータを自前で定義する【Jinja2】
通常Bottleを使用する場合は、使用するテンプレートに併せて必要なメソッドやデコレータをインポートして用いることで、viewテンプレートの描画を非常に簡単に行うことが出来ます。
例えば、Jinja2テンプレートを使用し、メソッドでviewテンプレートの描画を行う場合は以下のようになります。
from bottle import route, jinja2_template as template @route('/') def index(): return template('index.html', data = some_func())
また、同様の処理をデコレータで実装すると以下のようになります。
from bottle import route, jinja2_view as view @route('/') @view('index.html') def index(): return dict(data=some_func())
このメソッド群は非常に便利ですが、細かいセッティングをしようとすると、少なくない問題が発生します。
例えば、テンプレート側で何らかの関数を利用したい場合、jinja2.Environment
のglobals
に追加しますが、bottleに用意されているメソッドでそれを実装するのは少々難しいです(そこまでソースコードを読んでいないので可能かもしれません)。
というわけで、templateの展開を行うviewデコレータを自力で実装してしまえという結論に至ります。
環境
Bottle v0.12
Jinja2 v2.8
実装
新しいview用のファイルをdecoview.pyという名前で作成し、以下のようにします。
# decoview.py import functools import jinja2 env = jinja2.Environment( loader=jinja2.FileSystemLoader('./path/to/views'), autoescape = True ) env.globals.update({ 'some_func_key', some_func() }) def some_func(): return 'Called some_func!' def view(template_name): def decorator(view_func): @functools.wraps(view_func) def wrapper(*args, **kwargs): response = view_func(*args, **kwargs) if isinstance(response, dict): template = env.get_or_select_template(template_name) return template.render(**response) else: return response return wrapper return decorator
せっかくなのでautoescape
もTrue
にしてみました。
新しく作成したdecoviewをインポートして使用すれば、jinja2テンプレートファイルの中でsome_func()
が実行可能です。
# index.py from bottle import route from decoview import view @route('/') @view('index.html') def index(): return {}
例えば下記のようにjinja2テンプレートを呼び出します。
<!-- index.html -->
{{ some_func_key }}
きっとCalled some_func!
という文字列が表示されていることと思います。
参考
API — Jinja2 Documentation (2.8-dev)
Jinja2 templates and Bottle | Reliably Broken
キーボードの入力ソースからUSを削除する
何故か定期的に復活してくるためメモ。
環境
解決策
まずはメニューバーからキーボード環境設定を開く。
入力ソースタブに移動し、USを選択すると、
−
が選択出来ない状態になっている。
以前までは日本語入力ソースのことえりを追加後、削除という手順を行っていたが、Yosemiteからことえりが廃止されたため、ことえりの追加は出来ない。
しかし、新規に追加された日本語入力ソースを一旦追加して同様の手順を行えば、これまで通りにUSソースの削除が可能。
+
をクリックし、日本語 -> 日本語
を選択して追加。
USを選択すると、−
が有効になっている。
あとはUSおよび日本語の順に−
で取り除けば……
綺麗サッパリ!
【Jinja2】特別な定数は小文字を使う
Noneってなんだよと度々怒られたのでメモ。
Jinja2ではPythonのTrue
,False
,None
は小文字で表記される。
# × {% if some_func() is None %} # ◯ {% if some_func() is none %}
いい加減にやってると結構難しい……。
参考
【Python】returnを記述しなかった関数が返す値
pythonコードを書いている際に、returnを書いていない(返り値の指定がない)関数が何を返しているのかが気になったためメモ。
結果からいうとNone
を返している。
def foo(): pass foo() is None # True
明示的にreturnを書いた場合も同様にNoneを返している模様。
def bar(): return bar() is None # True foo() is bar() # True
returnがないとなんとなく落ち着かないのは何故だろう……。
参考
関数の中で返り値が指定されていない場合の扱い | 関数・メソッド | プログラミング言語の比較 | hydroculのメモ
縦タブのサムネイル除去も標準搭載したVivaldiはやはり最強か
以前の記事でユーザー手動での縦タブ時サムネイル除去を紹介したのですが、やはり不評だったのか、Snapshot 1.0.190.2から標準のオプションとしてサムネイルの除去が実装されました。
Snapshotの入手はこちらのページ右上から可能です。
あくまでSnapshotリリースは不安定な開発版ですので、不具合が起こっても文句はいいっこなしです。
では早速設定 -> デザイン
から
Show Tab Thumbnails
のチェックを外せば完了です。
またShow Tooltips for Tabs
のチェックを外すと、
上画像のタブにマウスオーバーしたときの情報を非表示に出来ます。
その他セッティングオプションも続々と実装されてきており、今後とも成長が見込めるのではないでしょうか。
やはりVivaldiが最強の系譜か……。
参考
Vivaldi.net - Snapshot 1.0.190.2 Startpage customization, UI zooming, auto-update on mac and more