カテゴリー: UNIX/Linux

  • 【Linux】grepの否定で検索【vオプション】

    grepの否定の覚書です。

    結論から言うと、grepコマンドに、-v オプションをつけてやると否定の検索ができます。

    ことの顛末も書いておきます。

    HTMLでリンクを記述する場合には、パラメーターの繋ぎに使う&を実体参照として、& と記述しなければならない。

    今回は、そのチェックのために、複数ディレクトリに有る500ほどのファイルに存在する&および&を確認しようと思った次第です。

    そこで、まずは、次のコマンドで、&の存在するファイルを確認。

    grep -n '&' */*

    こうしてやると、&を含む行が表示されますが、&のあるすべての行がすべて表示されるので、&が実体参照で正しく記述されているかの確認が困難です。

    そこで、grepのAND検索と否定を利用して絞り込みをしていきます。

    grep '&' */* | grep -vn '&&'

    絞込みは、パイプ(|)を使います。また、否定には、-v オプションを使います。

    こうしてやることで、&&の行を除外して検索できます。

    同様に、次のようにします(実質1行)。

    grep '&' */* | grep -v '&&' | grep -v 'nbsp' |
    grep -v 'amp' | grep -v 'gt' | grep -nv 'lt'

    これで、&&や他の実体参照を除外できます。

    ただし、これだと、&と実体参照が有る場合、&単独のものも表示されないので、他にもgrepをして確認します。

    grep '&' */* | grep -n 'href'

    こうしてやると&がある行で、かつ、リンクを作っているであろう行を絞り込み検索できます。

    その他、いろいろ試してみて、リンク文字列に、&が単独で利用されていないか確認します。

    もっとスマートなやり方もあると思いますが、急ぎの確認でざっと見るのにはこれで十分でした。

    他のやり方があれば、コメントくださるとありがたいです。

    なお、最初は、grepと正規表現での否定の検索を考えましたが、-v オプションの方が簡単だと思います。正規表現は難しい・・・。

  • 【Linux】MySQLをgzipからインポートする方法【CORESERVER】

    MySQLのデータをgzip形式でエクスポートした場合、今度は、逆にインポート処理が必要になる場合があります。

    そこで、ここでは、gzip形式のバックアップファイルから、MySQLデータをリストアしてインポートする方法を覚書しておきます。

    なお、使用サーバーは、CORESERVERです。また、お約束ですが、ご利用は、自己責任でお願いします。あと、もちろん、phpMyAdminからインポートする方法等もありますが、ここでは取り上げません。

    ■ SSHでコマンドラインから実行する方法

    まず、SSHログインしていて、コマンドラインから実行するには次のコマンドでインポートが可能です。

    zcat /virtual/yours/backup/sample.gz |
    mysql -h localhost -u user --password=pass your_db

    上記スクリプトは、実質1行です。また、赤字は、ユーザー依存のデータであり、適当な値に置き換えが必要です。

    簡単に解説しておくと、zcatコマンドで、gzファイル(絶対パス)を開き読み込みます。その後、パイプ(|)でmysqlコマンドに渡し、読み込んだデータ(SQL)を処理します。

    SSHでコマンドラインからインポートすると処理が軽いので短時間でインポートが済むメリットがあります。

    ■ CRONから自動実行する方法

    次に、上記スクリプトを改良して、CRONから、実行できるようにしたスクリプトを紹介します。使い方としては、毎日バックアップしたデータから、日毎の最新データを毎日、自動的にインポートする処理等が考えられます。

    なお、これもCORESERVERで実行する場合です。shファイルとして保存し、CRON設定画面で処理ができるようにしておきます。例えば、import.shと保存して、CRON設定画面でファイル等を指定します。

    #!/bin/sh
    
    DATE=`date -d '1 days ago' +'%Y%m%d'` 
    EXT=.gz
    
    zcat /virtual/yours/db_backup/$DATE$EXT | 
    /usr/local/mysql/bin/mysql -h localhost
      -u user --password=pass your_db
    
    exit

    ピンクの文字は、bashの変数となっています。変数の前後にはスペースは入れません。また、gzファイルは、20140227.gzのように日付をファイル名にしておきます。

    ここでは、1日前のデータを利用したいので、’1 days ago’を指定していますが、これを消せば、当日のデータがインポートされます。

    最初のスクリプトと異なるのは、mysqlコマンドが絶対パスになっていることです。CORESERVERでは、CRONから実行する場合、絶対パスにしないと動作しませんでした。パスを解決できないからと思われます。

    なお、コマンドのパスを調べるには、whichコマンドで確認することができます。

    以上、MySQLをgzipからインポートする方法の覚書でした。

  • 【PHP】サーバーの負荷を定期的にチェックする方法

    サーバーの負荷を定期的に調べて、メールで通知するための方法です。

    まず、定期的にスクリプトを実行するので、CRONを利用します。CRONの使い方は、こちらの過去記事を参照。
    http://webmaster.chielog.com/php/39.html

    サーバーの負荷を調べるには、Linuxのuptimeコマンドを利用します。

    もっとも、ここでは、CRONでshを起動し、そこからPHPスクリプトを実行する方法をとります。

    そのPHPスクリプトですが、次のようになります。

    <?php
    
    //1.uptimeコマンドを実行
    $output = `uptime`;
    
    //2.結果を分割
    $pieces = explode(":", $output);
    
    //3.宛先・タイトル代入
    $to      = 'name@example.com;
    $subject = '(server no)-- '.$pieces[3];
    
    //4.送信処理
    mail($to, $subject, $output);
    
    //end
    

    ■1
    上記のLinuxコマンドは、バッククオートで実行していますが、shell_exec()と同様なので、どちらを使っても良いと思います。

    ■ 2
    結果を分割していますが、件名に負荷の値だけを表示したいので、時間の区切り文字で結果を分割して、最後の値だけを、3で付け足しています。メールの中身を見ずに、タイトルだけで、負荷の値を知ることが出来ます。

    ■ 3
    件名には、負荷の値を表示するようにしています。

    ■ 4
    メールの送信処理です、特に日本語は含まれないので、mail関数を使っています。

    PHPスクリプトは以上です。

    後は、このスクリプトをCRONから実行するために、CRONタブの設定をします。上記リンクを参考にどうぞ。

    また、shスクリプトもあわせて設置してください。

    PHPスクリプト、CRONの設定、shスクリプトの設置がすめば、設定したメールアドレス宛に、サーバーの負荷の値が定期的に送信されてきます。

    ちなみに、当該メールの到着時間を見れば、メールサーバーの調子も推測できます。遅延したりした場合には、対処が必要になるでしょう。

    以上です。

  • 【uptime】時々、役に立つLinuxコマンド【top】

    レンタルサーバーを借りていて、サーバーが重かったりすると、どのくらいの負荷が現在かかっているのか気になることがあります。

    そうした時に役立つのが、次の二つのコマンドです。

    ■ uptime

    ■ top

    uptimeは、現在の負荷を簡略的に表示してくれます。左から、
    「現在時刻 稼働時間 ログインユーザー数 ロードアベレージ」

    なお、load averages は システムの平均負荷であり、左から、1分、5分、15分の平均負荷を見ることができます。

    topは、サーバーのタスク(稼働状況)を表示するコマンドです。

    uptimeで表示されたものに加え、CPUやメモリー等の状態も把握できる上、個別のプロセスの詳細も表示されます。

    最後にもう一つ

    ■ wget

    例:wget -r http://exmalple.com
    rオプションで ルートディレクトリ以下を取得

    wget は、指定されたurlのファイルを取得します。

    たとえば、興味のあるWEBサイトのurlを指定して、wgetコマンドを発行すると、当該サイトのファイルを取得することができます。

    一度、取得したファイルはオフラインで読むことができるので便利です。

  • 【Linux】複数ディレクトリ内のファイル拡張子の変更

    現在、WEBサーバーとして、CORESERVERを利用しているのですが、将来的にはコストパフォーマンスにより他のサーバーに移転することも考えています。

    移転先有力候補には、さくらインターネットがあるのですが、さくらでは、原則として.htmlファイルを.phpファイルとして動作させることができないことを、最近知りました。

    標準では、以下の一文を.htaccessに記述すれば.htmlファイルでも.phpとして動かすことができます。

    AddType application/x-httpd-php .html

    さくらインターネットでは、この方法が使えないということです。

    それならば、現在、開発中のサイトについては、すべて.phpファイルとして作成した方がよいかと思い開発サイトの拡張子の変更作業を行いました。

    ■拡張子変更の初歩

    あるディレクトリ内のファイルの拡張子を変更(html→php)するには以下のコマンドを使います。

    for i in *.html ; do mv $i ${i/\.html/\.php}; done

    (なお、後半のドットの前はエスケープ(半角¥)しています。しなくてもよいかもしれませんが。)

    ただし、これだとディレクトリが複数有る場合には対応が面倒です。

    一括で複数ディレクトリ内のファイル拡張子を変更するには以下のコマンドを使います。

    find . -type f -name "*.html" -print0 | 
    while read -r -d '' file; 
    do mv "$file" "${file%%.html}.php"; done

    上記コマンドは実質一行で行います。

    これで、ファイルの拡張子の変更はできたのですが、次に、ファイル内のリンクパスやアクション先の文字列の変更を行います。

    つまり、ファイルテキスト内の、.htmlという文字列を.phpに変更します。

    変更するには以下のコマンドを使います。

    find */* | xargs perl -pi -e "s/\.html/\.php/g"

    上記コマンドの注意点は、ドットをエスケープしてやることです。.はメタ文字なので、バックスラッシュでエスケープしてやります。半角の¥でエスケープします。

    これでファイル内のテキストも変更できました。

    ただし、確認するとなぜか.htaccess内の文字列が変更されていませんでした。仕方ないのでここは手作業で置換しました。

    なお、お約束ですが、実行は自己責任で。作業前にはバックアップを取って置く事おをオススメします。

    cp -r hogedir backdir

    上記コマンドでhogedirのバックアップをbackdirとして作成できます。作業前にどうぞ。

    以上です。