たまたまGoogleマップのストリートビューを見ていたら、ストリートビュー撮影車にカメラ目線の猫を発見しました。
おや?何かいる!と思ってズームしてみると・・・
猫だ!
おぬこさまだ!!!
しかし、心なしか「見てないで助けろ」とでも言いたさそうですねw

たまたまGoogleマップのストリートビューを見ていたら、ストリートビュー撮影車にカメラ目線の猫を発見しました。
おや?何かいる!と思ってズームしてみると・・・
猫だ!
おぬこさまだ!!!
しかし、心なしか「見てないで助けろ」とでも言いたさそうですねw
先ほどの猫ちゃんが無事に家に戻れるのだろうかと気になって、Googleストリートビューを別角度から見てみました。
どうやら体を反転させることができたようですが、やっぱりこちらを向いて「見てないで助けろ」と言いたさそうでした。にゃー。
あるシステムの入力項目から入力されたテキストデータから、カタカナを強制的にアルファベット(ローマ字)へ変換したいという要件が出てきました。さすがにワンライナーでやるにはキツいので、sedの置換ファイルを作ってやるのが楽ですね。
s/キャ/kya/g s/キュ/kyu/g s/キョ/kyo/g s/ギャ/gya/g s/ギュ/gyu/g s/ギョ/gyo/g s/シャ/sha/g s/シュ/shu/g s/ショ/sho/g s/ジャ/ja/g s/ジュ/ju/g s/ジョ/jo/g s/チャ/cha/g s/チュ/chu/g s/チョ/cho/g s/ヂャ/ja/g s/ヂュ/ju/g s/ヂョ/jo/g s/ニャ/nya/g s/ニュ/nyu/g s/ニョ/nyo/g s/ヒャ/hya/g s/ヒュ/hyu/g s/ヒョ/hyo/g s/ビャ/bya/g s/ビュ/byu/g s/ビョ/byo/g s/ピャ/pya/g s/ピュ/pyu/g s/ピョ/pyo/g s/ミャ/mya/g s/ミュ/myu/g s/ミョ/myo/g s/リャ/rya/g s/リュ/ryu/g s/リョ/ryo/g s/ファ/fa/g s/フィ/fi/g s/フェ/fe/g s/フォ/fo/g s/ティ/thi/g s/ディ/dhi/g s/ヴァ/va/g s/ヴィ/vi/g s/ヴ/vu/g s/ヴェ/ve/g s/ヴォ/vo/g s/ア/a/g s/イ/i/g s/ウ/u/g s/エ/e/g s/オ/o/g s/カ/ka/g s/ガ/ga/g s/キ/ki/g s/ギ/gi/g s/ク/ku/g s/グ/gu/g s/ケ/ke/g s/ゲ/ge/g s/コ/ko/g s/ゴ/go/g s/サ/sa/g s/ザ/za/g s/シ/shi/g s/ジ/ji/g s/ス/su/g s/ズ/zu/g s/セ/se/g s/ゼ/ze/g s/ソ/so/g s/ゾ/zo/g s/タ/ta/g s/ダ/da/g s/チ/chi/g s/ヂ/ji/g s/ツ/tsu/g s/ヅ/zu/g s/テ/te/g s/デ/de/g s/ト/to/g s/ド/do/g s/ナ/na/g s/ニ/ni/g s/ヌ/nu/g s/ネ/ne/g s/ノ/no/g s/ハ/ha/g s/バ/ba/g s/パ/pa/g s/ヒ/hi/g s/ビ/bi/g s/ピ/pi/g s/フ/fu/g s/ブ/bu/g s/プ/pu/g s/ヘ/he/g s/ベ/be/g s/ペ/pe/g s/ホ/ho/g s/ボ/bo/g s/ポ/po/g s/マ/ma/g s/ミ/mi/g s/ム/mu/g s/メ/me/g s/モ/mo/g s/ヤ/ya/g s/ユ/yu/g s/ヨ/yo/g s/ラ/ra/g s/リ/ri/g s/ル/ru/g s/レ/re/g s/ロ/ro/g s/ワ/wa/g s/ヲ/wo/g s/ン/n/g s/ー/-/g
例えば大岡山(オオオカヤマ)をカタカナからローマ字に変換するにはこうします。
$ echo "オオオカヤマ" | sed -f katakana2alpha.sed oookayama
先頭文字のみを大文字にするには、awkのワンライナーを使うと便利です。今回のワンライナーは py4s-tnk さんの一行をパk・・・参考にさせていただきました。
$ echo "オオオカヤマ" | sed -f katakana2alpha.sed | awk '{print toupper(substr($1,1,1))substr($1,2)}' Oookayama
上に貼り付けたコードをご覧いただけるとおわかりいただけるかと思いますが、2文字で発音する文字をファイルの最初に持ってきています。こうすることで、「貴社の記者は汽車で帰社した(キシャノキシャハキシャデキシャシタ)」をうまく変換することができます。
$ echo "キシャノキシャハキシャデキシャシタ" | sed -f katakana2alpha.sed kishanokishahakishadekishashita
もしこの工夫がなければ・・・
$ echo "キシャノキシャハキシャデキシャシタ" | sed -f katakana2alpha.sed kishiャnokishiャhakishiャdekishiャshita
このように、1文字目でマッチさせてしまうため、拗音があると無視されてしまうのです。拗音だけの変換テーブルを作ってやればいいじゃんという声もあるかも知れませんが、そもそも拗音だけ発音するという機会はないので作っていません。
どうしてもファイルを作りたくないという方はワンライナーでやいjって、どうぞ。
$ echo "キシャノキシャハキシャデキシャシタ" | sed -e "s/キャ/kya/g;s/キュ/kyu/g;s/キョ/kyo/g;s/ギャ/gya/g;s/ギュ/gyu/g;s/ギョ/gyo/g;s/シャ/sha/g;s/シュ/shu/g;s/ショ/sho/g;s/ジャ/ja/g;s/ジュ/ju/g;s/ジョ/jo/g;s/チャ/cha/g;s/チュ/chu/g;s/チョ/cho/g;s/ヂャ/ja/g;s/ヂュ/ju/g;s/ヂョ/jo/g;s/ニャ/nya/g;s/ニュ/nyu/g;s/ニョ/nyo/g;s/ヒャ/hya/g;s/ヒュ/hyu/g;s/ヒョ/hyo/g;s/ビャ/bya/g;s/ビュ/byu/g;s/ビョ/byo/g;s/ピャ/pya/g;s/ピュ/pyu/g;s/ピョ/pyo/g;s/ミャ/mya/g;s/ミュ/myu/g;s/ミョ/myo/g;s/リャ/rya/g;s/リュ/ryu/g;s/リョ/ryo/g;s/ファ/fa/g;s/フィ/fi/g;s/フェ/fe/g;s/フォ/fo/g;s/ティ/thi/g;s/ディ/dhi/g;s/ヴァ/va/g;s/ヴィ/vi/g;s/ヴ/vu/g;s/ヴェ/ve/g;s/ヴォ/vo/g;s/ア/a/g;s/イ/i/g;s/ウ/u/g;s/エ/e/g;s/オ/o/g;s/カ/ka/g;s/ガ/ga/g;s/キ/ki/g;s/ギ/gi/g;s/ク/ku/g;s/グ/gu/g;s/ケ/ke/g;s/ゲ/ge/g;s/コ/ko/g;s/ゴ/go/g;s/サ/sa/g;s/ザ/za/g;s/シ/shi/g;s/ジ/ji/g;s/ス/su/g;s/ズ/zu/g;s/セ/se/g;s/ゼ/ze/g;s/ソ/so/g;s/ゾ/zo/g;s/タ/ta/g;s/ダ/da/g;s/チ/chi/g;s/ヂ/ji/g;s/ツ/tsu/g;s/ヅ/zu/g;s/テ/te/g;s/デ/de/g;s/ト/to/g;s/ド/do/g;s/ナ/na/g;s/ニ/ni/g;s/ヌ/nu/g;s/ネ/ne/g;s/ノ/no/g;s/ハ/ha/g;s/バ/ba/g;s/パ/pa/g;s/ヒ/hi/g;s/ビ/bi/g;s/ピ/pi/g;s/フ/fu/g;s/ブ/bu/g;s/プ/pu/g;s/ヘ/he/g;s/ベ/be/g;s/ペ/pe/g;s/ホ/ho/g;s/ボ/bo/g;s/ポ/po/g;s/マ/ma/g;s/ミ/mi/g;s/ ム/mu/g;s/メ/me/g;s/モ/mo/g;s/ヤ/ya/g;s/ユ/yu/g;s/ヨ/yo/g;s/ラ/ra/g;s/リ/ri/g;s/ル/ru/g;s/レ/re/g;s/ロ/ro/g;s/ワ/wa/g;s/ヲ/wo/g;s/ン/n/g;s/ー/-/g"
以上、sed awkの小ネタでございました。
こんにちは。主夫になりたい @nullpopopo です。先日、近所のスーパーのページ取得がうまくいかず、特売情弱になりかけていましたが、CHIRASHIGETTERを作って近所のスーパーのサイト更新を検知してチラシの収集ができるようになってから、食生活のコスパが改善するわ健康的になるわモテまくりでリア充ライフを満喫するわでもう大変ですよ。まぁ、最後はウソなんですけどね。
で、うちから歩いて行くのが苦にならない範囲のスーパーは東急ストア、ライフ、フジマート、まいばすけっと、オオゼキ(最近できた)、サミットなんですが、東急ストアとライフとフジマートのチラシはどこかのASPを使っているようで、チラシのPDFへのリンクがFlashだったんですよね。これだと解析できないのでちょっと諦めて、まいばすけっとはそもそもチラシがWEBに公開されてなかったので、今のところ解析できたのはオオゼキとサミットです。で、解析に使ったコードはこちら。
オオゼキとサミットは店ごとのページにチラシのPDFファイルがリンクされているのですが、表と裏で別ファイルになっているので、HTMLソースからファイル名を抜き出してリンクを生成してダウンロードし、表裏のPDFを1つのファイルにまとめてDropboxへ保存するようにしました。こうすることで、スマホの上下スクロールだけでチラシを見ることができてなかなか便利です。スマホ片手にチラシ見ながら買い物できるっていいですねー。
あと、ページの更新を検知したときだけメールを飛ばしてフラグファイルを生成するようにしたので、GmailのラベルやDropboxの更新検知とIFTTTあたりを組み合わせれば面白いことできそうですね。
それでは、また!
たまに長い名前のパッケージがあるとyum listの出力が折り返されてしまうので、一覧をテキストへ出力するのが少し不便でした。なので以下のワンライナーで綺麗なタブ区切りに。
$ yum list | sed -e "s/[[:space:]]\+/\t/g" | sed -e ':loop; N; $!b loop; ;s/\n[[:space:]]/\t/g'
最初のパイプですべての連続したスペースを1タブに置換して、次のパイプでsedのループに渡し、改行の後に来るスペースをタブへ置換しています。2つめのsedはこちらを参考にさせていただきました。
勉強会やガチ作業ではノートPCを外に持ち出すぼくですが、軽い作業しかしない外出では少々しんどいなーということで、iPadでSSHできる環境を整えました。SSHクライアントはServerauditorが過不足なくいい感じに使いやすいのですが、やはりBlueToothキーボードが欲しいところですね。
ぼくのiPadは今からしたら少々古めな第三世代なので、対応キーボードがまだ売ってるか不安でしたが、ヨドバシの通販にあったので早速ロジクールのKeys-To-Goを購入しました。朝にぽちって夕方にはすぐ届くなんて、うれしい!
iPadの世代は、本体背面のこちらで確認することができます。
上の赤いアンダーラインを引いた箇所とアップルのサイトを突き合わせることで、iPadの世代を確認することができます。
夕方に届いたキーボードを早速開封してペアリング。割とすんなり繋がりました。横幅はiPad本体と一緒ですね。
持ってみた感じですが、重量が180gと超軽量なので、持ち運びは全然苦になりません。おまけに厚さが6mmとこんなに薄いので、カバンに入れてもハンドキャリーでもまったく楽ちんです。
打鍵してみた感じですが、肩幅が大きい私でもほとんどストレスを感じませんでした。ベッドにうつ伏せになって自分のサーバーにssh接続してカタカタやってみましたが、結構な速度にも付いて来れているようです。キートップの素材もソフトなので、スタバでドヤるときでも打鍵音が気にならないでしょう。しばらくこれで戦ってみたいと思います。いい買い物しました!
昨日の仕事帰りにオオゼキ戸越銀座店に寄ったら、北海道産 国産牛等級3 肩ロースステーキ用肉が値引きされていたので、たまに贅沢でもするかと買って帰りました。戦利品はこちらになります。
帰宅後パタリと倒れるようにして寝てしまったので、ステーキ肉も冷蔵庫でおねんねでしたが、朝からいっちゃいましたよ!
塩コショウで満足まんぞう!柔らかくてジューシーでした。(∩´∀`)∩ワーイ
渋谷のビックカメラへ行こうとしたら、道玄坂方向に運ばれるパトレイバーを発見。
あわてて撮ったのでズーム。
この後果たしてどうなった?続きはこちら。
渋谷警察署のほうから歩道橋を駅方向に歩いて気がついたのですが、旧東急東横線の駅舎が解体されて、JRの駅舎や246の真上にかかっていた鉄橋が丸見えでした。
自宅インフラ(自宅サーバーとは言っていない)にWindowsマシンが必要になったので、さくらのVPS for Windows Serverを1つ契約、自宅や出先からVNCのGUIでグリグリできるように環境構築したのでメモ。さくらのVPSのコントロールパネルからVNC接続できるのですが、そのために毎回さくらのコントロールパネルにログインしたくないのと、さりとて家から生VNCはセキュリティ的にどうなのよということで、SSHポートフォワードを使ってVNC接続を暗号化してWindowsサーバーにログインするようにしました。最初の設定は、さくらのVPS コントロールパネルから行います。
まずはRealVNC Serverをココからダウンロードします。プライベートな用途(実験目的)なのでココでFreeプランのキーを取得します。PersonalプランやEnterpriseプランにするとRealVNCだけで暗号化できるのですが、Freeプランは漢の生パケットです。なので、次に挙げるPowerShell SSH Server を併用します。
TechNetマガジンで紹介されていたPowerShell SSH Server、こちらも商用版があるのですが、個人使用は無償(ただし複数人および同時に複数SSHセッションを張ることができない)なので、こちらからダウンロードします。
RealVNC Serverのほうは、できることが少ないので気休め程度ですが、パスワードをかけるようにしておきましょう。PowerShell SSH Serverですが、次の項目にチェックを入れておきましょう。
[Service]タブ → 「Run as a Windows Service」
[Connection]タブ → 「Enable SSH Tunnel Support」「Enable SSH Reverse Tunnel Support」(SCPとSFTPはお好みで)
これら設定が終わったら、画面上部「Save Changes」をクリックし、「Start」または「Restart」をクリックします。
アプリケーションの設定ができたら、Windows ファイアウォールに穴をあけます。コントロールパネルからWindows ファイアウォールをクリックし、「詳細設定」をクリックします。受信の規則にVNC Serverが2つ、PowerShell Server V6が1つエントリされているかと思います。
VNC Serverのプロパティですが、私は以下のように設定しました。
[詳細設定]タブ → プロファイルに「プライベート」「パブリック」の2つをチェック
[スコープ]タブ → リモートIPアドレスで「これらのIPアドレス」を選択し、自宅の固定IPアドレスと踏み台VPSのIPアドレスを登録
PowerShell Server V6のプロパティですが、接続元を絞る要件などがなければ何も弄らなくてOKです。
■ 自宅のPCから繋いでみる
まずは自宅のPC(Fedora)からWindowsサーバーに向けてSSHのセッションを張ります。
$ ssh -L 5900:<WindowsサーバーのIPアドレス>:5900 <Windowsサーバーのユーザー名>@<WindowsサーバーのIPアドレス>
上記のように、SSHのポートフォワーディングでlocalhostの5900番ポートをWindowsサーバーの5900番(VNCのポート)へ転送します。SSHのパスワード(Windowsのパスワード)を入力してログインすると、PowerShellのプロンプトが表示されます。
次に、VNCクライアントを立ち上げ、localhostへ接続しましょう。今回はChromeアプリのVNC Viewerを使いました。
Connectを押下したあと、「Unencrepted Connection」という警告が出ますが、SSHポートフォワードで暗号化しているので気にせず「Connect」をクリックします。次にVNCサーバーで設定したパスワードを聞かれるので、パスワードを入力してOKをクリックします。Windowsサーバーにログオンしていない状態ですと、以下のような画面になります(壁紙は趣味で変えましたw)
ここでCtrl+Alt+Delを押すわけにいかないので、VNC ViewerのソフトウェアキーボードでCtrl+Alt+Delを送信します。
ここでユーザー名を聞かれる段階になったら、ソフトウェアキーボードは閉じてしまって構いません(てか邪魔ですよね?)。画面下部のキーボードボタンをクリックして閉じます。
いよいよWindowsにログオンです。
ご覧のように、デスクトップが表示されました。ログオン成功です。自宅から生VNCで繋がっていないことをnetstatで確認してみましょう。
1行目のローカルアドレスがTCPの22番ポートですので、VNCではなくSSHが待ち受けていることがわかります。また、1行目の外部アドレスは画面上伏せていますが、自宅の固定IPアドレスになっています。他にESTABLISHEDになっている通信はlocalhostとリンクローカルアドレスなので、外部のホストから突かれていないことがわかります。(本当は野ざらしのVPSなので80番ポートや443番ポートが凄いことになっていましたが、Windowsファイアウォールで閉じました)
せっかくなので、SSHクライアントのほうも見てみましょう。
ご覧のように、PowerShellをSSH越しに実行しています。
これでWindowsサーバーを外から弄る環境ができました。意外と簡単ですね。でわ〜♪
前回の続きで、今回はスマホからSSHポートフォワードを使ってWindowsサーバーへVNC接続します。なお、Windowsサーバー側の準備は前回のエントリで済ませているものとします。
[スマホ] -> [踏み台VPS (CentOS)] -> [Windows Server]
スマホやタブレットは自宅の固定IPアドレスから繋ぐ場合、いきなりWindows ServerにSSH接続してポートフォワードしてもよいのですが、外出時に固定IPアドレスがあるとも限らないので、踏み台VPS経由で接続することにします。
App StoreやGoogle Playから VNC ViewerとServer auditorをダウンロードしておきます。
まず、Serverauditorで踏み台VPSに通常のSSH接続を行います。その後、ログインした踏み台VPSで以下のコマンドを実行し、WindowsサーバーにSSH接続します。
$ ssh <Windowsサーバーのユーザー名>@<Windowsサーバーのアドレス> -L 15900:localhost:5900
上記コマンドですが、踏み台VPSの15900番ポートをWindowsサーバーの5900番ポートへ転送します。
次に、ServerAuditorのPort Forwardingから新規接続設定を作ります。LocalとRemoteを選べますが、今回はLocalを選択します。設定は以下の通りです。
Host: 踏み台VPSのアドレス:ポート
Port From: 5900または1024番以上の任意のポート
Destination: localhost
Port To: 15900
設定が終わったら、ポートフォワードの設定をタップして「L」の文字が青くなればポートフォワード成功です。
ポートフォワードに成功したら、VNC VIewerに接続します。Address欄にはlocalhost、またはServer AuditorのPort Fromで何がしかのポート番号を設定した場合は localhost:<ポート番号> で設定します。以下のように、Windowsのログオン画面が出てきたら、接続はできています。
上記赤枠で囲った箇所のキーボードボタンをクリックします。
次に、ソフトウェアキーボードの赤枠で囲ったボタンをそれぞれタップし、Ctrl+Alt+Delを送信し、ログオンIDとパスワードを入力します。
無事にログオンできました。
WindowsサーバーにインストールしたTera Termを立ち上げて、踏み台VPSにログインしてみました。wコマンドを叩くと今ログイン中のユーザーが実行しているコマンドを見ることができますが、しっかりとSSHポートフォワードしていることがわかります。
Firefoxを起動してみました。
ちゃんとスマホからアクセスしてますよ?
スマホからもInternet Explorerの動作確認をしてみます。勿論動いているのはWindowsサーバーでです。
Dropboxに飛び込んできたスーパーのチラシを見るのもお手の物です。
2回にわたって、非WindowsマシンからWindowsマシンへ安全にVNC接続する方法をご紹介しましたが、やりたかったことをまとめると
ですが、自宅が固定IP回線だと、これに加えて、Windowsにしかドライバが提供されていないハードウェアのコントロールなんかもできちゃいますね。また、会社のPCなどのようにNATの内側にあるPCを制御する場合は、あらかじめ会社PCから待ち合わせ場所的なマシンにSSH接続しておいて、あたかも家から会社のPCで仕事してる素振りをすることもできます。
ここらへんのTIPSはPiro様の「まんがでわかるLinux シス管系女子」発売記念! 作者と学ぶ コマンドライン ハンズオン勉強会の資料に詳しくまとめられていますので、是非ご一読をば。
でわ〜♪
肩の治療のため紹介された病院へ通院のため奥沢へ。目黒線の奥沢に降り立ったのは実は初めてです。
日吉方向のホームを降り立つと、小さな駅前広場がありました。さすが世田谷、オシャレですね。
一体桃尻バーミヤン #とは 如何なるものか?
— 続きはこちら —
世田谷電器 USB9pinポート変換 奥沢一丁目 AR-UPIPO-A
監視サーバー(munin)をリプレースするついでにredmineを一撃インストール。さくらのVPS 2G(HDD)にCentOS6をISOイメージからインストール後、本エントリー末尾に添付した一撃シェルスクリプトをrootで実行。30分くらいして再起動したらもう使えるようにはなっています。以前こんなの作りましたが、格段に進化しています。
WEBサーバーはnginx+unicornで動くようにしています。あと、すぐW○rdPressなんかをインストールできるように、PHPもさらっとインストールしています。気に入らなければコメントアウトするなりしていただければ。。。
動作の前提条件ですが、OS初期インストール時のホスト名は localhost.localdomain にしておいてください。MySQLのrootパスワード変更のところでコケますので。 mysql -N -s -e “select host,user from mysql.user;” からawkでゴニョゴニョしてもよかったのですが面d(略
実行ログは勝手に /root/logs 以下に取られるようにしていますので、scriptコマンド打たなくてもデバッグはできます。あれ、yumとかのプログレスバーでログ汚くなっちゃいますもんね (´・_・`)
所々、意図は汲んでもらえるかと思いますが、CentOS 6と7でOSのバージョンを見て条件分岐してserviceコマンド叩くかsystemctlコマンド叩くかの処理をわけてますが、あまり徹底していませんごめんなさい。
Redmine実践ガイド 理論と実践、事例で学ぶ新しいプロジェクトマネジメント
#!/bin/bash set -uex LANG=C # rootユーザー以外が実行しようとすると異常終了させる [ ! ${USER} = root ] && exit 1 # UNIXアカウント(一般ユーザー)を変数に格納する CREATEUSER=oresama # ベーシック認証のユーザーとパスワードを変数に格納する AUTHUSER=username AUTHPASS=B@S1cAuThP@sSw0rD # Redmine用DB、ユーザーを変数に格納する DBNAME=redminedb DBUSER=redmine DBUSERPW=rEdM1n3P@sSw0Rd # Redmineインストール対象ブランチを決める # 2 = Version2 # 3 = Version3 REDMINEVERSION=3 # Redmineのドキュメントルートを変数に格納する MINEDIR=/var/www/html/redmine # MySQL rootユーザーのパスワードを生成する MYSQLROOTPW=$(cat /dev/urandom | tr -dc '[:alnum:]' | head -c 16) # OSのバージョンを変数に格納する OSVER=$(rpm -qi centos-release | grep ^Version | awk '{print $3}') # 以降の処理をすべてログに残す LOGDIR=${HOME}/logs LOGFILE=${LOGDIR}/$(uname -n)_$(date +%Y%m%d%H%M%S)_$(basename ${0})_${$}.LOG mkdir -p ${LOGDIR} exec >> ${LOGFILE} exec 2>&1 # date # コンソールログイン用のパスワードを生成する TMPPW=$(cat /dev/urandom | tr -dc '[:alnum:]' | head -c 16) # ホスト名を付け替える ## 変数設定 DOMAIN=example.com NODENAME=mine ## ホスト名付け替え export NEWHOSTNAME=${NODENAME}.${DOMAIN} ## ホスト名の恒久的な付け替え hostname ${NEWHOSTNAME} sed -i.orig "/^HOSTNAME/s/\=[[:alnum:].]*/=${NEWHOSTNAME}/" /etc/sysconfig/network # Firewall (IPTABLES) 設定 service iptables stop iptables -P INPUT DROP iptables -P OUTPUT ACCEPT iptables -P FORWARD DROP iptables -A INPUT -i lo -j ACCEPT iptables -I INPUT -p icmp --icmp-type 0 -j ACCEPT iptables -I INPUT -p icmp --icmp-type 8 -j ACCEPT iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A INPUT -p tcp --dport 10022 -j ACCEPT # iptables -A INPUT -s xxx.xxx.xxx.xxx -p tcp --dport 22 -j ACCEPT iptables -A INPUT -s 192.16.0.0/24 -p tcp --dport 22 -j ACCEPT iptables -A INPUT -s 172.16.0.0/16 -p tcp --dport 22 -j ACCEPT iptables -A INPUT -s 10.0.0.0/8 -p tcp --dport 22 -j ACCEPT service iptables save service iptables start chkconfig iptables on # SELinux 無効化 setenforce 0 sed -i.orig 's/enforcing$/disabled/' /etc/selinux/config # sshd 設定 SSHDCONFIG=/etc/ssh/sshd_config cp -p ${SSHDCONFIG} ${SSHDCONFIG}.orig sed -i "/^#Port[[:space:]]22$/a\Port 22" ${SSHDCONFIG} sed -i "/^Port[[:space:]]22$/a\Port 10022" ${SSHDCONFIG} sed -i "/^#GSSAPIAuthentication no/s/#//" ${SSHDCONFIG} sed -i "/^GSSAPIAuthentication yes/s/yes$/no/" ${SSHDCONFIG} sed -i "/^GSSAPICleanupCredentials yes/s/yes$/no/" ${SSHDCONFIG} sed -i "s/#GSSAPIStrictAcceptorCheck yes/GSSAPIStrictAcceptorCheck no/" ${SSHDCONFIG} sed -i "/#GSSAPIKeyExchange no/s/#//" ${SSHDCONFIG} sed -i "s/#UseDNS yes/UseDNS no/" ${SSHDCONFIG} cp -p ${SSHDCONFIG} ${SSHDCONFIG}.TMP awk 'NR==1||prev!=$0;{prev=$0}' ${SSHDCONFIG}.TMP > ${SSHDCONFIG} rm -f ${SSHDCONFIG}.TMP service sshd reload # Group ADD groupadd -g 500 hamada groupadd -g 501 webmaster # User ADD useradd -u 500 -g 500 ${CREATEUSER} echo ${CREATEUSER}:${TMPPW} | tee PASSWD chpasswd < PASSWD mkdir -p /home/${CREATEUSER}/.ssh/ chmod 700 /home/${CREATEUSER}/.ssh/ touch /home/${CREATEUSER}/.ssh/authorized_keys chmod 600 /home/${CREATEUSER}/.ssh/authorized_keys cat << _EOL_ | tee /home/${CREATEUSER}/.ssh/authorized_keys ssh-rsa XXXXXXXX _EOL_ chown -R ${CREATEUSER}. /home/${CREATEUSER}/.ssh/ # PasswordFile Remove rm -f PASSWD # sudoers User Add cat << _EOL_ | tee /etc/sudoers.d/${CREATEUSER} ${CREATEUSER} ALL=(ALL) NOPASSWD: ALL _EOL_ # OpenSSH clients install yum -y install openssh-clients rsync # NTP install yum -y install ntp ntpdate NTPCONF=/etc/ntp.conf [ ! -f ${NTPCONF}.orig ] && cp -p ${NTPCONF}{,.orig} || cp -p ${NTPCONF}{,.$(date +%Y%m%d)00} sed -i "s/restrict default kod nomodify notrap nopeer noquery/restrict default ignore/" ${NTPCONF} sed -i "s/restrict -6 default kod nomodify notrap nopeer noquery/restrict -6 default ignore/" ${NTPCONF} sed -i "/restrict -6 default ignore/a\restrict -6 ntp1.sakura.ad.jp kod nomodify notrap nopeer noquery" ${NTPCONF} sed -i "/restrict -6 default ignore/a\restrict ntp1.sakura.ad.jp kod nomodify notrap nopeer noquery" ${NTPCONF} sed -i "s/server 0.centos.pool.ntp.org/server ntp1.sakura.ad.jp iburst/" ${NTPCONF} sed -i "/server [12].centos.pool.ntp.org/d" ${NTPCONF} chkconfig ntpd on chkconfig ntpdate on # Yum Update yum -y update # epel Repository install if [ ! -f /etc/yum.repos.d/epel.repo ]; then yum -y install epel-release mkdir -p /etc/yum.repos.d/BACKUP/ sed -i.orig "s/enabled=1/enabled=0/" /etc/yum.repos.d/epel.repo mv /etc/yum.repos.d/epel.repo.orig /etc/yum.repos.d/BACKUP/ fi # remi Repository install REMIRPM=http://rpms.famillecollet.com/enterprise/remi-release-6.rpm if [ 0 = $(yum list installed | grep epel-release > /dev/null 2>&1) ]; then yum -y install ${REMIRPM} else yum -y install epel-release mkdir -p /etc/yum.repos.d/BACKUP/ sed -i.$(date +%Y%m%d)00 "s/enabled=1/enabled=0/" /etc/yum.repos.d/epel.repo mv /etc/yum.repos.d/epel.repo.$(date +%Y%m%d)00 /etc/yum.repos.d/BACKUP/ yum -y install ${REMIRPM} fi # perl modules install yum -y install \ perl \ perl-CGI \ perl-Cache-Memcached \ perl-Class-Singleton \ perl-Compress-Raw-Zlib \ perl-Compress-Zlib \ perl-DBD-Pg \ perl-DBI \ perl-Date-Manip \ perl-DateTime \ perl-Digest-HMAC \ perl-Digest-SHA1 \ perl-Email-Date-Format \ perl-File-Copy-Recursive \ perl-IO-Compress-Base \ perl-IO-Compress-Zlib \ perl-IO-Socket-INET6 \ perl-List-MoreUtils \ perl-MIME-Lite \ perl-MIME-Types \ perl-MailTools \ perl-Module-Pluggable \ perl-Net-DNS \ perl-Net-SSLeay \ perl-Params-Validate \ perl-Pod-Escapes \ perl-Pod-Simple \ perl-Socket6 \ perl-String-CRC32 \ perl-Taint-Runtime \ perl-Time-HiRes \ perl-TimeDate \ perl-XML-DOM \ perl-XML-LibXML \ perl-XML-NamespaceSupport \ perl-XML-RegExp \ perl-XML-SAX \ perl-YAML-Syck \ perl-libs \ perl-version yum --enablerepo=epel -y install \ perl-Cache-Cache \ perl-Carp-Always \ perl-Crypt-DES \ perl-FCGI \ perl-HTML-Template \ perl-IO-Multiplex \ perl-IPC-ShareLite \ perl-Log-Dispatch \ perl-Log-Dispatch-FileRotate \ perl-Log-Log4perl \ perl-Mail-Sender \ perl-Mail-Sendmail \ perl-Net-CIDR \ perl-Net-SNMP \ perl-Net-Server # iptables穴開け (TCP80) if [ 6 = ${OSVER} ]; then iptables -A INPUT -p tcp --dport 80 -j ACCEPT service iptables save fi if [ 7 = ${OSVER} ]; then if [ 3 = $(systemctl status firewalld.service > /dev/null ; echo $?) ]; then systemctl start firewalld.service fi systemctl enable firewalld.service firewall-cmd --zone=public --add-service http firewall-cmd --zone=public --add-service http --permanent fi # nginxリポジトリインストール NGINXREPO=http://nginx.org/packages/centos/${OSVER}/noarch/RPMS/nginx-release-centos-${OSVER}-0.el${OSVER}.ngx.noarch.rpm yum -y install ${NGINXREPO} sed -i.orig 's/centos/mainline\/centos/' /etc/yum.repos.d/nginx.repo # nginxインストール yum -y install nginx # basic認証ファイル作成 PASSWORDFILE=/etc/nginx/htpasswd echo "${AUTHUSER}:$(openssl passwd -apr1 ${AUTHPASS})" > ${PASSWORDFILE} # nginx settings sed -i.orig "s/worker_processes[[:space:]]\+[0-9]\+/worker_processes auto/" /etc/nginx/nginx.conf cat << _EOL_ | tee /etc/nginx/conf.d/vhost.conf server { listen 80; server_name $(hostname); location / { root /var/www/html; index index.html index.htm; } location ^~ /munin-cgi/munin-cgi-graph/ { access_log off; fastcgi_split_path_info ^(/munin-cgi/munin-cgi-graph)(.*); fastcgi_param PATH_INFO \$fastcgi_path_info; fastcgi_pass unix:/var/run/munin/munin-cgi-graph.sock; include fastcgi_params; } location /munin/static/ { alias /etc/munin/static/; } location /munin/ { auth_basic "admin only"; auth_basic_user_file ${PASSWORDFILE}; fastcgi_split_path_info ^(/munin)(.*); fastcgi_param PATH_INFO \$fastcgi_path_info; fastcgi_pass unix:/var/run/munin/munin-cgi-html.sock; include fastcgi_params; } location /redmine { proxy_redirect off; proxy_set_header X-Real-IP \$remote_addr; proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; proxy_set_header Host \$http_host; proxy_connect_timeout 60; proxy_read_timeout 60; proxy_send_timeout 600; proxy_pass http://127.0.0.1:5001; } } _EOL_ # nginx start PROGNAME=nginx if [ 6 = ${OSVER} ]; then service ${PROGNAME} start ; chkconfig ${PROGNAME} on fi if [ 7 = ${OSVER} ]; then systemctl start ${PROGNAME} ; systemctl enable ${PROGNAME} fi # PHPインストール yum --enablerepo=remi -y install gd-last yum --enablerepo=remi-php56 -y install \ php-cli \ php-common \ php-fpm \ php-mbstring \ php-mysqlnd \ php-opcache \ php-pdo \ php-pear \ php-pecl-apcu \ php-pecl-jsonc \ php-pecl-zip \ php-xml \ php-xmlrpc \ php-gd # php.ini settings sed -i.orig "s/;date.timezone =/date.timezone = Asia\/Tokyo/" /etc/php.ini # php-fpm settings cp -p /etc/php-fpm.d/www.conf{,.orig} sed -i 's/^user = apache/;user = apache\nuser = nginx/' /etc/php-fpm.d/www.conf sed -i 's/^group = apache/;group = apache\ngroup = nginx/' /etc/php-fpm.d/www.conf chgrp nginx /var/lib/php/{session,wsdlcache} # php-fpm start PROGNAME=php-fpm if [ 6 = ${OSVER} ]; then service ${PROGNAME} start ; chkconfig ${PROGNAME} on fi if [ 7 = ${OSVER} ]; then systemctl start ${PROGNAME} ; systemctl enable ${PROGNAME} fi # munin install yum --enablerepo=epel -y install munin munin-node munin-nginx munin-common # munin.conf edit MUNINCONF=/etc/munin/munin.conf cp -p ${MUNINCONF}{,.orig} sed -i "s/^#dbdir/dbdir/" ${MUNINCONF} sed -i "s/^#htmldir/htmldir/" ${MUNINCONF} sed -i "s/^#logdir/logdir/" ${MUNINCONF} sed -i "s/^#rundir/rundir/" ${MUNINCONF} sed -i "/^graph_strategy/s/cron/cgi/" ${MUNINCONF} sed -i "/^html_strategy/s/cron/cgi/" ${MUNINCONF} # nginx munin config move mkdir -p /etc/nginx/conf.d/BACKUP/ cd /etc/nginx/conf.d for A in $(ls | egrep -v '(BACKUP|vhost)') do mv $A BACKUP/ done cd # munin-fcgi-graph edit mkdir -p /etc/init.d/BACKUP/ cp -p /etc/init.d/munin-fcgi-graph /etc/init.d/BACKUP/ sed -i "s/fcgi-graph.sock/munin-cgi-graph.sock/g" /etc/init.d/munin-fcgi-graph # munin-fcgi-html edit mkdir -p /etc/init.d/BACKUP/ cp -p /etc/init.d/munin-fcgi-html /etc/init.d/BACKUP/ sed -i "s/fcgi-html.sock/munin-cgi-html.sock/g" /etc/init.d/munin-fcgi-html # munin services start MUNINPROGS=() MUNINPROGS=("munin-fcgi-graph" "munin-fcgi-html" "munin-node") for PROGNAME in ${MUNINPROGS[@]} do if [ 6 = ${OSVER} ]; then chkconfig --add ${PROGNAME} ; chkconfig ${PROGNAME} on ; service ${PROGNAME} start fi if [ 7 = ${OSVER} ]; then systemctl start ${PROGNAME} ; systemctl enable ${PROGNAME} fi done # Redmine Install ## 開発ツールインストール yum -y install gcc libxml2 libxslt libxml2-devel libxslt-devel ## ruby 2.2.2のrpmパッケージをダウンロードする curl -LO https://github.com/feedforce/ruby-rpm/releases/download/2.2.2/ruby-2.2.2-1.el6.x86_64.rpm yum -y localinstall ruby-2.2.2-1.el6.x86_64.rpm ## yum.conf でrubyをexcludeする cp -p /etc/yum.conf{,.orig} cat /etc/yum.conf.orig | grep -v "#" | grep . > /etc/yum.conf echo "exclude=ruby*" >> /etc/yum.conf cat /etc/yum.conf.orig | egrep -v '^([[:alnum:]\[])' >> /etc/yum.conf ## ImageMagick , Header files and Japanese Font install yum -y install ImageMagick ImageMagick-devel ipa-pgothic-fonts ## MySQL Server install yum -y install http://dev.mysql.com/get/mysql-community-release-el${OSVER}-5.noarch.rpm yum -y install mysql-community-server mysql-community-devel ## MySQL起動 PROGNAME=mysqld if [ 6 = ${OSVER} ]; then service ${PROGNAME} start ; chkconfig --add ${PROGNAME} ; chkconfig ${PROGNAME} on fi if [ 7 = ${OSVER} ]; then systemctl start ${PROGNAME} ; systemctl enable ${PROGNAME} fi ## MySQL rootユーザーのパスワード設定 mysql -u root -e "SET PASSWORD FOR root@localhost=PASSWORD('${MYSQLROOTPW}');" echo [client] | tee ${HOME}/.my.cnf echo user=root | tee -a ${HOME}/.my.cnf echo password=\"${MYSQLROOTPW}\" | tee -a ${HOME}/.my.cnf #mysql -e "SET PASSWORD FOR root@\"${HOSTNAME}\"=PASSWORD('${MYSQLROOTPW}');" mysql -e "SET PASSWORD FOR root@\"${NEWHOSTNAME}\"=PASSWORD('${MYSQLROOTPW}');" mysql -e "SET PASSWORD FOR root@127.0.0.1=PASSWORD('${MYSQLROOTPW}');" mysql -e "SET PASSWORD FOR root@\"::1\"=PASSWORD('${MYSQLROOTPW}');" mysql -e "delete from mysql.user where user='';" mysql -e 'FLUSH PRIVILEGES;' ## Redmine用DB作成 mysql -u root -e "create database ${DBNAME} character set utf8;" ## Redmine用ユーザー作成 mysql -u root -e "GRANT ALL PRIVILEGES on ${DBNAME}.* to ${DBUSER}@localhost identified by \"${DBUSERPW}\";" mysql -e 'FLUSH PRIVILEGES;' ## bundler install gem install bundler --no-rdoc --no-ri ## Redmine Install mkdir -p ${HOME}/src/redmine cd ${HOME}/src/redmine LINKURI=http://www.redmine.org/projects/redmine/wiki/Download curl -O $(curl -s ${LINKURI} | \ grep -i href | \ grep tar.gz | \ grep "redmine-${REDMINEVERSION}" | \ sed -e "s/<li>//g;s/<a href=//g;s/<\/[[:alnum:]]*>//g;s/<code>//g;s/\"//g;s/>[[:alnum:]-]*[0-9.]*.tar.gz//g;s/[()]//g" | \ awk '{print "http://www.redmine.org"$1}') ## md5sum値チェック MD5SUM=$(curl -s http://www.redmine.org/projects/redmine/wiki/Download | grep -i href | grep tar.gz | grep "redmine-${REDMINEVERSION}" | sed -e "s/<li>//g;s/<a href=//g;s/<\/[[:alnum:]]*>//g;s/<code>//g;s/\"//g;s/>[[:alnum:]-]*[0-9.]*.tar.gz//g;s/[()]//g" | awk '{print $NF}') [ ! ${MD5SUM} = $(md5sum redmine-3.0.3.tar.gz | awk '{print $1}') ] && exit 1 ## Redmine解凍 REDMINE=$(ls | grep redmine-${REDMINEVERSION} | sed -e "s/.tar.gz//") tar xzf ${REDMINE}.tar.gz mv ${REDMINE} ${MINEDIR} # Redmine Settings cd ${MINEDIR}/config for A in production: adapter: database: host: username: password: encoding: do cat database.yml.example | \ egrep -m 1 $A done | \ sed -e "/database:/s/redmine/${DBNAME}/" | \ sed -e "/username:/s/root/${DBUSER}/" | \ sed -e "/password:/s/\"\"/${DBUSERPW}/" > database.yml cat << _EOL_ | tee /var/www/html/redmine/config/configuration.yml production: email_delivery: delivery_method: :smtp smtp_settings: address: ${NODENAME} port: 25 domain: ${DOMAIN} rmagick_font_path: /usr/share/fonts/ipa-pgothic/ipagp.ttf _EOL_ cd ${MINEDIR}/ gem install json -v '1.8.3' gem install nokogiri -v '1.6.6.2' -- --use-system-libraries gem install mysql2 -v '0.3.18' bundle install --without development test bundle exec rake generate_secret_token RAILS_ENV=production bundle exec rake db:migrate echo "gem 'unicorn'" > Gemfile.local bundle install cp -p config.ru config.ru.orig cat << _EOL_ | tee config.ru require ::File.expand_path('../config/environment', __FILE__) if ENV['RAILS_RELATIVE_URL_ROOT'] map ENV['RAILS_RELATIVE_URL_ROOT'] do run RedmineApp::Application end else run RedmineApp::Application end _EOL_ echo "working_directory '${MINEDIR}'" > config/unicorn.rb chown -R nginx:hamada ${MINEDIR}/ chmod -R g+w ${MINEDIR}/ touch /etc/init.d/redmine chmod 700 /etc/init.d/redmine cat << '_EOL_' | tee /etc/init.d/redmine #!/bin/bash # REDMINE ### BEGIN INIT INFO # Provides: redmine # Required-Start: $local_fs $remote_fs $network $syslog redis-server # Required-Stop: $local_fs $remote_fs $network $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Redmine # Description: Redmine # chkconfig: - 75 25 ### END INIT INFO export PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin APP_NAME=redmine APP_ROOT=_MINEDIR_ APP_PATH="/redmine" CONFIGS="$APP_ROOT/config/unicorn.rb" PID="$APP_ROOT/tmp/pids/unicorn.pid" ENV=production PORT=5001 UNICORN_OPTS="-D -E $ENV -c $CONFIGS --path $APP_PATH -p $PORT" start() { if [ -e $PID ]; then echo "$APP_NAME already started"; exit 1; fi echo "start $APP_NAME"; cd $APP_ROOT bundle exec unicorn_rails $UNICORN_OPTS } stop() { if [ ! -e $PID ]; then echo "$APP_NAME not started"; exit 1; fi echo "stop $APP_NAME"; kill -QUIT `cat ${PID}` rm -f $PID } force_stop() { if [ ! -e $PID ]; then echo "$APP_NAME not started"; exit 1; fi echo "stop $APP_NAME"; kill -TERM `cat ${PID}` rm -f $PID } reload() { if [ ! -e $PID ]; then echo "$APP_NAME not started"; start exit 0; fi echo "reload $APP_NAME"; kill -HUP `cat ${PID}` } restart() { stop start } case "$1" in start) start ;; stop) stop ;; force-stop) force_stop ;; reload) reload ;; restart) restart ;; *) echo "Usage: $(basename $0) [start|stop|force-stop|reload|restart]" ;; esac exit _EOL_ sed -i "s/_MINEDIR_/$(echo ${MINEDIR} | sed -e 's/\//\\\//g')/g" /etc/init.d/redmine chkconfig --add redmine # date # reboot
スクリーンショット画像などを整理する際、連番のファイル名を手動でリネームするのは骨が折れますよね?ダメ写真を削除したりして、抜け番が生じることもあるかと思います。しかし、bashのforループを使えばすんなりリネームすることができるので、是非試してみてください。まずはファイルの一覧を見てみましょう。ご覧のように、ファイル名はすべて接頭語が「OS_INSTALL_」で、連番は4桁の数字になっています。
$ ls OS_INSTALL_0001.jpg OS_INSTALL_0019.jpg OS_INSTALL_0039.jpg OS_INSTALL_0058.jpg OS_INSTALL_0078.jpg OS_INSTALL_0096.jpg OS_INSTALL_0002.jpg OS_INSTALL_0020.jpg OS_INSTALL_0040.jpg OS_INSTALL_0059.jpg OS_INSTALL_0079.jpg OS_INSTALL_0097.jpg OS_INSTALL_0003.jpg OS_INSTALL_0021.jpg OS_INSTALL_0041.jpg OS_INSTALL_0060.jpg OS_INSTALL_0080.jpg OS_INSTALL_0098.jpg OS_INSTALL_0004.jpg OS_INSTALL_0022.jpg OS_INSTALL_0042.jpg OS_INSTALL_0061.jpg OS_INSTALL_0081.jpg OS_INSTALL_0099.jpg OS_INSTALL_0005.jpg OS_INSTALL_0024.jpg OS_INSTALL_0043.jpg OS_INSTALL_0062.jpg OS_INSTALL_0082.jpg OS_INSTALL_0100.jpg OS_INSTALL_0006.jpg OS_INSTALL_0025.jpg OS_INSTALL_0044.jpg OS_INSTALL_0064.jpg OS_INSTALL_0083.jpg OS_INSTALL_0101.jpg OS_INSTALL_0007.jpg OS_INSTALL_0026.jpg OS_INSTALL_0045.jpg OS_INSTALL_0065.jpg OS_INSTALL_0084.jpg OS_INSTALL_0102.jpg OS_INSTALL_0008.jpg OS_INSTALL_0027.jpg OS_INSTALL_0046.jpg OS_INSTALL_0066.jpg OS_INSTALL_0085.jpg OS_INSTALL_0103.jpg OS_INSTALL_0009.jpg OS_INSTALL_0028.jpg OS_INSTALL_0047.jpg OS_INSTALL_0067.jpg OS_INSTALL_0086.jpg OS_INSTALL_0104.jpg OS_INSTALL_0010.jpg OS_INSTALL_0030.jpg OS_INSTALL_0049.jpg OS_INSTALL_0068.jpg OS_INSTALL_0087.jpg OS_INSTALL_0105.jpg OS_INSTALL_0011.jpg OS_INSTALL_0031.jpg OS_INSTALL_0050.jpg OS_INSTALL_0070.jpg OS_INSTALL_0088.jpg OS_INSTALL_0106.jpg OS_INSTALL_0012.jpg OS_INSTALL_0032.jpg OS_INSTALL_0051.jpg OS_INSTALL_0071.jpg OS_INSTALL_0089.jpg OS_INSTALL_0107.jpg OS_INSTALL_0013.jpg OS_INSTALL_0033.jpg OS_INSTALL_0052.jpg OS_INSTALL_0072.jpg OS_INSTALL_0090.jpg OS_INSTALL_0108.jpg OS_INSTALL_0014.jpg OS_INSTALL_0034.jpg OS_INSTALL_0053.jpg OS_INSTALL_0073.jpg OS_INSTALL_0091.jpg OS_INSTALL_0109.jpg OS_INSTALL_0015.jpg OS_INSTALL_0035.jpg OS_INSTALL_0054.jpg OS_INSTALL_0074.jpg OS_INSTALL_0092.jpg OS_INSTALL_0111.jpg OS_INSTALL_0016.jpg OS_INSTALL_0036.jpg OS_INSTALL_0055.jpg OS_INSTALL_0075.jpg OS_INSTALL_0093.jpg OS_INSTALL_0112.jpg OS_INSTALL_0017.jpg OS_INSTALL_0037.jpg OS_INSTALL_0056.jpg OS_INSTALL_0076.jpg OS_INSTALL_0094.jpg OS_INSTALL_0113.jpg OS_INSTALL_0018.jpg OS_INSTALL_0038.jpg OS_INSTALL_0057.jpg OS_INSTALL_0077.jpg OS_INSTALL_0095.jpg
数が多くてわかりにくいかと思いますので、抜け番があるあたりを見てみましょう。以下のように、23番目のファイルが抜けていることがわかります。
$ ls | egrep '(002[0-5])' OS_INSTALL_0020.jpg OS_INSTALL_0021.jpg OS_INSTALL_0022.jpg OS_INSTALL_0024.jpg OS_INSTALL_0025.jpg
全体でどれだけ抜けがあるのかは ls コマンドをパイプで wc に渡してみるとわかります。
$ ls | tail -n 1 ; ls | wc -l OS_INSTALL_0113.jpg 107
ご覧のように、連番のファイルが113まであるのに対してファイルの数は107です。
ファイル名に抜け番があるということは、先ほどの例のように、ファイル名に含まれる番号の最大値よりも実際のファイル数のほうが少ないわけです。これを自動でリネームするということは、抜け番の次にある番号がその抜け番号を埋める、つまりファイル名がデクリメントされていくというわけです。まずはリネームの一部を見てみましょう。なお、このコマンドを実行した時点ではまだリネームされません。
$ for A in $(ls) ; do echo $A ; done | cat -n | awk '{print "mv",$2,"OS_INSTALL_"$1".jpg"}' | egrep '(002[0-5])' mv OS_INSTALL_0020.jpg OS_INSTALL_20.jpg mv OS_INSTALL_0021.jpg OS_INSTALL_21.jpg mv OS_INSTALL_0022.jpg OS_INSTALL_22.jpg mv OS_INSTALL_0024.jpg OS_INSTALL_23.jpg mv OS_INSTALL_0025.jpg OS_INSTALL_24.jpg
桁数を無視してよいなら、awkの次のパイプに sh を渡してあげて実行しておしまいです。しかしこれでは折角元のファイルがゼロパディングでソートできているのに、台無しになってしまいます。
桁数を揃えたままリネームするなら、以下のようにするとよいでしょう。なお、今回の例でもコマンド実行時にはまだリネームされません。動作を確認するため、 mv コマンドの前に echo とタイプすることで「やっちまった!」を防いでいます。確認後OKなら echo を削るか、forループが終わったあと、つまり done の後にパイプで sh コマンドに渡してあげましょう。私はいつも done のあとに sh に渡しています。その方がOPミスで間違う可能性が低いからです。
$ declare -i num ; num=1 ; for FILES in $(ls) ; do echo mv $FILES $(printf "OS-INSTALL_%04d.jpg\n" $num) ; num=$num+1 ; done | egrep '(002[0-5])' mv OS_INSTALL_0020.jpg OS-INSTALL_0020.jpg mv OS_INSTALL_0021.jpg OS-INSTALL_0021.jpg mv OS_INSTALL_0022.jpg OS-INSTALL_0022.jpg mv OS_INSTALL_0024.jpg OS-INSTALL_0023.jpg mv OS_INSTALL_0025.jpg OS-INSTALL_0024.jpg mv OS_INSTALL_0026.jpg OS-INSTALL_0025.jpg
上記の例のように、抜け番が埋められているのがおわかりいただけるかと思います。ただし、ちょっと工夫をしています。
最初に変数numを指定する前に、 declare コマンドで、「変数 num は数値型ですぜ」と宣言しています。これがあるおかげで、forループの最後に num 変数 に 1 を足して、ループが続く限りカウントアップされます。
続いて、ファイル名ですが、最初のアンダーバーをハイフンに置換しています。mvの前にif文でファイルの有無を見るほうが本当はよいのですが、まずはリネームできること優先でやっています。リネーム後のファイル名は printf で4桁の数字のファイル名を生成しています。
$ declare -i num ; num=1 ; for FILES in $(ls) ; do echo mv $FILES $(printf "OS-INSTALL_%04d.jpg\n" $num) ; num=$num+1 ; done | sh $ ls OS-INSTALL_0001.jpg OS-INSTALL_0019.jpg OS-INSTALL_0037.jpg OS-INSTALL_0055.jpg OS-INSTALL_0073.jpg OS-INSTALL_0091.jpg OS-INSTALL_0002.jpg OS-INSTALL_0020.jpg OS-INSTALL_0038.jpg OS-INSTALL_0056.jpg OS-INSTALL_0074.jpg OS-INSTALL_0092.jpg OS-INSTALL_0003.jpg OS-INSTALL_0021.jpg OS-INSTALL_0039.jpg OS-INSTALL_0057.jpg OS-INSTALL_0075.jpg OS-INSTALL_0093.jpg OS-INSTALL_0004.jpg OS-INSTALL_0022.jpg OS-INSTALL_0040.jpg OS-INSTALL_0058.jpg OS-INSTALL_0076.jpg OS-INSTALL_0094.jpg OS-INSTALL_0005.jpg OS-INSTALL_0023.jpg OS-INSTALL_0041.jpg OS-INSTALL_0059.jpg OS-INSTALL_0077.jpg OS-INSTALL_0095.jpg OS-INSTALL_0006.jpg OS-INSTALL_0024.jpg OS-INSTALL_0042.jpg OS-INSTALL_0060.jpg OS-INSTALL_0078.jpg OS-INSTALL_0096.jpg OS-INSTALL_0007.jpg OS-INSTALL_0025.jpg OS-INSTALL_0043.jpg OS-INSTALL_0061.jpg OS-INSTALL_0079.jpg OS-INSTALL_0097.jpg OS-INSTALL_0008.jpg OS-INSTALL_0026.jpg OS-INSTALL_0044.jpg OS-INSTALL_0062.jpg OS-INSTALL_0080.jpg OS-INSTALL_0098.jpg OS-INSTALL_0009.jpg OS-INSTALL_0027.jpg OS-INSTALL_0045.jpg OS-INSTALL_0063.jpg OS-INSTALL_0081.jpg OS-INSTALL_0099.jpg OS-INSTALL_0010.jpg OS-INSTALL_0028.jpg OS-INSTALL_0046.jpg OS-INSTALL_0064.jpg OS-INSTALL_0082.jpg OS-INSTALL_0100.jpg OS-INSTALL_0011.jpg OS-INSTALL_0029.jpg OS-INSTALL_0047.jpg OS-INSTALL_0065.jpg OS-INSTALL_0083.jpg OS-INSTALL_0101.jpg OS-INSTALL_0012.jpg OS-INSTALL_0030.jpg OS-INSTALL_0048.jpg OS-INSTALL_0066.jpg OS-INSTALL_0084.jpg OS-INSTALL_0102.jpg OS-INSTALL_0013.jpg OS-INSTALL_0031.jpg OS-INSTALL_0049.jpg OS-INSTALL_0067.jpg OS-INSTALL_0085.jpg OS-INSTALL_0103.jpg OS-INSTALL_0014.jpg OS-INSTALL_0032.jpg OS-INSTALL_0050.jpg OS-INSTALL_0068.jpg OS-INSTALL_0086.jpg OS-INSTALL_0104.jpg OS-INSTALL_0015.jpg OS-INSTALL_0033.jpg OS-INSTALL_0051.jpg OS-INSTALL_0069.jpg OS-INSTALL_0087.jpg OS-INSTALL_0105.jpg OS-INSTALL_0016.jpg OS-INSTALL_0034.jpg OS-INSTALL_0052.jpg OS-INSTALL_0070.jpg OS-INSTALL_0088.jpg OS-INSTALL_0106.jpg OS-INSTALL_0017.jpg OS-INSTALL_0035.jpg OS-INSTALL_0053.jpg OS-INSTALL_0071.jpg OS-INSTALL_0089.jpg OS-INSTALL_0107.jpg OS-INSTALL_0018.jpg OS-INSTALL_0036.jpg OS-INSTALL_0054.jpg OS-INSTALL_0072.jpg OS-INSTALL_0090.jpg
とりあえず先ほどの例ではリネームできましたが、ファイル名にハイフンが入ったままで気持ちが悪いです。またリネームしてあげてもよいのですが、実行するコマンドは少ないに越したことがありません。今度はtestコマンドをつけて、リネーム後のファイルがなければという条件式にマッチした時だけ、抜け番を埋めるようにします。勿論わざわざアンダーバーをハイフンにせず実行できます。というわけでまたまたechoで確認です。
$ declare -i num ; num=1 ; for FILES in $(ls) ; do echo "[ ! -f $(printf "OS_INSTALL_%04d.jpg\n" $num) ] && mv $FILES $(printf "OS_INSTALL_%04d.jpg\n" $num)" ; num=$num+1 ; done | egrep '(002[0-5])' [ ! -f OS_INSTALL_0020.jpg ] && mv OS_INSTALL_0020.jpg OS_INSTALL_0020.jpg [ ! -f OS_INSTALL_0021.jpg ] && mv OS_INSTALL_0021.jpg OS_INSTALL_0021.jpg [ ! -f OS_INSTALL_0022.jpg ] && mv OS_INSTALL_0022.jpg OS_INSTALL_0022.jpg [ ! -f OS_INSTALL_0023.jpg ] && mv OS_INSTALL_0024.jpg OS_INSTALL_0023.jpg [ ! -f OS_INSTALL_0024.jpg ] && mv OS_INSTALL_0025.jpg OS_INSTALL_0024.jpg [ ! -f OS_INSTALL_0025.jpg ] && mv OS_INSTALL_0026.jpg OS_INSTALL_0025.jpg
コマンドの構文が期待どおりなので、実行してみましょう。なお、shコマンドには -x をつけると処理の中身を見ることができます。
$ declare -i num ; num=1 ; for FILES in $(ls) ; do echo "[ ! -f $(printf "OS_INSTALL_%04d.jpg\n" $num) ] && mv $FILES $(printf "OS_INSTALL_%04d.jpg\n" $num)" ; num=$num+1 ; done | sh -x + '[' '!' -f OS_INSTALL_0001.jpg ']' + '[' '!' -f OS_INSTALL_0002.jpg ']' + '[' '!' -f OS_INSTALL_0003.jpg ']' + '[' '!' -f OS_INSTALL_0004.jpg ']' + '[' '!' -f OS_INSTALL_0005.jpg ']' + '[' '!' -f OS_INSTALL_0006.jpg ']' + '[' '!' -f OS_INSTALL_0007.jpg ']' + '[' '!' -f OS_INSTALL_0008.jpg ']' + '[' '!' -f OS_INSTALL_0009.jpg ']' + '[' '!' -f OS_INSTALL_0010.jpg ']' + '[' '!' -f OS_INSTALL_0011.jpg ']' + '[' '!' -f OS_INSTALL_0012.jpg ']' + '[' '!' -f OS_INSTALL_0013.jpg ']' + '[' '!' -f OS_INSTALL_0014.jpg ']' + '[' '!' -f OS_INSTALL_0015.jpg ']' + '[' '!' -f OS_INSTALL_0016.jpg ']' + '[' '!' -f OS_INSTALL_0017.jpg ']' + '[' '!' -f OS_INSTALL_0018.jpg ']' + '[' '!' -f OS_INSTALL_0019.jpg ']' + '[' '!' -f OS_INSTALL_0020.jpg ']' + '[' '!' -f OS_INSTALL_0021.jpg ']' + '[' '!' -f OS_INSTALL_0022.jpg ']' + '[' '!' -f OS_INSTALL_0023.jpg ']' + mv OS_INSTALL_0024.jpg OS_INSTALL_0023.jpg + '[' '!' -f OS_INSTALL_0024.jpg ']' + mv OS_INSTALL_0025.jpg OS_INSTALL_0024.jpg + '[' '!' -f OS_INSTALL_0025.jpg ']' + mv OS_INSTALL_0026.jpg OS_INSTALL_0025.jpg + '[' '!' -f OS_INSTALL_0026.jpg ']' + mv OS_INSTALL_0027.jpg OS_INSTALL_0026.jpg + '[' '!' -f OS_INSTALL_0027.jpg ']' + mv OS_INSTALL_0028.jpg OS_INSTALL_0027.jpg + '[' '!' -f OS_INSTALL_0028.jpg ']' + mv OS_INSTALL_0030.jpg OS_INSTALL_0028.jpg + '[' '!' -f OS_INSTALL_0029.jpg ']' + mv OS_INSTALL_0031.jpg OS_INSTALL_0029.jpg + '[' '!' -f OS_INSTALL_0030.jpg ']' + mv OS_INSTALL_0032.jpg OS_INSTALL_0030.jpg + '[' '!' -f OS_INSTALL_0031.jpg ']' + mv OS_INSTALL_0033.jpg OS_INSTALL_0031.jpg + '[' '!' -f OS_INSTALL_0032.jpg ']' + mv OS_INSTALL_0034.jpg OS_INSTALL_0032.jpg + '[' '!' -f OS_INSTALL_0033.jpg ']' + mv OS_INSTALL_0035.jpg OS_INSTALL_0033.jpg + '[' '!' -f OS_INSTALL_0034.jpg ']' + mv OS_INSTALL_0036.jpg OS_INSTALL_0034.jpg + '[' '!' -f OS_INSTALL_0035.jpg ']' + mv OS_INSTALL_0037.jpg OS_INSTALL_0035.jpg + '[' '!' -f OS_INSTALL_0036.jpg ']' + mv OS_INSTALL_0038.jpg OS_INSTALL_0036.jpg + '[' '!' -f OS_INSTALL_0037.jpg ']' + mv OS_INSTALL_0039.jpg OS_INSTALL_0037.jpg + '[' '!' -f OS_INSTALL_0038.jpg ']' + mv OS_INSTALL_0040.jpg OS_INSTALL_0038.jpg + '[' '!' -f OS_INSTALL_0039.jpg ']' + mv OS_INSTALL_0041.jpg OS_INSTALL_0039.jpg + '[' '!' -f OS_INSTALL_0040.jpg ']' + mv OS_INSTALL_0042.jpg OS_INSTALL_0040.jpg + '[' '!' -f OS_INSTALL_0041.jpg ']' + mv OS_INSTALL_0043.jpg OS_INSTALL_0041.jpg + '[' '!' -f OS_INSTALL_0042.jpg ']' + mv OS_INSTALL_0044.jpg OS_INSTALL_0042.jpg + '[' '!' -f OS_INSTALL_0043.jpg ']' + mv OS_INSTALL_0045.jpg OS_INSTALL_0043.jpg + '[' '!' -f OS_INSTALL_0044.jpg ']' + mv OS_INSTALL_0046.jpg OS_INSTALL_0044.jpg + '[' '!' -f OS_INSTALL_0045.jpg ']' + mv OS_INSTALL_0047.jpg OS_INSTALL_0045.jpg + '[' '!' -f OS_INSTALL_0046.jpg ']' + mv OS_INSTALL_0049.jpg OS_INSTALL_0046.jpg + '[' '!' -f OS_INSTALL_0047.jpg ']' + mv OS_INSTALL_0050.jpg OS_INSTALL_0047.jpg + '[' '!' -f OS_INSTALL_0048.jpg ']' + mv OS_INSTALL_0051.jpg OS_INSTALL_0048.jpg + '[' '!' -f OS_INSTALL_0049.jpg ']' + mv OS_INSTALL_0052.jpg OS_INSTALL_0049.jpg + '[' '!' -f OS_INSTALL_0050.jpg ']' + mv OS_INSTALL_0053.jpg OS_INSTALL_0050.jpg + '[' '!' -f OS_INSTALL_0051.jpg ']' + mv OS_INSTALL_0054.jpg OS_INSTALL_0051.jpg + '[' '!' -f OS_INSTALL_0052.jpg ']' + mv OS_INSTALL_0055.jpg OS_INSTALL_0052.jpg + '[' '!' -f OS_INSTALL_0053.jpg ']' + mv OS_INSTALL_0056.jpg OS_INSTALL_0053.jpg + '[' '!' -f OS_INSTALL_0054.jpg ']' + mv OS_INSTALL_0057.jpg OS_INSTALL_0054.jpg + '[' '!' -f OS_INSTALL_0055.jpg ']' + mv OS_INSTALL_0058.jpg OS_INSTALL_0055.jpg + '[' '!' -f OS_INSTALL_0056.jpg ']' + mv OS_INSTALL_0059.jpg OS_INSTALL_0056.jpg + '[' '!' -f OS_INSTALL_0057.jpg ']' + mv OS_INSTALL_0060.jpg OS_INSTALL_0057.jpg + '[' '!' -f OS_INSTALL_0058.jpg ']' + mv OS_INSTALL_0061.jpg OS_INSTALL_0058.jpg + '[' '!' -f OS_INSTALL_0059.jpg ']' + mv OS_INSTALL_0062.jpg OS_INSTALL_0059.jpg + '[' '!' -f OS_INSTALL_0060.jpg ']' + mv OS_INSTALL_0064.jpg OS_INSTALL_0060.jpg + '[' '!' -f OS_INSTALL_0061.jpg ']' + mv OS_INSTALL_0065.jpg OS_INSTALL_0061.jpg + '[' '!' -f OS_INSTALL_0062.jpg ']' + mv OS_INSTALL_0066.jpg OS_INSTALL_0062.jpg + '[' '!' -f OS_INSTALL_0063.jpg ']' + mv OS_INSTALL_0067.jpg OS_INSTALL_0063.jpg + '[' '!' -f OS_INSTALL_0064.jpg ']' + mv OS_INSTALL_0068.jpg OS_INSTALL_0064.jpg + '[' '!' -f OS_INSTALL_0065.jpg ']' + mv OS_INSTALL_0070.jpg OS_INSTALL_0065.jpg + '[' '!' -f OS_INSTALL_0066.jpg ']' + mv OS_INSTALL_0071.jpg OS_INSTALL_0066.jpg + '[' '!' -f OS_INSTALL_0067.jpg ']' + mv OS_INSTALL_0072.jpg OS_INSTALL_0067.jpg + '[' '!' -f OS_INSTALL_0068.jpg ']' + mv OS_INSTALL_0073.jpg OS_INSTALL_0068.jpg + '[' '!' -f OS_INSTALL_0069.jpg ']' + mv OS_INSTALL_0074.jpg OS_INSTALL_0069.jpg + '[' '!' -f OS_INSTALL_0070.jpg ']' + mv OS_INSTALL_0075.jpg OS_INSTALL_0070.jpg + '[' '!' -f OS_INSTALL_0071.jpg ']' + mv OS_INSTALL_0076.jpg OS_INSTALL_0071.jpg + '[' '!' -f OS_INSTALL_0072.jpg ']' + mv OS_INSTALL_0077.jpg OS_INSTALL_0072.jpg + '[' '!' -f OS_INSTALL_0073.jpg ']' + mv OS_INSTALL_0078.jpg OS_INSTALL_0073.jpg + '[' '!' -f OS_INSTALL_0074.jpg ']' + mv OS_INSTALL_0079.jpg OS_INSTALL_0074.jpg + '[' '!' -f OS_INSTALL_0075.jpg ']' + mv OS_INSTALL_0080.jpg OS_INSTALL_0075.jpg + '[' '!' -f OS_INSTALL_0076.jpg ']' + mv OS_INSTALL_0081.jpg OS_INSTALL_0076.jpg + '[' '!' -f OS_INSTALL_0077.jpg ']' + mv OS_INSTALL_0082.jpg OS_INSTALL_0077.jpg + '[' '!' -f OS_INSTALL_0078.jpg ']' + mv OS_INSTALL_0083.jpg OS_INSTALL_0078.jpg + '[' '!' -f OS_INSTALL_0079.jpg ']' + mv OS_INSTALL_0084.jpg OS_INSTALL_0079.jpg + '[' '!' -f OS_INSTALL_0080.jpg ']' + mv OS_INSTALL_0085.jpg OS_INSTALL_0080.jpg + '[' '!' -f OS_INSTALL_0081.jpg ']' + mv OS_INSTALL_0086.jpg OS_INSTALL_0081.jpg + '[' '!' -f OS_INSTALL_0082.jpg ']' + mv OS_INSTALL_0087.jpg OS_INSTALL_0082.jpg + '[' '!' -f OS_INSTALL_0083.jpg ']' + mv OS_INSTALL_0088.jpg OS_INSTALL_0083.jpg + '[' '!' -f OS_INSTALL_0084.jpg ']' + mv OS_INSTALL_0089.jpg OS_INSTALL_0084.jpg + '[' '!' -f OS_INSTALL_0085.jpg ']' + mv OS_INSTALL_0090.jpg OS_INSTALL_0085.jpg + '[' '!' -f OS_INSTALL_0086.jpg ']' + mv OS_INSTALL_0091.jpg OS_INSTALL_0086.jpg + '[' '!' -f OS_INSTALL_0087.jpg ']' + mv OS_INSTALL_0092.jpg OS_INSTALL_0087.jpg + '[' '!' -f OS_INSTALL_0088.jpg ']' + mv OS_INSTALL_0093.jpg OS_INSTALL_0088.jpg + '[' '!' -f OS_INSTALL_0089.jpg ']' + mv OS_INSTALL_0094.jpg OS_INSTALL_0089.jpg + '[' '!' -f OS_INSTALL_0090.jpg ']' + mv OS_INSTALL_0095.jpg OS_INSTALL_0090.jpg + '[' '!' -f OS_INSTALL_0091.jpg ']' + mv OS_INSTALL_0096.jpg OS_INSTALL_0091.jpg + '[' '!' -f OS_INSTALL_0092.jpg ']' + mv OS_INSTALL_0097.jpg OS_INSTALL_0092.jpg + '[' '!' -f OS_INSTALL_0093.jpg ']' + mv OS_INSTALL_0098.jpg OS_INSTALL_0093.jpg + '[' '!' -f OS_INSTALL_0094.jpg ']' + mv OS_INSTALL_0099.jpg OS_INSTALL_0094.jpg + '[' '!' -f OS_INSTALL_0095.jpg ']' + mv OS_INSTALL_0100.jpg OS_INSTALL_0095.jpg + '[' '!' -f OS_INSTALL_0096.jpg ']' + mv OS_INSTALL_0101.jpg OS_INSTALL_0096.jpg + '[' '!' -f OS_INSTALL_0097.jpg ']' + mv OS_INSTALL_0102.jpg OS_INSTALL_0097.jpg + '[' '!' -f OS_INSTALL_0098.jpg ']' + mv OS_INSTALL_0103.jpg OS_INSTALL_0098.jpg + '[' '!' -f OS_INSTALL_0099.jpg ']' + mv OS_INSTALL_0104.jpg OS_INSTALL_0099.jpg + '[' '!' -f OS_INSTALL_0100.jpg ']' + mv OS_INSTALL_0105.jpg OS_INSTALL_0100.jpg + '[' '!' -f OS_INSTALL_0101.jpg ']' + mv OS_INSTALL_0106.jpg OS_INSTALL_0101.jpg + '[' '!' -f OS_INSTALL_0102.jpg ']' + mv OS_INSTALL_0107.jpg OS_INSTALL_0102.jpg + '[' '!' -f OS_INSTALL_0103.jpg ']' + mv OS_INSTALL_0108.jpg OS_INSTALL_0103.jpg + '[' '!' -f OS_INSTALL_0104.jpg ']' + mv OS_INSTALL_0109.jpg OS_INSTALL_0104.jpg + '[' '!' -f OS_INSTALL_0105.jpg ']' + mv OS_INSTALL_0111.jpg OS_INSTALL_0105.jpg + '[' '!' -f OS_INSTALL_0106.jpg ']' + mv OS_INSTALL_0112.jpg OS_INSTALL_0106.jpg + '[' '!' -f OS_INSTALL_0107.jpg ']' + mv OS_INSTALL_0113.jpg OS_INSTALL_0107.jpg
ご覧のように、22番目のファイルまでは何もしていません。23番目のファイルが抜け番なので、24番目のファイルを23番にリネームしています。このように1つでも抜け番があれば、どんどんファイル名の数字を詰めていくので、以降のファイルはすべてリネームしています。また、2番目の抜け番もこのようによろしくやってくれています。
+ mv OS_INSTALL_0027.jpg OS_INSTALL_0026.jpg + '[' '!' -f OS_INSTALL_0027.jpg ']' + mv OS_INSTALL_0028.jpg OS_INSTALL_0027.jpg + '[' '!' -f OS_INSTALL_0028.jpg ']' + mv OS_INSTALL_0030.jpg OS_INSTALL_0028.jpg + '[' '!' -f OS_INSTALL_0029.jpg ']' + mv OS_INSTALL_0031.jpg OS_INSTALL_0029.jpg
リネーム前のファイル名は、そもそも存在しないファイル名が変数に入りません。また、リネーム後のファイル名は、forループで前回実行した回のリネーム後のファイル名に1を足しているので、上書きの心配もありません。
それではなぜtestコマンドで条件式をつけているのでしょう。その理由ですが、mvコマンドでエラーを出さないためです。testコマンドなしで実行したときはこうなります。
$ declare -i num ; num=1 ; for FILES in $(ls) ; do echo "mv $FILES $(printf "OS_INSTALL_%04d.jpg\n" $num)" ; num=$num+1 ; done | sh -x + mv OS_INSTALL_0001.jpg OS_INSTALL_0001.jpg mv: `OS_INSTALL_0001.jpg' と `OS_INSTALL_0001.jpg' は同じファイルです + mv OS_INSTALL_0002.jpg OS_INSTALL_0002.jpg mv: `OS_INSTALL_0002.jpg' と `OS_INSTALL_0002.jpg' は同じファイルです + mv OS_INSTALL_0003.jpg OS_INSTALL_0003.jpg mv: `OS_INSTALL_0003.jpg' と `OS_INSTALL_0003.jpg' は同じファイルです + mv OS_INSTALL_0004.jpg OS_INSTALL_0004.jpg mv: `OS_INSTALL_0004.jpg' と `OS_INSTALL_0004.jpg' は同じファイルです + mv OS_INSTALL_0005.jpg OS_INSTALL_0005.jpg mv: `OS_INSTALL_0005.jpg' と `OS_INSTALL_0005.jpg' は同じファイルです (以下略)
エラーで止めずにすすめたいという乱暴な考えなら一応動きますが、エラーで止める処理がある場合はこうなります。
$ declare -i num ; num=1 ; for FILES in $(ls) ; do echo "mv $FILES $(printf "OS_INSTALL_%04d.jpg\n" $num)" ; num=$num+1 ; done | sh -uex + mv OS_INSTALL_0001.jpg OS_INSTALL_0001.jpg mv: `OS_INSTALL_0001.jpg' と `OS_INSTALL_0001.jpg' は同じファイルです
ご覧のように、mvコマンドのエラーで処理が止まりました。なので、testコマンドの条件式が有用だということがおわかりいただけたかと思います。わざわざshに渡すときにエラーチェックしなくてもいいじゃんと言われればそれまでですが、仮にシェルスクリプトに書く場合、後続の処理を力技ですすめるの怖くないですか?なので、ここまですれば「一応動く」ではなく、「mvコマンドが出すエラーもちゃんとケアして」リネームできたと言えることになります。それではよい画像収集ライフを!
こんにちは。さくらクラブ startuphack in Kagoshima という素敵イベントに参加してまいりましたので、イベントレポートでございます。
さくらインターネットより「イベントあるけど来ない?」と誘われてホイホイ着いて行ったのですが、黒塗りのベンツに追突することもなく非常に熱く楽しい時間を過ごすことができました。公式イベントページによると、目的は2つ
とのことで、さくらインターネット 田中社長以外のスピーカーの皆様について何の予備知識も先入観もなく、飛び込みで参加してみたのですが、非常に熱量の高い、久々に興奮するイベントでございました。イベント自体は、私が鹿児島入りする前日の 2015/06/26 から始まっており、この日は「ワンボタンハッカソン」というハッカソンが行われていたのですが、私はイベント2日目からの参加でした。
会場はホテルだったので「どんな堅いイベントなのだろう?」と思っていたのですが、なんと部屋は畳に座布団!
そして基調講演でさくらインターネット 田中社長が登壇したときは、これは地元公民館での落語じゃないかと思ったくらいに最初のイメージが逆転してゆるい雰囲気でのスタートとなりました。
内容をまとめると
というキッカケで、さくらインターネット社員とユーザーによるコミュニティができたということです。
その後、コーナーは「鹿児島スタートアップショーケース」に移り、鹿児島にゆかりのあるスタートアップたちがサービスの紹介をしていました。
中でも私が一番度肝を抜かれたのは「痛すぽ」のJoyas 内村さんのデモンストレーション。
なでなでするとキャラクターの音声が流れる抱き枕向けキットだそうで、どこかで聞いたことがあると思ったら、
スラドで見たことがあって「あ〜〜〜〜〜!」と1人納得でございます。実際に抱き枕を持ち込んでの実演もあったのですが、叩くと「もっと優しくして♡」とたしなめられたりして、アクションごとに違う音が流れることが実体験としてわかりました。
その後の質疑応答で
「叩いたときのリアクションに『ぶってぶって♡』という音声に差し替えることは可能なのでしょうか?」と聞いたら
叩いたときの反応に「ぶってぶって♡」はアリなんですか?って聞いたら「すでにあります」と… (´⊙ω⊙`)
— (っ´∀`)っ ゃー (@nullpopopo) June 27, 2015
マジですか・・・ (´⊙ω⊙`)
蛇足で大変恐縮なのですが、私の前職でも「なでなで目覚まし。かのん」というプロダクトがございまして、開発のコアメンバーに九州勢が多かった記憶があります。
その後休憩を挟み、シェアゼロ 中川氏による「New Work Style 〜起業、フリーランス、副業。これからのハタラキカタ〜」から「呑ん方談話。地方スタートアップはこう戦え」というコーナーだったのですが、壇上に座布団ってこれは大喜利ですか(笑)。
壇上のパネリストは焼酎飲みながらトークをしていたのですが、これはまるでTechLIONですね!やはりお酒が入るとトークも熱が入ります。この日のイベントでは、何度も「熱量」というキーワードが出ていたのですが、壇上のパネリストだけでなく、参加者からも非常に熱い質問などが飛び交い、本当に会場全体の熱量がとんでもなく、久々にイベントで胸が熱くなりました。
その後、いよいよハッカソン成果発表だったのですが、16歳高専生のスライドがあまりにも(我々の業界的に)完璧すぎて、チーム「ヤングマン」が優勝でした。
内容は「ワンボタンプッシュで楽天レシピから自分好みのレシピをgetしてくる」というもので、世の奥様方には非常に喜ばれるのではないでしょうか。slideshareでの公開が楽しみです。優勝賞品としてラズパイ(チーム全員)と、さくらインターネット 石狩DC 見学ツアーご招待(チームの中から1名)でしたが、彼の楽しみな表情がすごく新鮮でした。
続いてライトニングトーク大会でしたが、(後述する)イベント参加前の桜島観光が押したせいで1人あたりの持ち時間が1分という事態に。私の超駆け足発表はこちらになります。
最後に全員で記念撮影しておしまいでございました。終わった瞬間、酔いつぶれてご迷惑おかけして本当に申し訳ございません (;´Д`)
旅の思い出は次のページからどうぞ。
CentOS 6と7でnginxを1.9.2にアップデートした後から、muninでnginxとphp-fpmのグラフが取得できなくなったので、対処したときのメモを残します。nginxは公式サイトのyumリポジトリ(mainline)からインストールおよびアップデートしています。
アップデート前のnginxは1.9.1でした。
$ rpm -q nginx nginx-1.9.1-1.el7.ngx.x86_64
アップデート後のnginxは1.9.2です。
$ rpm -q nginx nginx-1.9.2-1.el7.ngx.x86_64
アップデート直後のmunin-run実行結果はこんな感じで値が取得できていません。アクセスログを見ても404でした。
$ munin-run nginx_status total.value U reading.value U writing.value U waiting.value U
127.0.0.1 - - [02/Jul/2015:08:31:26 +0900] "GET /nginx_status HTTP/1.1" 404 168 "-" "munin/2.0.25 (libwww-perl/5.833)" "-"
$ munin-run phpfpm_connections accepted.value U
127.0.0.1 - - [02/Jul/2015:08:32:05 +0900] "GET /phpfpm_status HTTP/1.1" 404 168 "-" "libwww-perl/5.833" "-"
$ munin-run phpfpm_status idle.value U active.value U total.value U
127.0.0.1 - - [02/Jul/2015:08:32:44 +0900] "GET /phpfpm_status HTTP/1.1" 404 168 "-" "libwww-perl/5.833" "-"
ただし、一部値が取得できているのもあり。
$ munin-run phpfpm_average php_average.value 5600051
$ munin-run phpfpm_memory ram.value 28000256
$ munin-run phpfpm_processes php_processes.value 5
いろいろ調べているうちに、munin-runではなくcurlでURLを突ついてみたらどうなるか、切り分けてみました。
※ アップデート前
$ curl -LIs http://127.0.0.1/nginx_status HTTP/1.1 200 OK Server: nginx/1.9.1 Date: Thu, 02 Jul 2015 09:14:38 GMT Content-Type: text/plain Connection: keep-alive
$ curl -LIs http://localhost/nginx_status HTTP/1.1 200 OK Server: nginx/1.9.1 Date: Thu, 02 Jul 2015 09:14:54 GMT Content-Type: text/plain Connection: keep-alive
$ curl -LIs http://127.0.0.1/phpfpm_status HTTP/1.1 200 OK Server: nginx/1.9.1 Date: Thu, 02 Jul 2015 09:17:45 GMT Content-Type: text/html; charset=UTF-8 Connection: keep-alive X-Powered-By: PHP/5.6.9 Expires: Thu, 01 Jan 1970 00:00:00 GMT Cache-Control: no-cache, no-store, must-revalidate, max-age=0
$ curl -LIs http://localhost/phpfpm_status HTTP/1.1 200 OK Server: nginx/1.9.1 Date: Thu, 02 Jul 2015 09:17:50 GMT Content-Type: text/html; charset=UTF-8 Connection: keep-alive X-Powered-By: PHP/5.6.9 Expires: Thu, 01 Jan 1970 00:00:00 GMT Cache-Control: no-cache, no-store, must-revalidate, max-age=0
アップデート後、何もしないとこうなります。
$ curl -LIs http://127.0.0.1/nginx_status HTTP/1.1 200 OK Server: nginx/1.9.2 Date: Thu, 02 Jul 2015 09:19:56 GMT Content-Type: text/plain Connection: keep-alive
$ curl -LIs http://localhost/nginx_status HTTP/1.1 404 Not Found Server: nginx/1.9.2 Date: Thu, 02 Jul 2015 09:19:59 GMT Content-Type: text/html Content-Length: 168 Connection: keep-alive
$ curl -LIs http://127.0.0.1/phpfpm_status HTTP/1.1 200 OK Server: nginx/1.9.2 Date: Thu, 02 Jul 2015 09:20:06 GMT Content-Type: text/html; charset=UTF-8 Connection: keep-alive X-Powered-By: PHP/5.6.9 Expires: Thu, 01 Jan 1970 00:00:00 GMT Cache-Control: no-cache, no-store, must-revalidate, max-age=0
$ curl -LIs http://localhost/phpfpm_status HTTP/1.1 404 Not Found Server: nginx/1.9.2 Date: Thu, 02 Jul 2015 09:20:10 GMT Content-Type: text/html Content-Length: 168 Connection: keep-alive
おわかりいただけましたでしょうか。curlでアクセスするURLが127.0.0.1だとnginxはステータス200を返すのですが、localhostだと404を返すため、munin-runでも値が取得できず、muninでグラフが生成されなくなってしまうのです。
これまでは、nginxのメインのバーチャルホストのserverディレクティブに設定をしていました。
server { listen 80 default_server; server_name www.example.com; (略) location /nginx_status { stub_status on; access_log off; allow 127.0.0.1; deny all; } location /phpfpm_status { include fastcgi_params; fastcgi_pass localhost:9000; fastcgi_param SCRIPT_FILENAME $fastcgi_script_name; allow 127.0.0.1; deny all; } }
変更後はこんな感じです。
server { listen 80 default_server; server_name www.example.com; (略) # /nginx_status と /phpfpm_status のlocation設定を削除 } server { listen 127.0.0.1:80; listen [::1]:80; server_name localhost localhost.localdomain 127.0.0.1 [::1]; location / { root /home/vhosts/www.example.com/public_html; index index.php index.html index.htm; } location /nginx_status { stub_status on; access_log off; allow ::1; allow 127.0.0.1; deny all; } location /phpfpm_status { include fastcgi_params; fastcgi_pass localhost:9000; fastcgi_param SCRIPT_FILENAME $fastcgi_script_name; allow ::1; allow 127.0.0.1; deny all; } location ~ \.php$ { root /home/vhosts/www.example.com/public_html; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name; client_max_body_size 256M; include fastcgi_params; } error_page 404 /404.html; location = /404.html { root /usr/share/nginx/html; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } }
新たにserverディレクティブを作ってあげました。ポイントは以下の通りです。
listen 127.0.0.1:80; listen [::1]:80;
server_name localhost localhost.localdomain 127.0.0.1 [::1];
allow ::1; allow 127.0.0.1; deny all;
なお、ここでのIPv6アドレスは[]で囲わないことに注意です。
最初はIPv6のアドレスを書かずに設定していたのですが、curlで確認してみると、最初にIPv6で接続を試み、接続できなければIPv4でリトライするようでしたので、無駄なリトライを避けるためにlistenでIPv6とIPv4のアドレスを併記しています。
$ curl -vv http://localhost/nginx_status * About to connect() to localhost port 80 (#0) * Trying ::1... * 接続を拒否されました * Trying 127.0.0.1... * Connected to localhost (127.0.0.1) port 80 (#0) > GET /nginx_status HTTP/1.1 > User-Agent: curl/7.29.0 > Host: localhost > Accept: */* > < HTTP/1.1 200 OK < Server: nginx/1.9.2 < Date: Thu, 02 Jul 2015 09:27:23 GMT < Content-Type: text/plain < Content-Length: 97 < Connection: keep-alive < Active connections: 1 server accepts handled requests 6 6 6 Reading: 0 Writing: 1 Waiting: 0 * Connection #0 to host localhost left intact
また、locationの中で「allow ::1;」を書き忘れるとこうなります。
$ curl -vv http://localhost/nginx_status * About to connect() to localhost port 80 (#0) * Trying ::1... * Connected to localhost (::1) port 80 (#0) > GET /nginx_status HTTP/1.1 > User-Agent: curl/7.29.0 > Host: localhost > Accept: */* > < HTTP/1.1 403 Forbidden < Server: nginx/1.9.2 < Date: Thu, 02 Jul 2015 09:33:11 GMT < Content-Type: text/html < Content-Length: 168 < Connection: keep-alive < <html> <head><title>403 Forbidden</title></head> <body bgcolor="white"> <center><h1>403 Forbidden</h1></center> <hr><center>nginx/1.9.2</center> </body> </html> * Connection #0 to host localhost left intact
というわけで、localhost専用のserverディレクティブを書いてあげると、curlでこのように綺麗なアクセスができました。
$ curl -vv http://localhost/nginx_status * About to connect() to localhost port 80 (#0) * Trying ::1... * Connected to localhost (::1) port 80 (#0) > GET /nginx_status HTTP/1.1 > User-Agent: curl/7.29.0 > Host: localhost > Accept: */* > < HTTP/1.1 200 OK < Server: nginx/1.9.2 < Date: Thu, 02 Jul 2015 09:38:02 GMT < Content-Type: text/plain < Content-Length: 97 < Connection: keep-alive < Active connections: 1 server accepts handled requests 1 1 1 Reading: 0 Writing: 1 Waiting: 0 * Connection #0 to host localhost left intact
$ curl -vv http://localhost/phpfpm_status * About to connect() to localhost port 80 (#0) * Trying ::1... * Connected to localhost (::1) port 80 (#0) > GET /phpfpm_status HTTP/1.1 > User-Agent: curl/7.29.0 > Host: localhost > Accept: */* > < HTTP/1.1 200 OK < Server: nginx/1.9.2 < Date: Thu, 02 Jul 2015 09:38:10 GMT < Content-Type: text/plain;charset=UTF-8 < Transfer-Encoding: chunked < Connection: keep-alive < X-Powered-By: PHP/5.6.9 < Expires: Thu, 01 Jan 1970 00:00:00 GMT < Cache-Control: no-cache, no-store, must-revalidate, max-age=0 < pool: www process manager: dynamic start time: 02/Jul/2015:18:26:32 +0900 start since: 698 accepted conn: 39 listen queue: 0 max listen queue: 0 listen queue len: 128 idle processes: 5 active processes: 1 total processes: 6 max active processes: 2 max children reached: 0 slow requests: 0 * Connection #0 to host localhost left intact
それでは肝心のmunin-runで最終確認してみましょう。
$ munin-run nginx_request request.value 4837
$ munin-run nginx_status total.value 2 reading.value 0 writing.value 1 waiting.value 1
$ munin-run phpfpm_average php_average.value 101467136
$ munin-run phpfpm_connections accepted.value 2262
$ munin-run phpfpm_memory ram.value 811737088
$ munin-run phpfpm_processes php_processes.value 8
$ munin-run phpfpm_status idle.value 7 active.value 1 total.value 8
バッチリ値が取得できていますね。(∩´∀`)∩ワーイ
おはようございます。早朝muninおじさんです。munin監視対象でhttp_loadtimeの値が取れず、 /usr/share/munin/plugins/http_loadtime を修正したので対処メモを残します。監視対象の環境は以下の通りです。
$ cat /etc/redhat-release CentOS release 6.6 (Final)
$ yum list installed munin-node | egrep munin-node | awk '{print $1,$2,$3}' munin-node.noarch 2.0.25-2.el6 @epel
$ yum list installed httpd | egrep httpd | awk '{print $1,$2,$3}' httpd.x86_64 2.2.15-39.el6.centos @base
監視対象がWEBサーバーだったので、いつものようにmunin-nodeをインストールしてhttp_loadtimeを監視項目に加えたのですが・・・
$ sudo ln -s /usr/share/munin/plugins/http_loadtime /etc/munin/plugins/http_loadtime
munin-runで値が取れているか確認したところ
$ sudo munin-run http_loadtime which: no time in (/usr/sbin:/usr/bin:/sbin:/bin) /etc/munin/plugins/http_loadtime: line 78: syntax error: unexpected end of file
いきなり2つエラーが出てしまいました。。。
まず1つ目
time_bin=`which time`
なんて変数指定があるのですが、bash内部コマンドのtimeだとwhichでPATHが表示されず、異常終了します。
$ which time > /dev/null 2>&1 ; echo $? 1
なので、GNU timeをインストールしてあげる必要があります。baseリポジトリにあるのでサックリインストールしてあげましょう。
$ sudo yum install time
さて、もう一度whichでtimeコマンドのPATHを確認してみましょう。
$ which time ; echo $? /usr/bin/time 0
timeコマンドのPATHが表示され、正常終了しました。なお、シェルがbashの場合、timeコマンドをフルパスで指定しない限り、bash内部コマンドのtimeが優先されて実行されます。だからプラグインの中でtimeコマンドを変数に格納するときに time_bin=which time
なんてやってたんですね。
http_loadtime “line 78: syntax error: unexpected end of file” でググったら、Bugzillaのページがhitして、コメント3がそのものズバリの答えでした。
d. johnson 2015-04-10 16:37:36 EDT
Line 45 of /usr/share/munin/plugins/http_loadtime has an ‘if’ statement that has no ending ‘fi’This is what causes it to fail.
45行目の「if ! $wget_bin -q -O /dev/null $target; then」がfiで閉じられておらず。。。というわけで、55行目の「exit 0」と56行目の「fi」の間にfiを追記。
さあ気を取り直して再実行!
$ sudo munin-run http_loadtime /home/nullpopopo loadtime.value /usr/bin/time: unrecognized option '--quiet' Usage: /usr/bin/time [-apvV] [-f format] [-o file] [--append] [--verbose] [--portability] [--format=format] [--output=file] [--version] [--help] command [arg...]
あれ?カレントディレクトリが表示されてるぞ?こんな値くれとは言ってないぞ・・・。
$ cd / $ sudo munin-run http_loadtime / loadtime.value /usr/bin/time: unrecognized option '--quiet' Usage: /usr/bin/time [-apvV] [-f format] [-o file] [--append] [--verbose] [--portability] [--format=format] [--output=file] [--version] [--help] command [arg...]
あのさあ・・・。
なんでカレントディレクトリが表示されているのかはちょっと置いといて、まずは明らかにエラーの原因がわかっている「–quiet」のほうからやっつけます。GNU timeにはそんなオプション無いぞと言われたのでふたたび /usr/share/munin/plugins/http_loadtime を編集します。
$ cat /usr/share/munin/plugins/http_loadtime | grep quiet loadtime=`$time_bin --quiet -f "%e" wget $wget_opt $target 2>&1`
$ sudo sed -i "s/--quiet //" /usr/share/munin/plugins/http_loadtime
$ cat /usr/share/munin/plugins/http_loadtime | grep quiet
$ cat /usr/share/munin/plugins/http_loadtime | egrep "time_bin -f" loadtime=`$time_bin -f "%e" wget $wget_opt $target 2>&1`
さあもう一度実行だ!
$ sudo munin-run http_loadtime /home/nullpopopo loadtime.value 0.08
( ・᷄ὢ・᷅ )えー・・・試しに手動で実行してみます。
$ target=${target:-"http://localhost/" $ wget_opt="--user-agent munin/http_loadtime --no-cache -q --delete-after" $ time_bin=`which time`
$ $time_bin -f "%e" wget $wget_opt $target 0.05
お、値がとれた。loadtimeも変数に入れてみましょう。
$ loadtime=`$time_bin -f "%e" wget $wget_opt $target 2>&1`
$ echo $loadtime 0.02
こちらも値が取れている。どうやらtimeコマンドまわりは解決、カレントディレクトリが表示される原因は他の箇所にありそうです。
もう一度 munin-run で確認してみます。
$ sudo munin-run http_loadtime /home/nullpopopo loadtime.value 0.01
munin-runで値は取れるようになったものの、まだカレントディレクトリが表示されちゃってます。どうしてこうなった!?と憤怒しながらも、最後の最後を見てみると、「cd -」してるんですね。カレントディレクトリに戻るのはいいけど出力して意味あるの?ないでしょ?ということで /dev/null送りに。どうせ最後は「echo “loadtime.value $loadtime」するだけだから行ごと削除でもいいんですけど!(プンスコ)
$ sudo munin-run http_loadtime loadtime.value 0.01
はいめでたしめでたし。やっと欲しい値が取れて、余計な出力もされなくなりました。グラフも見てみましょう。値が取れてますね。
最後にソース全文をぺったんこ。
#!/bin/bash # -*- sh -*- : << =cut =head1 NAME http_loadtime - Plugin to graph HTTP response time of a specific page =head1 CONFIGURATION The following environment variables are used by this plugin target - URL to fetch (default: "http://localhost/") =head1 AUTHOR Unknown authors (2013) Axel Huebl =head1 LICENSE GPLv2 =head1 MAGIC MARKERS #%# family=auto #%# capabilities=autoconf =cut target=${target:-"http://localhost/"} wget_opt="--user-agent munin/http_loadtime --no-cache -q --delete-after" time_bin=`which time` if [ "$1" = "autoconf" ]; then result="yes" command -v $time_bin 2>&1 >/dev/null || result=1 command -v tr 2>&1 >/dev/null || result=1 command -v wget 2>&1 >/dev/null || result=1 if [ "$result" != "yes" ]; then echo "no (programs time, wget and tr required)" exit 0 fi if ! $wget_bin -q -O /dev/null $target; then # check if url responds # wget --spider $target $wget_opt if [ "$?" != "0" ]; then echo "no (Cannot run wget against \"$target\")" exit 0 fi echo yes exit 0 fi fi if [ "$1" = "config" ]; then echo "graph_title HTTP loadtime of a page" echo "graph_args --base 1000 -l 0" echo "graph_vlabel Load time in seconds" echo "graph_category network" echo "graph_info This graph shows load time in seconds of $target" echo "loadtime.label loadtime" echo "loadtime.info Load time" exit 0 fi TEMPO_DIR=$(mktemp -dt munin_http_loadtime.XXXXXX) || exit 1 trap "rm -rf $TEMPO_DIR" EXIT cd $TEMPO_DIR || exit 1 loadtime=`$time_bin -f "%e" wget $wget_opt $target 2>&1` cd - > /dev/null echo "loadtime.value $loadtime"
めでたしめでたし。 (ノ)・ω・(ヾ)ムニムニ
munin監視対象のホスト名が変わった場合、監視サーバー側でもホスト名を変えないと、見た人がホストを取り違えるなどミスがおきてしまいます。監視サーバー側のmunin.confでホスト名を変えるだけでは過去データは失われないものの、過去監視データは引き継がれません。監視対象のIPアドレスはそのままでホスト名が変わったときの、過去監視データを引き継ぐ手順をメモします。
監視サーバー側のディストリビューションはCentOS 6.6、muninパッケージは以下の通りです。
$ cat /etc/redhat-release CentOS release 6.6 (Final)
$ yum list installed munin* | egrep munin | awk '{print $1,$2,$3}' munin.noarch 2.0.25-2.el6 @epel munin-common.noarch 2.0.25-2.el6 @epel munin-nginx.noarch 2.0.25-2.el6 @epel munin-node.noarch 2.0.25-2.el6 @epel
監視サーバーと監視対象でそれぞれオペレーションを行うので、見出しにどちらで作業するのかを書いています。監視対象の旧ホスト名を www.old.example.com 、新ホスト名を www.new.test.jp とします。
5分に1回、muninのデータ出力が行われるたびに旧ホスト名でのデータが更新されてしまうので、これらのデーモンを動かしている場合は一旦停止します。
/etc/munin.conf に書かれている、監視対象のホスト名を書き換えます。IPアドレスの変更がなければホスト名のみの書き換えでOKです。
/etc/munin/munin-node.conf にかかれている、「host_name」で始まる行のホスト名(自ホスト名)を書き換えます。
監視対象の過去データ(rrdファイル)は /var/lib/munin の下のグループ名のディレクトリの中に www.old.example.com-〜〜〜.rrdというファイル名で置かれています。グループ名はmuninの監視画面またはmunin.confで確認してください。
$ cd /var/lib/munin/GROUPNAME
そして一撃リネームです。
$ for A in $(ls | grep www.old.example.com); do sudo mv ${A} $(echo ${A} | sed -e "s/www.old.example.com/www.new.test.jp/"); done
■ state-グループ名-www.old.example.com.storable ファイルをリネームする
state-グループ名-www.old.example.com.storable ファイルを state-グループ名-www.new.test.jp.storable にリネーム(コピー)します。
$ cd /var/lib/munin $ sudo mkdir -p BACKUP $ sudo cp -p state-GROUPNAME-www.old.example.com.storable state-GROUPNAME-www.new.test.jp.storable $ sudo mv state-GROUPNAME-www.old.example.com.storable BACKUP/
先ほど止めた munin-fcgi-graph munin-fcgi-htmlのデーモンを起動します。5分程度待ってからブラウザの監視画面をリロードして、監視対象のホスト名が変わっていればOKです。ね、簡単でしょう?
CentOSにWordPressを一撃インストールするシェルスクリプトを大幅見直ししてgithubに公開しました。主な変更点は
です。
ほんとはREADMEも一緒にリリースしとけって話ですが・・・素の一撃スクリプトをrootで実行しても動きます。デフォルトで
ブログのタイトル | ICHIGEKI |
ブログの管理者ID | ichigeki |
ブログのパスワード | ランダムなもの |
管理者メールアドレス | webmaster@example.com |
となっています。だいたいの変更要素はスクリプト上部の変数だけ弄ればよいように作ってあります。2015/07/27 00:00 時点でのWordPress最新版は日本語版としてダウンロードしようとするとwp-cliに怒られるので、4.2.2の日本語版をダウンロードするようにしています。
一応こちらにもコードを貼り付けておきます。
#!/bin/bash set -eux LANG=C BLOGTITLE= BLOGADMIN= BLOGPW= ADMINMAIL= WPVERSION=4.2.2 WPLOCALE=ja #WPVERSION= #WPLOCALE= NEWHOSTNAME=www NEWDOMAIN=example.com NEWFQDN=${NEWHOSTNAME}.${NEWDOMAIN} # Specify the SSH port SSHPORT= # Store the MySQL version to the variable #MYSQLVER=5.6 MYSQLVER=5.7 # Store the MySQL ServerID to variable SERVERID=1 # Store the trusted network to an array TRUSTSUBNET=() TRUSTSUBNET=(" 127.0.0.1/32 192.168.0.0/24 ") # Store a UNIX account to a variable ADMINUSER=nullpopopo ADMINUSERPW=$(cat /dev/urandom | tr -dc '[:alnum:]' | head -c 16) ADMINUSERUID=500 ADMINUSERGID=500 ADMINUSERPUBKEY="ssh-rsa AAAAxxxxxxxx==" # Store the version of the CentOS Distribution to a variable OSVER=$(rpm -qi centos-release | grep ^Version | awk '{print $3}') REMIREPOURI=http://remi.kazukioishi.net/enterprise/remi-release-${OSVER}.rpm WP=/usr/local/bin/wp WPDOWNLOADURI=https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar RUBYGETTERURI=https://raw.githubusercontent.com/nullpopopo/RUBYGETTER/master/RUBYGETTER RUBYSPECURI=https://raw.githubusercontent.com/hansode/ruby-2.1.x-rpm/master/ruby21x.spec # Leave to log all the subsequent processing LOGDIR=${HOME}/logs LOGFILE=${LOGDIR}/$(uname -n)_$(date +%Y%m%d%H%M%S)_$(basename ${0})_${$}.LOG mkdir -p ${LOGDIR} exec >> ${LOGFILE} exec 2>&1 # date # ################################################################ # SELinux Disable getenforce setenforce 0 getenforce sed -i.orig 's/enforcing$/disabled/' /etc/selinux/config ################################################################ ################################################################ # Create VirtualHost DocumentRoot mkdir -p /home/vhosts/${NEWFQDN} VHDIR=/home/vhosts/${NEWFQDN}/public_html ################################################################ ################################################################ # Generate the parameters of the DB NUM=$(ls /home/vhosts/ | wc -l) DBNAME=$(printf "wpdb%04d" ${NUM}) DBUSER=$(printf "user%04d" ${NUM}) DBUSERPW=$(cat /dev/urandom | tr -dc '[:alnum:]' | head -c 8) MYSQLROOTPW=$(cat /dev/urandom | tr -dc '[:alnum:]' | head -c 16) ################################################################ ################################################################ # Group ADD if [ ! 0 = $(grep ${ADMINUSER} /etc/group > /dev/null ; echo $?) ]; then if [ ! 0 = $(grep ${ADMINUSERGID} /etc/group > /dev/null ; echo $?) ]; then echo "Group ADD ${ADMINUSERGID} ${ADMINUSER}" groupadd -g ${ADMINUSERGID} ${ADMINUSER} else echo "Group ADD ${ADMINUSER}" groupadd ${ADMINUSER} fi fi # User ADD if [ ! 0 = $(grep ${ADMINUSER} /etc/passwd > /dev/null ; echo $?) ]; then if [ ! 0 = $(grep ${ADMINUSERUID} /etc/passwd > /dev/null ; echo $?) ]; then echo "User ADD ${ADMINUSERUID} ${ADMINUSER}" useradd -u ${ADMINUSERUID} -g ${ADMINUSERGID} ${ADMINUSER} else echo "User ADD ${ADMINUSER}" useradd ${ADMINUSER} fi echo ${ADMINUSER}:${ADMINUSERPW} | tee PASSWD chpasswd < PASSWD mkdir -p /home/${ADMINUSER}/.ssh/ chmod 711 /home/${ADMINUSER}/ chmod 700 /home/${ADMINUSER}/.ssh/ touch /home/${ADMINUSER}/.ssh/authorized_keys chmod 600 /home/${ADMINUSER}/.ssh/authorized_keys cat << _EOL_ | tee /home/${ADMINUSER}/.ssh/authorized_keys ${ADMINUSERPUBKEY} _EOL_ chown -R ${ADMINUSER}. /home/${ADMINUSER}/.ssh/ fi # PasswordFile Remove rm -f PASSWD echo "" ################################################################ ################################################################ # sudoers Add if [ 0 = $(grep ${ADMINUSER} /etc/passwd > /dev/null ; echo $?) -a ! -f /etc/sudoers.d/${ADMINUSER} ]; then echo "Sudoers ADD ${ADMINUSER}" cat << _EOL_ | tee /etc/sudoers.d/${ADMINUSER} ${ADMINUSER} ALL=(ALL) NOPASSWD: ALL Defaults:${ADMINUSER} !requiretty Defaults:${ADMINUSER} env_keep += SSH_AUTH_SOCK _EOL_ fi echo "" ################################################################ ################################################################ # epel Repository Install if [ ! -f /etc/yum.repos.d/epel.repo ]; then yum -y install epel-release mkdir /etc/yum.repos.d/BACKUP/ cp -p /etc/yum.repos.d/epel.repo{,.orig} sed -i "s/enabled=1/enabled=0/" /etc/yum.repos.d/epel.repo fi ################################################################ ################################################################ # remi Repository Install if [ ! -f /etc/yum.repos.d/remi.repo ]; then yum -y install ${REMIREPOURI} fi yum -y install \ bind-utils \ dstat \ gcc \ gcc-c++ \ git \ lsof \ mailx \ nkf \ rpm-build \ telnet \ unzip \ wget \ zip yum -y --enablerepo=epel install htop ################################################################ ################################################################ # Configure sshd SSHDCONFIG=/etc/ssh/sshd_config : ${SSHPORT:="60022"} cp -p ${SSHDCONFIG} ${SSHDCONFIG}.orig sed -i "/^#Port[[:space:]]22$/a\Port 22" ${SSHDCONFIG} sed -i "/^Port[[:space:]]22$/a\Port ${SSHPORT}" ${SSHDCONFIG} sed -i "/^#GSSAPIAuthentication no/s/#//" ${SSHDCONFIG} sed -i "/^GSSAPIAuthentication yes/s/yes$/no/" ${SSHDCONFIG} sed -i "/^GSSAPICleanupCredentials yes/s/yes$/no/" ${SSHDCONFIG} sed -i "s/#GSSAPIStrictAcceptorCheck yes/GSSAPIStrictAcceptorCheck no/" ${SSHDCONFIG} sed -i "/#GSSAPIKeyExchange no/s/#//" ${SSHDCONFIG} sed -i "s/#UseDNS yes/UseDNS no/" ${SSHDCONFIG} cp -p ${SSHDCONFIG} ${SSHDCONFIG}.TMP awk 'NR==1||prev!=$0;{prev=$0}' ${SSHDCONFIG}.TMP > ${SSHDCONFIG} rm -f ${SSHDCONFIG}.TMP ################################################################ ################################################################ # yum update yum -y update ################################################################ ################################################################ # postfix setting cp -p /etc/postfix/main.cf{,.orig} sed -i "s/#myhostname = virtual.domain.tld/#myhostname = virtual.domain.tld\nmyhostname = ${NEWFQDN}/" /etc/postfix/main.cf sed -i "s/#inet_interfaces = all/inet_interfaces = all/" /etc/postfix/main.cf sed -i "s/inet_interfaces = localhost/#inet_interfaces = localhost/" /etc/postfix/main.cf sed -i 's/#myorigin = $myhostname/myorigin = $myhostname/' /etc/postfix/main.cf sed -i "s/#home_mailbox = Maildir/home_mailbox = Maildir/" /etc/postfix/main.cf if [ ${OSVER} = 6 ]; then service postfix restart chkconfig postfix on fi if [ ${OSVER} = 7 ]; then systemctl restart postfix.service systemctl enable postfix.service fi ################################################################ ################################################################ # iptables setting if [ ${OSVER} = 6 ]; then iptables -L -n -v echo "" service iptables stop iptables -P INPUT DROP iptables -P OUTPUT ACCEPT iptables -P FORWARD DROP iptables -A INPUT -i lo -j ACCEPT iptables -I INPUT -p icmp --icmp-type 0 -j ACCEPT iptables -I INPUT -p icmp --icmp-type 8 -j ACCEPT iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A INPUT -p tcp --dport 25 -j ACCEPT iptables -A INPUT -p tcp --dport 80 -j ACCEPT iptables -A INPUT -p tcp --dport ${SSHPORT} -j ACCEPT for SUBNETS in ${TRUSTSUBNET[@]} do iptables -A INPUT -s ${SUBNETS} -p tcp --dport 22 -j ACCEPT done service iptables save service iptables start chkconfig iptables on echo "" iptables -L -n -v echo "" fi if [ ${OSVER} = 7 ]; then if [ 3 = $(systemctl status firewalld.service > /dev/null ; echo $?) ]; then systemctl start firewalld.service fi systemctl enable firewalld.service firewall-cmd --zone=public --add-service http firewall-cmd --zone=public --add-service http --permanent firewall-cmd --zone=public --add-service smtp firewall-cmd --zone=public --add-service smtp --permanent firewall-cmd --zone=public --add-port=${SSHPORT}/tcp firewall-cmd --zone=public --add-port=${SSHPORT}/tcp --permanent for SUBNETS in ${TRUSTSUBNET[@]} do firewall-cmd --direct \ --add-rule ipv4 \ filter INPUT 1 -m conntrack --ctstate NEW -m tcp -p tcp --dport 22 -s ${SUBNETS} -j ACCEPT firewall-cmd --permanent --direct \ --add-rule ipv4 \ filter INPUT 1 -m conntrack --ctstate NEW -m tcp -p tcp --dport 22 -s ${SUBNETS} -j ACCEPT done firewall-cmd --remove-service=ssh --zone=public firewall-cmd --remove-service=ssh --zone=public --permanent fi ################################################################ ################################################################ # MySQL Community Server 5.6 or 5.7 Install yum -y install http://dev.mysql.com/get/mysql-community-release-el${OSVER}-5.noarch.rpm : ${MYSQLVER:="5.6"} if [ ${MYSQLVER} = 5.7 ]; then cp -p /etc/yum.repos.d/mysql-community.repo{,.orig} mv /etc/yum.repos.d/mysql-community.repo.orig /etc/yum.repos.d/BACKUP/ sed -i '/mysql56-community/,/gpgcheck/s/enabled=1/enabled=0/g' /etc/yum.repos.d/mysql-community.repo sed -i '/mysql57-community-dmr/,/^enabled/s/0/1/' /etc/yum.repos.d/mysql-community.repo fi yum -y install mysql-community-server ################################################################ ################################################################ # Configure MySQL MYCNF=/etc/my.cnf sed -i.orig '/^#/d;/^$/d' ${MYCNF} sed -i "/^\[mysqld\]$/a\query_cache_limit=1M\\n" ${MYCNF} sed -i "/^\[mysqld\]$/a\query_cache_min_res_unit=1024" ${MYCNF} sed -i "/^\[mysqld\]$/a\query_cache_size=0" ${MYCNF} sed -i "/^\[mysqld\]$/a\query_cache_type=ON" ${MYCNF} sed -i "/^\[mysqld\]$/a\user=mysql" ${MYCNF} sed -i "/^\[mysqld\]$/a\binlog_direct_non_transactional_updates=Off\\n" ${MYCNF} sed -i "/^\[mysqld\]$/a\binlog_stmt_cache_size=16384" ${MYCNF} sed -i "/^\[mysqld\]$/a\binlog_cache_size=16384" ${MYCNF} sed -i "/^\[mysqld\]$/a\binlog_format=MIXED" ${MYCNF} if [ ${MYSQLVER} = 5.6 ]; then sed -i "/^\[mysqld\]$/a\innodb_additional_mem_pool_size=4M\\n" ${MYCNF} fi sed -i "/^\[mysqld\]$/a\innodb_autoextend_increment=1000" ${MYCNF} sed -i "/^\[mysqld\]$/a\innodb_log_buffer_size=16M" ${MYCNF} sed -i "/^\[mysqld\]$/a\innodb_log_file_size=64M" ${MYCNF} sed -i "/^\[mysqld\]$/a\innodb_buffer_pool_size=512M" ${MYCNF} sed -i "/^\[mysqld\]$/a\innodb_max_dirty_pages_pct=75" ${MYCNF} sed -i "/^\[mysqld\]$/a\innodb_stats_on_metadata=Off" ${MYCNF} sed -i "/^\[mysqld\]$/a\innodb_read_io_threads=4" ${MYCNF} sed -i "/^\[mysqld\]$/a\innodb_write_io_threads=4" ${MYCNF} sed -i "/^\[mysqld\]$/a\innodb_file_format=Barracuda" ${MYCNF} sed -i "/^\[mysqld\]$/a\innodb_file_per_table=1" ${MYCNF} sed -i "/^\[mysqld\]$/a\max_allowed_packet=512M\\n" ${MYCNF} sed -i "/^\[mysqld\]$/a\max_connections=151" ${MYCNF} sed -i "/^\[mysqld\]$/a\max_binlog_size=512M" ${MYCNF} sed -i "/^\[mysqld\]$/a\#binlog_ignore_db=performance_schema\\n" ${MYCNF} sed -i "/^\[mysqld\]$/a\#binlog_ignore_db=information_schema" ${MYCNF} sed -i "/^\[mysqld\]$/a\#binlog_ignore_db=mysql" ${MYCNF} sed -i "/^\[mysqld\]$/a\long_query_time=2\\n" ${MYCNF} sed -i "/^\[mysqld\]$/a\slow_query_log_file=/var/log/mysql/slow.log" ${MYCNF} sed -i "/^\[mysqld\]$/a\slow_query_log=ON" ${MYCNF} sed -i "/^\[mysqld\]$/a\skip-character-set-client-handshake\\n" ${MYCNF} sed -i "/^\[mysqld\]$/a\character-set-server=utf8" ${MYCNF} sed -i "/^\[mysqld\]$/a\log-bin=/var/lib/mysql/binlog/mysqld-bin\\n" ${MYCNF} sed -i "/^\[mysqld\]$/a\expire_logs_days=2" ${MYCNF} sed -i "/^\[mysqld\]$/a\#log_output=FILE" ${MYCNF} sed -i "/^\[mysqld\]$/a\server-id=${SERVERID}" ${MYCNF} sed -i "/^\[mysqld_safe\]$/i\\\n" ${MYCNF} cat << _EOL_ | tee -a ${MYCNF} [client] default-character-set=utf8 [mysql] default-character-set=utf8 [mysqldump] default-character-set=utf8 _EOL_ mkdir -p /var/log/mysql/ chown mysql. /var/log/mysql/ if [ ${MYSQLVER} = 5.6 ]; then mkdir -p /var/lib/mysql/binlog/ chown mysql. /var/lib/mysql/binlog/ [ ${OSVER} = 6 ] && service mysqld start [ ${OSVER} = 6 ] && chkconfig mysqld on [ ${OSVER} = 7 ] && systemctl start mysqld.service [ ${OSVER} = 7 ] && systemctl enable mysqld.service fi if [ ${MYSQLVER} = 5.7 ]; then mv /etc/my.cnf{,.DISABLED} cd /var/lib/mysql mysqld --secure-file-priv --initialize-insecure --no-defaults --user=mysql --log-error-verbosity=3 mkdir -p /var/lib/mysql/binlog/ chown mysql. /var/lib/mysql/binlog/ cd mv /etc/my.cnf.DISABLED /etc/my.cnf [ ${OSVER} = 6 ] && service mysqld start [ ${OSVER} = 6 ] && chkconfig mysqld on [ ${OSVER} = 7 ] && systemctl start mysqld.service [ ${OSVER} = 7 ] && systemctl enable mysqld.service fi if [ ${MYSQLVER} = 5.6 ]; then mysql -u root -e "SET PASSWORD FOR root@localhost=PASSWORD('${MYSQLROOTPW}');" echo [client] | tee ${HOME}/.my.cnf echo user=root | tee -a ${HOME}/.my.cnf echo password=\"${MYSQLROOTPW}\" | tee -a ${HOME}/.my.cnf cp -p ${HOME}/.my.cnf /home/${ADMINUSER}/ mysql -e "SET PASSWORD FOR root@localhost.localdomain=PASSWORD('${MYSQLROOTPW}');" mysql -e "SET PASSWORD FOR root@127.0.0.1=PASSWORD('${MYSQLROOTPW}');" mysql -e "SET PASSWORD FOR root@\"::1\"=PASSWORD('${MYSQLROOTPW}');" mysql -e "select user,host,password from mysql.user;" mysql -e "delete from mysql.user where user='';" mysql -e 'FLUSH PRIVILEGES;' mysql -e "select user,host,password from mysql.user;" echo "" fi if [ ${MYSQLVER} = 5.7 ]; then echo "USE mysql; SET PASSWORD FOR root@localhost=PASSWORD('${MYSQLROOTPW}');" | tee ${HOME}/MYSQLCOMMAND.txt mysql < ${HOME}/MYSQLCOMMAND.txt echo [client] | tee ${HOME}/.my.cnf echo user=root | tee -a ${HOME}/.my.cnf echo password=\"${MYSQLROOTPW}\" | tee -a ${HOME}/.my.cnf cp -p ${HOME}/.my.cnf /home/${ADMINUSER}/ fi ################################################################ ################################################################ # memcached Install yum -y --enablerepo=remi install memcached libmemcached-last mkdir -p /etc/sysconfig/BACKUP/ cp -p /etc/sysconfig/memcached /etc/sysconfig/BACKUP/memcached.orig #sed -i 's/MAXCONN="1024"/MAXCONN="1024"/' /etc/sysconfig/memcached sed -i 's/CACHESIZE="64"/CACHESIZE="384"/' /etc/sysconfig/memcached [ ${OSVER} = 6 ] && service memcached start [ ${OSVER} = 6 ] && chkconfig memcached on [ ${OSVER} = 7 ] && systemctl start memcached.service [ ${OSVER} = 7 ] && systemctl enable memcached.service ################################################################ ################################################################ # PHP Install yum -y --enablerepo=remi install \ gd-last \ fontconfig \ fontpackages-filesystem \ jbigkit-libs \ libX11 \ libX11-common \ libXau \ libXpm \ libjpeg-turbo \ libpng \ libtiff \ libvpx \ libxcb \ libicu yum -y --enablerepo=epel --enablerepo=remi-php56 install \ php-cli \ php-pdo \ php-pear \ php-pecl-igbinary \ php-pecl-jsonc \ php-pecl-msgpack \ php-process \ php-common \ php-fpm \ php-gd \ php-mbstring \ php-mcrypt \ php-mysqlnd \ php-opcache \ php-pecl-apcu \ php-pecl-geoip \ php-pecl-memcache \ php-pecl-memcached \ php-pecl-zip \ php-xml \ php-pecl-geoip cp -p /etc/php-fpm.d/www.conf{,.orig} sed -i 's/^user\ \= apache/\;user\ \= apache\nuser\ \=\ nginx/' /etc/php-fpm.d/www.conf sed -i 's/^group\ \= apache/\;group\ \= apache\ngroup\ \=\ nginx/' /etc/php-fpm.d/www.conf cp -p /etc/php.ini{,.orig} sed -i 's/\;date.timezone\ \=/\;##--@--##date.timezone\ \=\ndate.timezone\ \=\ Asia\/Tokyo/' /etc/php.ini ################################################################ ################################################################ # nginx Install yum -y install http://nginx.org/packages/centos/${OSVER}/noarch/RPMS/nginx-release-centos-${OSVER}-0.el${OSVER}.ngx.noarch.rpm cp -p /etc/yum.repos.d/nginx.repo{,.orig} sed -i 's/centos/mainline\/centos/' /etc/yum.repos.d/nginx.repo yum -y install nginx sed -i.orig "s/worker_processes[[:space:]]\+[0-9]\+/worker_processes auto/" /etc/nginx/nginx.conf chgrp nginx /var/lib/php/{session,wsdlcache} echo "mkdir -p /home/logs/${NEWFQDN} /home/vhosts/${NEWFQDN}/{src,public_html}" | sh chown -R nginx:root /home/vhosts chmod -R g+w /home/vhosts mkdir /etc/nginx/conf.d/BACKUP/ mv /etc/nginx/conf.d/*.conf /etc/nginx/conf.d/BACKUP/ cat << _EOL_ | tee /etc/nginx/conf.d/000_DEFAULT_${NEWFQDN}.conf server { listen 80 default_server; server_name ${NEWFQDN}; access_log /home/logs/${NEWFQDN}/access_log main; error_log /home/logs/${NEWFQDN}/error_log; location / { root /home/vhosts/${NEWFQDN}/public_html; index index.php index.html index.htm; ## WordPressのパーマリンク設定をカスタム構造に ## if (-f \$request_filename) { expires 30d; } if (!-e \$request_filename) { rewrite ^.+?(\$/wp-.*) \$1 last; rewrite ^.+?(/.*\.php)\$ \$1 last; rewrite ^ /index.php last; } ## ここまで ## } location ~ \.php\$ { root /home/vhosts/${NEWFQDN}/public_html; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME \$document_root/\$fastcgi_script_name; client_max_body_size 256M; include fastcgi_params; } error_page 404 /404.html; location = /404.html { root /usr/share/nginx/html; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } } _EOL_ ################################################################ ################################################################ # wp-cli Install curl -o ${WP} ${WPDOWNLOADURI} chmod 755 ${WP} ################################################################ ################################################################ # nginx logrotate setting mkdir -p /etc/logrotate.d/BACKUP/ cp -p /etc/logrotate.d/nginx /etc/logrotate.d/BACKUP/nginx.orig cat << _EOL_ | tee /etc/logrotate.d/nginx /var/log/nginx/*.log /home/logs/*/access_log /home/logs/*/error_log { daily missingok rotate 52 compress delaycompress notifempty create 640 nginx root sharedscripts postrotate [ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid` endscript } _EOL_ ################################################################ ################################################################ # daemons start [ ${OSVER} = 6 ] && service php-fpm start [ ${OSVER} = 6 ] && chkconfig php-fpm on [ ${OSVER} = 7 ] && systemctl start php-fpm.service [ ${OSVER} = 7 ] && systemctl enable php-fpm.service [ ${OSVER} = 6 ] && service nginx start [ ${OSVER} = 6 ] && chkconfig nginx on [ ${OSVER} = 7 ] && systemctl start nginx.service [ ${OSVER} = 7 ] && systemctl enable nginx.service ################################################################ ################################################################ # WordPress DB and USER CREATE mysql -e "CREATE DATABASE ${DBNAME} DEFAULT CHARACTER SET utf8;" mysql -e "GRANT ALL PRIVILEGES ON ${DBNAME}.* TO ${DBUSER}@localhost IDENTIFIED BY \"${DBUSERPW}\";" mysql -e "FLUSH PRIVILEGES;" ################################################################ ################################################################ # WordPress BLOG Create VHDIR=/home/vhosts/${NEWFQDN}/public_html chown -R nginx. ${VHDIR} : ${BLOGTITLE:="ICHIGEKI"} : ${BLOGADMIN:="ichigeki"} : ${BLOGPW:="$(cat /dev/urandom | tr -dc '[:alnum:]' | head -c 8)"} : ${ADMINMAIL:="webmaster@${NEWDOMAIN}"} cat << _EOL_ | tee ${HOME}/BLOGPARAM BLOGTITLE ${BLOGTITLE} BLOGADMIN ${BLOGADMIN} BLOGPW ${BLOGPW} ADMINMAIL ${ADMINMAIL} _EOL_ LATESTURI=https://wordpress.org/latest.zip : ${WPLOCALE:="en_US"} : ${WPVERSION:="$(curl -LIs ${LATESTURI} | egrep ^Content-Disposition | awk '{print $NF}' | sed -e "s/filename=wordpress-//;s/\.zip//")"} ${WP} --allow-root core download \ --locale=${WPLOCALE} \ --version=${WPVERSION} \ --path=${VHDIR}/ ${WP} --allow-root core config \ --dbname=${DBNAME} \ --dbuser=${DBUSER} \ --dbpass=${DBUSERPW} \ --path=${VHDIR}/ \ --extra-php <<PHP define('FS_METHOD', 'direct'); PHP ${WP} --allow-root core install \ --url=${NEWFQDN} \ --title=${BLOGTITLE} \ --admin_user=${BLOGADMIN} \ --admin_password=${BLOGPW} \ --admin_email=${ADMINMAIL} \ --path=${VHDIR}/ chown -R nginx:${ADMINUSER} /home/vhosts/${NEWFQDN}/ chmod -R g+w /home/vhosts/${NEWFQDN}/ ################################################################ ################################################################ # ruby development environment Install yum -y install \ byacc \ gdbm-devel \ libffi-devel \ libyaml \ libyaml-devel \ ncurses-devel \ openssl-devel \ readline-devel \ tcl \ tcl-devel \ pcre-devel \ zlib-devel echo '%_topdir %(echo $HOME)/rpmbuild' > ${HOME}/.rpmmacros mkdir -p ${HOME}/rpmbuild/{SPECS,SOURCES,BUILD,BUILDROOT,RPMS,SRPMS} mkdir -p ${HOME}/bin curl -o ${HOME}/bin/RUBYGETTER ${RUBYGETTERURI} chmod -R 700 ${HOME}/bin RUBYGETTER cp -p $(ls ${HOME}/src/ruby*) ${HOME}/rpmbuild/SOURCES/ RUBYFULLVERSION=$(ls src/ | grep ruby | sed -e "s/^ruby-//;s/.tar.gz//") RUBYABI=$(ls src/ | grep ruby | sed -e "s/^ruby-//;s/.tar.gz//;s/.[0-9]*$//") RELEASE=2 RUBYSPECFILE=${HOME}/rpmbuild/SPECS/ruby.spec curl -o ${RUBYSPECFILE} ${RUBYSPECURI} cp -p ${RUBYSPECFILE}{,.orig} sed -i "/^%define rubyver/s/[0-9.]*$/${RUBYFULLVERSION}/" ${RUBYSPECFILE} sed -i "/^%define rubyabi/s/[0-9.]*$/${RUBYABI}/" ${RUBYSPECFILE} sed -i "s/db4-devel//g" ${RUBYSPECFILE} rpmbuild -bb ${RUBYSPECFILE} [ ${OSVER} = 6 ] && RUBYRPM=${HOME}/rpmbuild/RPMS/$(uname -m)/ruby-${RUBYFULLVERSION}-${RELEASE}.el${OSVER}.$(uname -m).rpm [ ${OSVER} = 7 ] && RUBYRPM=${HOME}/rpmbuild/RPMS/$(uname -m)/ruby-${RUBYFULLVERSION}-${RELEASE}.el${OSVER}.centos.$(uname -m).rpm yum -y localinstall ${RUBYRPM} ################################################################ ################################################################ # wordmove Install gem install wordmove wordmove init cp -p Movefile{,.orig} sed -i "s/vhost.local/${NEWFQDN}/" Movefile sed -i "s/\/root/\/home\/vhosts\/${NEWFQDN}\/public_html/" Movefile sed -i "/local:/,/staging:/s/database_name/${DBNAME}/" Movefile sed -i "/local:/,/staging:/s/\"user\"/\"${DBUSER}\"/" Movefile sed -i "/local:/,/staging:/s/\"password\"/\"${DBUSERPW}\"/" Movefile sed -i "/local:/,/staging:/s/127.0.0.1/localhost/" Movefile ################################################################ # date # [ ${OSVER} = 6 ] && reboot [ ${OSVER} = 7 ] && systemctl reboot
WordPress 仕事の現場でサッと使える! デザイン教科書 (Webデザイナー養成講座)
gimpで作成した大量のxcf形式画像をコマンドラインでPNG形式に一撃変換したい場合、xcf2png コマンドを使うと便利。1枚1枚画像をクリックして開いてエクスポートするのがアホらしいくらい。
fedoraの標準yumリポジトリにあるので、何も考えず xcftools パッケージをインストールする。
$ sudo yum install xcftools
カレントディレクトリにxcfファイルしかないという前提で、一撃変換(の確認)をする。「xcf2png -o 出力ファイル.png 入力ファイル.xcf」という構文で実行する。
$ for A in $(ls); do echo xcf2png -o $(echo ${A} | sed -e "s/xcf/png/") ${A}; done
上記のfor文で期待どおりであれば
$ for A in $(ls); do echo xcf2png -o $(echo ${A} | sed -e "s/xcf/png/") ${A}; done | sh
で一撃実行。fileコマンドで確認してみると・・・
$ file 0001* 0001.png: PNG image data, 1366 x 741, 8-bit/color RGB, non-interlaced 0001.xcf: GIMP XCF image data, version 0, 1366 x 741, RGB Color
(∩´∀`)∩ワーイ できたー!