カテゴリー: IT Page 2 of 5

qmailの大量キューを送信元や送信先でフィルターして削除する方法

qmail!?って思われるかもしれないですが、勉強会とかいくと結構現役なサーバって多いみたいです。

以前、qmailの大量キューをすべて削除するという記事でqmailのキューをすべて削除する方法を書きましたが、実際の運用では削除すべき大量のメールキューの中に、削除してはいけないキューがあったりします。
今回はqmailの大量キューを送信元や送信先でフィルターして削除する方法を検証しました。

ツール類の準備

下記2つのキュー操作ツールを利用します。
両方サーバーに入れます。
両方、perlのスクリプトなので任意の場所において実行権限を付与したりパスを通したりして下さい。

・qmHandle
http://qmhandle.sourceforge.net/

tar zxvf qmhandle-1.3.2.tar.gz

・queue-fast
http://www.kawa.net/works/qmail/queue-fast.html

wget http://www.kawa.net/works/qmail/src/queue-fast.20050210.tar.gz
tar zxvf queue-fast.20050210.tar.gz
chmod 755 queue-fast.pl

送信先メールアドレスでフィルターして削除

queue-fastのみで対応可能です。

キューの確認

perl queue-fast.pl

user@domain.name宛のキューを確認

perl queue-fast.pl user@domain.name

user@domain.name宛のキューを削除
キューの削除の際はqmailを落としてください。(キューの整合性が取れなくなる可能性がある為)

perl queue-fast.pl -d user@domain.name

送信元メールアドレスでフィルターして削除

queue-fastとqmHandleを組み合わせて使います。
※厳密には送信元だけではなく送信先に含まれているものも削除されます

user@domain.nameというアドレスが関連したキューをすべて削除したい場合。
まず、queue-fastでuser@domain.nameに関連したキューのIDを一覧します。

perl queue-fast.pl | grep user@domain.name | cut -d" " -f1 | cut -d"/" -f2

qmHandle の引数にキューIDを渡してあげるとそのキューIDのキューを削除してくれます。

perl qmHandle -d22222

便利に使う為、適当なスクリプトを作成

qmailQueueDelete.sh

!/bin/sh
if [ $# -ne 1 ]; then
echo "\n"
echo "qmailQueueDelete.sh \n"
echo "usage : ./qmailQueueDelete.sh test@example.com \n"
exit 1
fi
QID=`perl queue-fast.pl | grep $1 | cut -d" " -f1 | cut -d"/" -f2`
for var in ${QID}
do
if [ ! -z "$var" ] ; then
perl qmHandle -d${var}
fi
done

qmailを停止してから、

./qmailQueueDelete.sh user@domain.name

で削除が実行されます。

VimでGo言語を書く環境を設定する

概要

Go言語をインストールして実行できる環境を作り、
VimでGo言語を書く設定をしていきます。

Goのインストール

以下のページでバイナリをダウンロードし、ホームディレクトリに設置します。
https://golang.org/dl/

wget https://storage.googleapis.com/golang/go1.3.3.linux-amd64.tar.gz
tar xvzf go1.3.3.linux-amd64.tar.gz
mv go1.3.3.linux-amd64 ~/go

Goパッケージの保存先であるディレクトリを作成します。

mkdir ~/go/packages

.bashrcなどに、以下の環境変数を設定します。

export GOROOT=~/go
export GOPATH=$GOROOT/packages
export PATH=$PATH:$GOROOT/bin

「source ~/.bashrc」で設定を有効にすると、goコマンドが使用できるようになります。

Vimの設定

goコマンドを使用して、以下のパッケージをインストールしておきます。

パッケージ 機能
gocode 入力補完
golint コーディング規約チェック
godef 定義ジャンプ

インストールコマンドは以下のようになります。

go get github.com/nsf/gocode
go get github.com/golang/lint/golint
go get code.google.com/p/rog-go/exp/cmd/godef

Goに対するVimの設定ですが、パッケージに同封されているVim設定ファイルを使用します。
上記の方法でインストールしている場合は、~/go/misc/vimに存在しています。

※現在のGoリポジトリにはmisc/vimは入っていないようです。将来的には少し違う設定になると思います。http://vim-jp.org/blog/2014/09/02/vim-go-extra.html

.vimrcに以下の設定を追記します。

filetype off
filetype plugin indent off
set runtimepath+=$GOROOT/misc/vim
filetype plugin indent on
syntax on
autocmd FileType go autocmd BufWritePre  Fmt
set rtp+=$GOPATH/src/github.com/nsf/gocode/vim
set rtp+=$GOPATH/src/github.com/golang/lint/misc/vim
set completeopt=menu,preview

これで自動補完や自動フォーマットが動作するようになります。

以下、よく使うコマンドを表にしておきます。

コマンド 意味
:Import {コマンド名} importにパッケージ名を追加
:Drop {パッケージ名} importにパッケージ名を削除
:GoDoc {パッケージ名} パッケージのドキュメントを閲覧する
:Godef {定数名/関数名など} 定義ジャンプ

参考

Vimを使ったGo言語開発手法
http://mattn.kaoriya.net/software/vim/20130531000559.htm

Go言語のインストール
http://golang.jp/install

GOPATH は適当に決めて問題ない
http://qiita.com/yuku_t/items/c7ab1b1519825cc2c06f

Go言語の開発環境構築 (Golang + Mac OS X + Vim)
http://note-of-engineer-b.blogspot.jp/2013/12/golang-setup.html

例外はきちんと書こう

PHPで、とあるリクエストに対して、xml形式でレスポンスを返すというプログラムを作成していました。

メインPHP

main.php
function main() {
// 1.DBより何か参照してくる
$rs = $child->reference();
// 2.domDocumentを利用し、xml生成する
$dom = new domDocument('1.0', 'UTF-8');
・・・省略・・・
// 3.レスポンス返す
header('Content-Type: application/xhtml+xml');
echo $dom->saveXML();
}

サブPHP

child.php
function reference() {
try {
// selectして結果返す
$rs = $dao->select('table', $columns, $where);
return $rs;
} catch (Exception $e) {
throw $e;
}
}

が期待した動作をせず、、、

Empty reply from server

みたいなエラーが返されてます。空がサーバから返されてる。。!?

何気にapacheのログを参照すると、、

child pid xxxx exit signal Segmentation fault (11)

なるエラーが!?
ググってみるとふむふむ、うーん、参照してはいけないメモリ領域を参照してるみたいで詳細を調査する場合は、コアダンプをはいてみないといけない・・・はい、レベル高いです!!
まだロジックで調べてみることがあるだろうと、気持ちを入れなおし、ごにょごにょ調べていると。。おおっ!SQLがエラーログはいてました!!

2以降の処理は、1からの正常処理しか期待していないロジックを書いていました。
きちんと例外(エラー)のことを考えないといけないですね。
メインPHPを以下のように改善しました。

改善後メインPHP

main.php
function reference() {
// 1.DBより何か参照してくる
$isSuccess = true;
try {
$rs = $child->reference();
} catch (Exception $e) {
$isSuccess = false;
}
// 2.domDocumentを利用し、xml生成する
$dom = new domDocument('1.0', 'UTF-8');
if ($isSuccess) {
// 2-1.正常処理
・・・省略・・・
} else {
// 2-2.例外処理
・・・省略・・・
}
// 3.レスポンス返す
header('Content-Type: application/xhtml+xml');
echo $dom->saveXML();
}

エラーでなくなりました。よかったです!
SQLエラーは仕方ないとして、どうしてSegmentation faultが出力されるのでしょうかね。
XML(DOM?)オブジェクトあたりが怪しい??詳細は不明、、、

例外処理もちゃんと考慮して書くようにしましょう。

Windowsでgitを使う場合の改行コード自動変換がうざい

MACWindows、両方を使って開発しているといろいろ苦しめられるところがあって
特に改行コードが辛い。

顕著なのはシェルスクリプトCGIプログラムで、
Windowsで作ったりgit pullしてきたシェルスクリプトはCRLFになるので、
そのまま仮想サーバからマウントして利用したりすると改行コードの問題で正常に動かない。
具体的には1行目のシェバンが改行コードのせいでシェバンと認識してくれないせいで正常に動かなくなります。
FTP等を利用した場合はFTPクライアントがLFに自動的に変換してくれる)

そこで、Windowsの場合はCRLFからLFに変換する必要があるのだけど変換するとgitでこんなエラーが出るようになります。

warning: LF will be replaced by CRLF in ファイル名

どうやらWindowsの場合はgitがCRLFに自動的に改行コードを変換してくるらしい。
以下を実行する事でこの自動変換をOFFにする事が出来る。

git config --global core.autoCRLF false

実際の設定はホームディレクトリ(C:\Users\ユーザー名)のディレクトリに「.gitconfig」というファイルが作られます。

[user]
name = hoge
email = hogehoge@seeds-std.co.jp
[core]
autoCRLF = false

この設定を行えばLFに変換してもgitがCRLFに変換してくる事がなくなります。

fuelphpでcsvファイルをアップロードして読み込み処理

こんにちは

WEBエンジニアのyuchiです。

前々回の記事に引き続き、開発でfuelphpからCSVファイルをアップロードして読み込みしないといけなかったので、
その時調べた方法を書きたいと思います。

まずはCSVファイルをアップロードします。

// 初期設定
$config = array(
'path' => dirname(DOCROOT).'/uploads/',
'randomize' => true,
'ext_whitelist' => array('csv'),
);
// アップロード基本プロセス実行
Upload::process($config);
// 検証
if (Upload::is_valid())
{
// 設定を元に保存
Upload::save();
// 情報をデータベースに保存する場合
$result = Model_Uploads::deliv_add(Upload::get_files());
}

configでアップロードする場所をpathに指定し、保存するファイルの拡張しを設定し保存します。
randomizeをtrueにすると保存されるファイル名がランダムにつけられます。

次にアップロードしたファイルからcsvの読み込みを行います。

foreach ($files as $file)
{
$data = file_get_contents($file['saved_to'].$file['saved_as']);
$data = mb_convert_encoding($data, 'UTF-8', 'SJIS');
$data = Format::forge($data, 'csv')->to_array();
}

csvファイルの文字コードが分からないため、文字化け防止としてmb_convert_encodingで変換します。
例としまして、ここではSJISからUTF-8に変換。

あとは、読み込んだcsvファイルのデータを表示したりするだけです。

foreach($data as $list)
{
echo $list;
}

fuelphpの機能を使えば簡単にできました。

ちなみにアップロードしたファイルを削除したい場合は、

//ファイルを削除したい場合
File::delete(dirname(DOCROOT).'/uploads/' . ファイル名);
//ディレクトリを削除したい場合
File::delete_dir(dirname(DOCROOT).'/uploads/');

を書けばOKです。

では、今日はこのあたりで!

三山崩しゲーム

名前だけ聞いても分からないかもですが、やったことのある方もたくさんいると思います。
私も授業中とかによくやりました。
最後の1つを取ったら勝ち的なゲームです。
このゲームには必勝法があるので、今回はそれを紹介します。

ルール

  1. いくつかの石を3つの山に分けます。
  2. 2人のプレイヤーは交互に1つの山から1つ以上の好きな数の石をとる。
  3. 最後の1つを取った方の勝ちヽ(´∀`。)ノ゚イェイ

必勝法

説明がちょっと難しいのですが、
それぞれの山の石の数を2進法展開して同じ基底の係数の和が全て偶数になるように石をとります。
文章で書かれてもよく分からないと思うので、PHPのコードにしてみました。

function saikyou($input) {
$order = ceil(log(max($input), 2)) + 1;
arsort($input);
foreach ($input as $k => $v) {
$binary[$k] = str_split(str_pad(decbin($v), $order, "0", STR_PAD_LEFT));
}
$key = null;
for ($i = 0; $i < $order; $i++) {
$sum = 0;
foreach ($binary as $v) {
$sum += (int)$v[$i];
}
if ($sum % 2 == 1) {
if ($key === null) {
foreach ($binary as $k => $v) {
if ($v[$i] === "1") {
$key = $k;
$binary[$key][$i] = "0";
break;
}
}
} else {
$binary[$key][$i] = (string)(1 - (int)$binary[$key][$i]);
}
}
}
ksort($binary);
foreach ($binary as $k => $v) {
$output[$k] = bindec(implode("", $v));
}
return $output;
}

$inputには配列でそれぞれの山の石の数を入れます。
↓こんな感じになります。

$input  = array(9, 2, 5);
$output = saikyou($input);  // array(7, 2, 5)

$outputは最強の石の取り方でできたそれぞれの山の石の数です。
上の例では(7,2,5)なので、9の山から石を2つ取るのが最強です。
ちゃんと2進法展開の同じ基底の係数の和が全て偶数になっているのが分かります。
山の数は3つでなくても同じですし、石の数もいくつあっても考え方は一緒です。

便利な関数がたくさんあって短いコードでスッキリ書けました。
説明の難しいこともコードにするとスッキリですね。

◯参考
三山崩しゲーム

HubotでSlackのボットを作成する

Hubotとは

Hubotは、Github社が開発したBot作成フレームワークです。
今回は、Hubotを使用してSlackボットを作成する方法をご紹介します。

Slack https://slack.com/
Hubot https://github.com/github/hubot

HubotはNode.jsのモジュールですので、Node.jsのインストールから始めます。

Node.jsのインストール

複数のNode.jsを管理するnvmコマンド経由で、Node.jsをインストールします。

nvmコマンドのインストール。

git clone git://github.com/creationix/nvm.git ~/.nvm

nvmのコマンドを使えるように、.bashrcにスクリプトを追記します。

if [[ -s ~/.nvm/nvm.sh ]]; then
source ~/.nvm/nvm.sh
fi

以上で、nvmコマンドが使えるようになります。

次にNode.jsをインストールします。
今回の例では、バージョン0.11.13をインストールします。

npm install 0.11.13
npm use v0.11.13

以上で、Node.js関連のコマンドが使えるようになります。

nvmの他の機能が気になる方は、
nvm単体で実行するとヘルプが表示されるので、そちらをご参照ください。

Hubotのインストール

npmコマンドでHubotをインストールします。
また、必要なモジュールもインストールします。

npm install -g hubot hubot-slack yo generator-hubot coffee-script

上記のコマンドでインストールしたモジュールの情報は以下のとおりになっています。

モジュール名 説明
hubot Hubot本体。hubotコマンドが使用できるようになる。
hubot-slack HubotのSlack用アダプタ。HubotをSlackに対応させるために使用する。
yo ひな形生成ツール。
generator-hubot yoでHubotプロジェクトのひな形を生成するために使用する。
coffee-script CoffeeScript。HubotのスクリプトはCoffeeScriptで記述する。

HubotでHello World

「Hello」と呼びかけたら「World」と返すボットを作成します。

まずはHubotのひな形作成します。

$ mkdir hellobot
$ cd hellobot
$ yo hubot
_____________________________
/                             \
//\              |      Extracting input for    |
////\    _____    |   self-replication process   |
//////\  /_____\   \                             /
======= |[^_/\_]|   /----------------------------
|   | _|___@@__|__
+===+/  ///     \_\
| |_\ /// HUBOT/\\
|___/\//      /  \\
\      /   +---+
\____/    |   |
| //|    +===+
\//      |xx|
? Owner: Uchiyama
? Bot name: hellobot
? Description: (A simple helpful robot for your Company)
? Bot adapter: (campfire) slack
? Bot adapter: slack

ひな形ができたら、scriptsディレクトリ下にスクリプトを作成します。
今回はscripts/helloworld.coffeeとしました。

# scripts/helloworld.coffee
module.exports = (robot) ->
robot.respond /HELLO$/i, (msg) ->
msg.send "world"

ざっくり説明すると、
robot.respond /HELLO$/i」で、正規表現で反応する文字列をマッチさせ、
msg.send “world”」で、レスポンスを返しています。

チャットからのメッセージを受信したり返信したりする処理は、Hubot側で行ってくれています。

Hubotのコンソールを立ち上げて、このスクリプトの動作確認をしてみます。
以下のコマンドを実行します。

$ bin/hubot

Heroku関連の環境変数の設定に関するエラーが出てきますが、
現状は問題ないのでエンターを押して、コマンドプロンプトを復活させます。

以下のようにHubotにメッセージを送信すると、メッセージが返ってきます。

Hubot> Hubot hello
Hubot> world!
Hubot>

このように、実際にSlack上で実行する前に、コンソールで動作確認することができます。

Slackと連携するBotを作成

SlackのIntegrationページでHubotと連携するための設定を行います。

「Hubot URL」は、Hubot設置予定のURLを設定します。

あとで参照するので、「HUBOT_SLACK_TOKEN」などの環境変数は覚えておきます。

今回のSlackボットは、Slack上で挨拶された場合に挨拶を返す仕様にします。
コードは以下のようになります。

# scripts/slack-hello.coffee
module.exports = (robot) ->
robot.hear /@hubot Hello/i, (msg) ->
username = msg.message.user.name
msg.send "Hello, " + username

robot.hear /@hubot Hello/i, (msg) ->」で、反応するメッセージを検出し、
username = msg.message.user.name」で、ユーザー名を取得し、
msg.send “Hello, ” + username」で、レスポンスしています。

このスクリプトをコンソール上で動作確認してみます。

$ bin/hubot
Hubot> hubot @hubot hello
Hubot> Hello, Shell
Hubot>

ということで、挨拶を返してくれました。

Slackと連携するBotを実行

本番でSlackと連携する場合は、実行時のオプション指定などが必要になってきます。
結論から言いますと、コマンドは以下のようになります。

HUBOT_SLACK_TOKEN=xxxxxxxxxxxxxxx \
HUBOT_SLACK_TEAM=xxxx \
HUBOT_SLACK_BOTNAME=hubot \
bin/hubot --adapter slack

HUBOT_SLACK_TOKEN」「HUBOT_SLACK_TEAM」「HUBOT_SLACK_BOTNAME」といった環境変数を設定しています。
これらはSlackのIntegration画面にありましたね。

また、–adapterオプションでアダプタ(slack)を指定しています。

これで、Hubotが立ち上がったと思います。
この状態で、Slack上に「@hubot hello」と打ち込めば返信が返ってくるはずです。

まとめ

Hubotでボットを作成する方法をご紹介しました。
scriptsディレクトリ下にスクリプトを追加していけば、
ボットの機能を増やしていけます。
慣れてくると気軽に開発できるので、ボットづくりが捗ります。
色々連携させて効率化していきましょう。

chef12になって今までのcookbookが動かなくなった

chefでサーバーの初期構築をする時、以下のコマンドでchefをインストールして

curl -L https://www.opscode.com/chef/install.sh | bash

その後、ソースをgitから持ってきてchef-soloを実行してました

chef-solo -c solo.rb -j localhost.json

ある時、chefをインストールしたらバージョン12になって、以下のようなエラーが出るようになりました。

ERROR: Cookbook loaded at path(s) [/tmp/vagrant-chef-1/chef-solo-1/cookbooks/xxxxxx] has invalid metadata: The `name' attribute is required in cookbook metadata

とか

ERROR: Cookbook hogehoge not found. If you're loading hogehoge from another cookbook, make sure you configure the dependency in your metadata

とか。。

どうやらchef 12 から cookbookのmetadata.rb内のname attributeの記述が必須になったり、重要視されるようになったようです。
具体的に上側のエラーはmetadata.rbにnameの記述がない、というエラー。
下側のエラーはmetadata.rbのnameに書かれてる名前が実際のレシピと異なる場合に出てるみたいです。
(例えばディレクトリ名がhogeなのに name が fuga と設定されていてrecipe[hoge]と呼び出した場合に上記のエラーになります)

上記のようなエラーが出た場合は
cookbookディレクトリ内にあるmetadata.rbのname部分を見直してみてください。

name             'hoge'  ←ここが重要!
maintainer       'YOUR_COMPANY_NAME'
maintainer_email 'YOUR_EMAIL'
license          'All rights reserved'
description      'Installs/Configures hoge'
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
version          '0.1.0'

ソフトウェア開発生産性の向上に向けて

個人的な話ですが、昨年は職場がかわり、その環境に慣れるための1年だったような気がします。同僚に、またよいお客様に支えられなんとか1年無事?に過ごすことができました。ありがとうございます!!感謝感謝(笑)

さて、本年は自分のことだけでなく、本題のとおり、会社全体の課題である「ソフトウェア開発生産性の向上」について考えていきたいと思っています。具体的なディテイルには落とし込めていないですが思っていることをつらつらと書き留めておきます。

私自身、いままで、様々なソフトウェア開発プロジェクトに参画させていただきました。その中で正直、このプロジェクトはうまくいった!!と実感したプロジェクトは少なかった気がします。やはり何かしら問題があって、最悪、プロジェクト崩れを起こしてしまう場合もあったと記憶しています。

では、プロジェクトを円滑に進め、生産性を向上させるためにはどうしたらよいか?・・ですが、大きく分けると以下の点に集約され、それぞれを改善することで生産性の向上が可能であると考えます。

エンジニアスキル向上

IT業界の人材不足が社会問題となっていますが、現場を見てますと個人の自己啓発や興味?に頼っている部分が大きいと思っています。簡単にいうとできる人はできるし、それなりの人はそれなりなんですね。ちなみに私はまだそれなりの部類ですが(涙)
ここを会社として底上げする必要があると考えます。基礎知識をつけたうえで、各自得意分野を身につけていく。。といった流れが望ましいと思っています。具体的には資格取得によって基礎知識を身につけて実務と勉強会で応用力を身につけるような流れになればよいです。ここは独断では実行できないので、会社と要相談です。

PDCAサイクルの徹底

PDCAの詳細についてはググってください(笑)
昨今のソフトウェア開発の短納期・低コストでのプロジェクトを回すことを優先するあまり「D」の部分ばかりがフォーカスにあたり、特に「P」「A」が疎かになっているプロジェクトが多いと思われます。
気が付けば、赤字プロジェクト・・・なんてこともあったりするので、ここを是正することで、生産性の向上を考えます。具体的には「P]「A」を主題とした会議や体制を設けることで対応できればよいと考えています。
エンジニアへの意識づけも大切です。

コミュニケーション力

当たり前のことですが、この当たり前のことが疎かになりがちです。
お客様からしたらプロジェクトの進捗状況は気になるところでしょうし、できあがったソフトウェアを動かしてみて、「こんなイメージではなかった」といった認識の相違をなくすためにはコミュニケーションは不可欠です。
プロジェクトごとの状況チェックを強化することで、疎かになっているプロジェクトがあれば是正する方向で対応できれば。と考えています。

全体的にぼんやりしていますが、今年は上記3点をよりいっそう意識してソフトウェア開発を進めていき、お客様によりよい製品を納入して喜んでいただけるようにしたいと思います。
よりディテイルなアクションプランについてもブログ上で報告できれば。と思います。(予定)

linux‘find‘コマンドのご紹介

こんにちは、サーバーインフラエンジニアの葉です。
遅くなりましたが、明けましておめでとうございます。
本年も何卒よろしくお願いいたします。

今日は、findをご紹介します。
条件を指定してファイルやディレクトリを検索するコマンドで、検索結果を別のコマンドの引数として実行することが出来ます。

find基本的使い方

[code]
find 検索開始ディレクトリ 検索条件 コマンド
[/code]

検索条件

-name

  検索するファイルを指定。

[code]
find /home/yo -name “test
[/code]
というコマンドを実行するとき
カレントディレクトリ以下に
[code]
/home/yo/test3.txt.gz
/home/yo/test6.txt
/home/yo/test1.txt.gz
/home/yo/test5.txt
/home/yo/test2.txt.gz
/home/yo/test4.txt
[/code]
-iname file

  検索するファイル名を指定。大文字小文字を区別しない以外は -name と同じ。

-atime [+-]n
n日前にアクセスされたファイル。

-atime 2 2日前にアクセスされたファイル
-atime +2 3日以前にアクセスされたファイル
-atime -2 1日以内にアクセスされたファイル

-ctime [+-]n
n日前にファイルステータスが変更されたファイル

-ctime 2 ちょうど2日前にファイルステータスが変更されたファイル
-ctime +2 3日以前にファイルステータスが変更されたファイル
-ctime -2 1日以内にファイルステータスが変更されたファイル

-mtime [+-]n
n日前に修正されたファイル

-mtime 2 ちょうど2日前に修正されたファイル
-mtime +2 3日以前に修正されたファイル
-mtime -2 1日以内に修正されたファイル

アクション

次に検索結果を引数にして実行するのに -exec というアクションを使います。使い方は、
[code]
-exec [command] {} \;
[/code]

過去n日を除き削除してみる

ホームディレクトリ以下に yo ディレクトリで過去90日ごとのファイルを作ります。

  このディレクトリの中の 90日前より古いファイルを削除してみます。いきなり 削除するのは危険なのでまずは検索だけして、目的の結果が得られたことを確認してから削除しましょう。

[code]
find /home/yo -name “test” -exec ls –axl {} \;
[/code]
[code]
-rw-r–r– 1 root root 0 9月 1 12:00 /home/yo/test1.txt
-rw-r–r– 1 root root 0 10月 1 12:00 /home/yo/test3.txt
-rw-r–r– 1 root root 11 1月 6 17:22 /home/yo/test6.txt
-rw-r–r– 1 root root 0 12月 1 12:00 /home/yo/test5.txt
-rw-r–r– 1 root root 0 11月 1 12:00 /home/yo/test4.txt
-rw-r–r– 1 root root 0 8月 1 12:00 /home/yo/test2.txt
[/code]
今日は 1月6日なので 90日前の 11月よりも古いファイル、つまり 8、9、10月のファイルが出力されたので目的の結果が得られたことが確認できたので -exec で繋げて削除します。※-okで繋げたら削除前、削除確認あります。

[code]
find /home/yo -name “test” -exec rm -f {} \;
[/code]
もう一回検索だけして、
[code]
find /home/yo -name “test” -exec ls –axl {} \;
[/code]
[code]
-rw-r–r– 1 root root 11 1月 6 17:22 /home/yo/test6.txt
-rw-r–r– 1 root root 0 12月 1 12:00 /home/yo/test5.txt
-rw-r–r– 1 root root 0 11月 1 12:00 /home/yo/test4.txt
[/code]
成功しました。

まとめ

find コマンドは本当に便利です。特に大量ファイルを削除とか圧縮するときに、めっちゃ使いやすいです。
ぜひ使いこなしてください。

Page 2 of 5

© SEEDS Co.,Ltd.