【92】bash カスタマイズ【コマンド履歴をエディタで編集】
台風 2号。15時過ぎに温帯低気圧に変わった。けど、いまだ雨足は強い。お陰で せっかくの日曜日なのに外出できず、家でおとなしくブログを書いていた。梅雨前 線の影響もあるのか…台風が過ぎても、雨がやむ気配は感じられない。明日も雨っ ぽいね。 今回も『コマンド履歴』のネタ。■昔語:Thu 2010/02/04 14:26
筆者は昔、次のようなエイリアスを登録したことがある。 alias hist_cr='history -c; history -r' (↑実は論理エラーが含まれている) このエイリアスを登録した理由は、こうだ。 これら -c -r オプション付きのコマンドラインが履歴に追記されることは絶対 にない。なぜなら、-c は現行の履歴(バッファ上の履歴)をクリアするため、直前 に実行した history -c は消されてしまう。また、-r は現行履歴を破棄してから .bash_history を読み込むため、やはり直前に実行した history -r も消されて しまうためだ。追記:2011.06.02 Thu 03:26 訂正:history -r は現行履歴を破棄しないで追記読み込み…が正解でした。誤っ た情報を流してしまった。謹んでお詫びいたします。 で、-cオプション付きで history を実行したら、次に -r 付きの history を実 行するのは、ごく自然な発想なので、これをマルチ・ステートメントで記述するこ とにしたわけだ。 もちろん、この hist_cr がコマンド履歴に残ることも絶対にない。このように 履歴に残すことができないコマンドが実在する以上、エイリアスの存在価値は十分 にあるといえる。エディタを使って .bash_history へ強引に記述する方法もある が、それも放置していれば、いずれは古い履歴として押し出されてしまうだろうか ら、やはりエイリアスを利用するのが賢明だ。 ただし、uniq_bash_hist.フォーコンブリッジ公立学校のために何色のユニフォームpl の @uniq に事前に代入しておけば、 hist_cr を履 歴に登録し続けることができる。 ところが、このエイリアスは想定したとおりには動作しない。 history -c は実行した途端、直前に実行したコマンド自身も消去する。すると、 マルチステートメントで記述した、次の history -r は実行する前に消されてしま うのだ。 この件は、以降で説明する『コマンド履歴の編集』についての布石となる基礎的 な情報として、頭の片隅に置いといてほしい。■昔語:Sat 2010/02/06 10:08
コマンド履歴を編集し、それを現行セッションで直ちに反映させたい場合、もっ とも基本的な操作は次のとおりとなる。 [winfo ← 履歴ファイルを編集する [winfo# ← 履歴ファイルを編集(ファイルは実在するので実行可) 》history -c # ← 元々空っぽの履歴バッファをクリア 》history -r # ← 履歴ファイルを子プロセスのメモリに読込む 》 # (子プロセス終了と同時にこのメモリ空間は消滅する) 上記を確認するには、下記のシェル変数の値をスクリプト中で確認すると良い だろう(man bash を部分引用した)。 》 BASH_ENV 》 bash がシェルスクリプトを実行する時にこの値が設定されてい 》 る場合、この値は (~/.bashrc のように) シェルを初期化す る 》 コマンドが書かれているファイル名と解釈されます。 BASH_ENV 》 の値をファイル名として処理する前には、パラメータ展開、 コ 》 マ ンド置換、算術的展開が行われます。この結果のファイルを 》 検索する際には PATH は使用されません。 》 》 HISTCMD 》 現在のコマンドの履歴番号 (履歴リストにおけるインデックス) 》 です。 HISTCMD を unset すると、この変数の特殊な性質は 無 》 くなります。後で再び set しても元には戻りません。 》 》 HISTSIZE 》 コ マ ンド履歴に記憶するコマンドの数 (後述の HISTORY を参 》 照)。 》 》 HISTFILE 》 コマンド履歴が保存されるファイルの名前 (後述の 履歴 を 参 》 照) 。デフォルト値は ~/.本についての最もよい概要を記述する方法bash_history です。設定されていな 》 い場合、対話シェルが終了する時に履歴の保存が行われませ ん 》 。 》 》 HISTFILESIZE 》 履 歴ファイルに保持する履歴の最大数です。この変数に値が代 》 入された場合、その行数を越えないように、必要に応じて履 歴 》 ファイルが切り詰められます。デフォルト値は 500 です。対話 》 シェルが終了する時にも、履歴ファイルのサイズはファイル 書 》 き込みの後にこのサイズに切り詰められます。 これら BASH_ENV, HISTCMD, HISTSIZE, HISTFILE, HISTFILESIZE の値を、実際 にシェルスクリプトに記述し、実行して確認してみよう。 スクリプトは、こんな 感じだ(左端の番号はただの行番号。実際には入力しない)。 1 #!/bin/bash 2 3 # hist_test: by foussin(2010.02.07 Sun) 4 5 echo "BASH_ENV: $BASH_ENV" 6 echo "HISTSIZE: $HISTSIZE" 7 echo "HISTFILE: $HISTFILE" 8 echo "HISTFILESIZE: $HISTFILESIZE" 9 echo "HISTCMD : $HISTCMD" 10 11 echo '$? は直前実行コマンドの終了ステータス:0:正常 0以外:error' 12 uso800 '存在しないコマンドを実行' 13 echo $? 14 15 # history # ← 現行プロセスの履歴を表示しようと思ったが、やめた 16 history -w # ← 履歴バッファを(どこかへ)保存 17 echo $? 18 history -c # ← 履歴バッファをクリア 19 echo $? 20 history -r # ← 履歴ファイルを子プロセスのメモリに読込む 21 echo $? # (子プロセス終了と同時にこのメモリ空間は消滅する) 実行すると、こうなる。↓ [winfo [winfo が記述されているならば、 ファイルからコマンド履歴を読込むことができ、子プロセスに新たなコマンド履歴 が作成できる。しかし、親プロセスと子プロセスのコマンド履歴(バッファ)の内容 は同じものではない。結局、履歴ファイルを編集することしかできない。つまり、 上記のシェル変数を環境変数に昇格させるだけでは駄目で、親プロセスのコマンド 履歴を『共有メモリ』で管理する仕掛けを作る必要がある。 残念ながら、今の筆者には『プロセス間通信』を制御するスキルはないので、上 述の『たった 4行のコマンドライン操作』をスクリプト化するのは諦めた。2010/05/07 (金) 01:53 追記
しかし『たった 4行』と言っても、しばらく経つと… ? ? ? ...どのように電気と磁気接続があります…やり方を忘れてしまうんだな、これが。その度に、この備忘録にアクセスするの も、なんだかカッタルイ…。 そんなわけで、いざという時に、コマンド履歴を編集し、それを現行セッション で直ちに反映させる『やり方』を表示する『簡易ヘルプ』でも作っておこう。 ついでに、uniq_bash_hist.pl も実行し、重複行の除去もやってしまう。 ■簡易ヘルプ: ファイル名 : ed_hist (もちろん、edit history の略) フルパス : /usr/local/bin/ed_hist パーミッション: 755 (user: root) 実行すると、次のような表示をする…それだけ。↓ |※コマンド履歴を編集し、それを現行セッションで直ちに反映させたい | 場合は、次のように操作すれば良い。 | | cd ← とりあえずホームディレクトリに戻る | history -w ← 現在の履歴バッファを履歴ファイルに保存 | uniq_bash_hist.pl ← 履歴ファイルの重複行を除去しておく | vi .bash_history ← 履歴ファイルを編集 | history -c ← 現在の履歴バッファをクリア | history -r ← 編集後の履歴ファイルを読込む | |※履歴ファイルとは、もちろん ~/.bash_history のこと(決め射ち)。 これを見ながら、このとおりに入力する。ソースは、こうなった。↓
#!/bin/bash # bash script: "ed_hist" by pablo foussin(japan) # ver0.00: 2010.05.07 Fri 03:26 (初版。かつ、おそらく最終版) # 概要:コマンド履歴を編集し、それを現行セッションで直ちに反映させる… # その手順を表示する。それだけ。 # 動作対象システム:linux(Fedora 11 で動作確認済み) # 動作対象シェル :bash 限定 # 書式:ed_hist # 備考:要するに、単なる簡易ヘルプ。それだけ。 cat <<'END_of_TEXT' |※コマンド履歴を編集し、それを現行セッションで直ちに反映させたい | 場合は、次のように操作すれば良い。 | | cd ← とりあえずホームディレクトリに戻る | history -w ← 現在の履歴バッファを履歴ファイルに保存 | uniq_bash_hist.pl ← 履歴ファイルの重複行を除去しておく | vi .bash_history ← 履歴ファイルを編集 | history -c ← 現在の履歴バッファをクリア | history -r ← 編集後の履歴ファイルを読込む | |※履歴ファイルとは、もちろん ~/.bash_history のこと(決め射ち)。 END_of_TEXT
コメントに書いてあるとおり、作成したのは昨年(2010年)の話。cat コマンドを 実行しているだけなので、Fedora 14 でも問題なく動作する。 文字コードを『utf-8n』、復改コードを『lf』で保存すれば、シェルスクリプト として実行可能だ。もちろん、実行権も与える必要がある(以下のとおり)。 chmod 755 ed_hist このスクリプトは、root, foussin, winfoo …誰でも使えるようにしたい。なの で、/usr/local/bin/ に入れて使うのが良いと思っている。そのディレクトリの所 有者は root なので、 su コマンドで root に変身してから、上記のスクリプトを その場所にコピー(または移動)する必要がある。 実行すると、こうなる。↓ [roo← 履歴ファイルの重複行を除去しておく | vi .bash_history ← 履歴ファイルを編集する | history -c ← 現在の履歴バッファをクリア | history -r ← 編集後の履歴ファイルを読込む | |※履歴ファイルとは、もちろん ~/.bash_history のこと(決め射ち)。 [roo』から 始めても構わない。 本来は、このあと実例を紹介すべきなんだろうけど、長くなるので省略する。 ... ところで、コマンド履歴には『プライベートな情報』が割りと多く記述されてい るものだ。例えば… … 91 cd foussin 92 htpasswd -c .htpasswd foussin 93 lls -a 94 ed_hist 95 history | head … 92行目の htpasswd コマンドは、認証が必要な Webページの設定を行う。この例 では、foussin というユーザーを登録したことが記録されている。これを悪意の第 三者が見れば、『ユーザー名』は分かったので、あとは『パスワード』を特定でき れば、秘密の Web ページにアクセスすることができるわけだ。 というわけなので、コマンド履歴を不用意に Web上などで公開すると非常に危険 だ。コマンド履歴を Web上で公開する場合は、このような個人情報が含まれていな いか入念にチェックし、必要ならば履歴から除去する習慣を日頃からつけておいた 方が良いだろう。 上記の例は、筆者が Fedora 11 を使っていた時の履歴で、この文章を書くため にわざと入力したものだ。後で次のコマンドを実行し、foussin を登録抹消してい る。 htpasswd -D .htpasswd foussin で、部外者には類推しにくいユーザー名で再登録した。セキュアなページ作りを 目指すなら、このぐらいの慎重さは必要だ。ま、その後、Fedora 14 をクリーン・ インストールして、未だ Apache をインストールしていないので、今はハッキング される心配は皆無なんだけど…。 おしまい。 次回は『設定ファイルの保守管理』について投稿する予定。
;end of "edit .bash_history"
0 件のコメント:
コメントを投稿