表題の操作をスキャン後のファイルに自動処理で行いたい。
不要なページの削除方法
◆pdftkコマンドを使う
今回はスキャナの為の台紙である一枚目を取り除きたいので、
$ pdftk origin.pdf cat 2-end output modify.pdf
となる。
2枚目だけを取り除きたい場合は、
$ pdftk origin.pdf cat 1 3-end output modify.pdf
オプションの詳細
解像度の変更
◆gsコマンドを使う
オプションが非常に長いが、中途半端に記載すると
処理に時間がかかったので、ファイルサイズ軽減に係るところは全部表記した。
$ gs -q -sOutputFile="/home/user0463/out.pdf" -sDEVICE=pdfwrite -dNOPAUSE -dBATCH -dSAFER -dQUIET -dCompatibilityLevel=1.4 -sColorConversionStrategy=GRAY -dProcessColorModel=/DeviceGray -dGrayImageDownsampleType=/Bicubic -dGrayImageResolution=72 -dMonoImageDownsampleType=/Bicubic -dMonoImageResolution=72 -dColorImageDownsampleType=/Bicubic -dColorImageResolution=72 -dEmbedAllFonts=false -dSubsetFonts=false -dPDFSETTINGS=/printer /home/user0463/moto.pdf
解説
-q 実行時にメッセージを出力しない。
-sOutputFile="出力先ファイル記述"
-sDEVICE=pdfwrite pdf以外の設定 gs -hで確認できる。
-dNOPAUSE ページごとに処理に一時停止をさせない。(これを書かないと遅くなる)
-dBATCH 一連処理させる。
-dSAFER deletefileとrenamefileオペレータを無効
-dQUIET 標準出力への情報を表示しない。
-dCompatibilityLevel=1.4 1.3~1.6まで定義可
-sColorConversionStrategy=GRAY GRAY,CMYK,RGBを指定
-dProcessColorModel=/DeviceGray DeviceGray,DeviceCMYK,DeviceRGBを指定
-dGrayImageDownsampleType=/Bicubic /Subsample, /Average, /Bicubicを指定
-dGrayImageResolution=72 解像度を指定 dpiを指定デフォルト72
-dMonoImageDownsampleType=/Bicubic /Subsample, /Average, /Bicubicを指定
-dMonoImageResolution=72 解像度を指定 dpiを指定デフォルト72
-dColorImageDownsampleType=/Bicubic /Subsample, /Average, /Bicubicを指定
-dColorImageResolution=72 解像度を指定 dpiを指定デフォルト72
-dEmbedAllFonts=false フォントを埋め込むか? true,falseを指定
-dSubsetFonts=false 標準フォントを埋め込むか? true,falseを指定
-dPDFSETTINGS=/printer /screen, /ebook, /printer, /prepress, /defaultを指定
PDFSETTINGS は 低解像度← screen,ebook,printer,prepress →高解像度
defaultは元データを参照するようである。
あとは、シェルスクリプトに記載して、cron や inotifywait
で 自動処理させれば良い。
gsコマンドは端折って記載するより全部書いたほうが早いと云うのが面白い。
2019/06/17
2019/05/17
raspberrypi3のカメラを使ってメール応答型のスクリプト node.jsを活用
やりたいこと
メールを受信すると、raspberrypi3のカメラで撮影し、
メールに添付して指定のメールアドレスに送信するスクリプト。
子供や愛犬の見守りなど目的は同じになるが、
玄関の施錠をしたか?を最寄りの駅で気になった場合に
万が一の為に戻りたくないので作成。
玄関が開き戸だったら、もっといろいろな仕掛けができたのだが・・・。
補足
メール部分は自分でサーバ建てるのが大変なので、
Gmailを利用し、node.jsを使ってメールの送信を常に監視し、
監視中にメールが来るとそれをトリガーにして
カメラで撮影、メールを送信する。
node.jsは『非同期スクリプト』であるため、
fs等を使う場合は、同期させた処理を行う必要がある。
ここで、嵌ってしまった・・・。
カメラの処理に時間がかかり、ファイルが生成される前に
メール送信のためのファイル加工が動作してしまい、
エラーが返って来てしまうので、
別々に動作確認が終わったら、promise 等で同期処理をさせる。
前提
・raspberry-pi3のカメラモジュールを認識済み
・Gmailのアカウント取得、安全性の低いアプリの許可」を有効にしてある。
・nodeが動かせること
◆◆◆成果物◆◆◆
'use strict';
var inbox = require('inbox');
//var nodemailer = require('nodemailer');
//var iconv = require('iconv');
//var conv = new iconv.Iconv("UTF-8", "UTF-8");
const simpleParser = require('mailparser').simpleParser;
var client = inbox.createConnection(false, 'imap.gmail.com', {
secureConnection: true
,auth: {
user:'Gmailアカウント@gmail.com'
,pass:'Gmailパスワード'
}
});
client.on('connect', function() {
console.log('connected');
client.openMailbox('INBOX', function(error) {
if (error) throw error;
});
});
client.connect();
client.on("new", function(message) {
console.log('日時:' + message.date);
console.log('送信者:' + message.from.name + '-' + message.from.address);
console.log('タイトル:' + message.title);
var stream = client.createMessageStream(message.UID);
simpleParser(stream)
.then(mail=> {
console.log('本文(HTMLテキスト):' + mail.textAsHtml);
})
.catch(err=> {
console.log(err);
});
//node.jsはデフォルトで非同期処理を行うため、
//asyncを用いてカメラがsnap.jpgを生成するのを待ち
//Gmailの送信(snap.jpgの添付)、snap.jpgの削除を行っている
//pi-cameraでは上書き保存ができないため、メール送信後に削除しておく。
const async = require('async'); //同期処理のためasync呼び出す
async.series([
function(callback) {
console.log('カメラの処理開始');
//pi-camera の動作ここから
const PiCamera = require('pi-camera');
const myCamera = new PiCamera({
mode: 'photo',
output: `${ __dirname }/snap.jpg`,
width: 640,
height: 480,
nopreview: true,
});
myCamera.snap()
.then((result) => {
// Your picture was captured
})
.catch((error) => {
// Handle your error
});
//pi-camera の動作ここまで
//安全をみて7秒ディレイ
setTimeout(callback, 7000);
}, function(callback) {
console.log('メールの返信開始');
//Gmailで送信ここから
var nodemailer = require('nodemailer')
var fs = require('fs');
// メッセージ内容
var message = {
from : '送信元@gmail.com',
to : '送信先@gmail.com',
subject : 'Reply to request',
text : 'Reply to request,Picture of the Pi-Camera !',
attachments : [{
filename: 'snap.jpg',
content: fs.readFileSync('snap.jpg') //カメラのデータ生成待ち
}]
};
var smtpConfig = {
host: 'smtp.gmail.com',
port: 465,
secure: true, // SSL
auth: {
user : 'Gmailアカウント@gmail.com',
pass : 'Gmailパスワード'
}
};
var transporter = nodemailer.createTransport(smtpConfig);
transporter.sendMail(message, function(err, response) {
console.log(err || response);
});
//ファイル削除
try {
fs.unlinkSync('snap.jpg');
console.log('snap.jpgを削除しました。');
} catch (error) {
throw error;
}
//Gmailで送信ここまで
setTimeout(callback, 1000);
}, function(callback) {
return console.log('処理終了');
}
], function(err, results) {
if (err) {
return console.log('err[' + err + ']');
}
});
}); // client.connect() を閉じる。
コマンド自体はプロンプト状態なので停止はcrtl+Zにて行う。
sshで操作する場合は、forever等で動かさないと、ターミナル閉じた瞬間に
Killされるので注意が必要。
◆◆動作部分解説◆◆
◆メール受信トリガー部分◆
node.jsのパッケージインストール
$ npm install inbox
$ npm install mailparser
まんま、@hideito2000様の掲載内容を使わせていただいた。
//ソース
client.on("new", function(message) {
console.log('日時:' + message.date);
console.log('送信者:' + message.from.name + '-' + message.from.address);
console.log('タイトル:' + message.title);
var stream = client.createMessageStream(message.UID);
simpleParser(stream)
.then(mail=> {
console.log('本文(HTMLテキスト):' + mail.textAsHtml);
})
.catch(err=> {
console.log(err);
});
//この部分にカメラ処理とメール送信を組み込む
});
//ソースここまで
◆pi-cameraのインストール◆
メールを受信すると、raspberrypi3のカメラで撮影し、
メールに添付して指定のメールアドレスに送信するスクリプト。
子供や愛犬の見守りなど目的は同じになるが、
玄関の施錠をしたか?を最寄りの駅で気になった場合に
万が一の為に戻りたくないので作成。
玄関が開き戸だったら、もっといろいろな仕掛けができたのだが・・・。
補足
メール部分は自分でサーバ建てるのが大変なので、
Gmailを利用し、node.jsを使ってメールの送信を常に監視し、
監視中にメールが来るとそれをトリガーにして
カメラで撮影、メールを送信する。
node.jsは『非同期スクリプト』であるため、
fs等を使う場合は、同期させた処理を行う必要がある。
ここで、嵌ってしまった・・・。
カメラの処理に時間がかかり、ファイルが生成される前に
メール送信のためのファイル加工が動作してしまい、
エラーが返って来てしまうので、
別々に動作確認が終わったら、promise 等で同期処理をさせる。
前提
・raspberry-pi3のカメラモジュールを認識済み
・Gmailのアカウント取得、安全性の低いアプリの許可」を有効にしてある。
・nodeが動かせること
◆◆◆成果物◆◆◆
'use strict';
var inbox = require('inbox');
//var nodemailer = require('nodemailer');
//var iconv = require('iconv');
//var conv = new iconv.Iconv("UTF-8", "UTF-8");
const simpleParser = require('mailparser').simpleParser;
var client = inbox.createConnection(false, 'imap.gmail.com', {
secureConnection: true
,auth: {
user:'Gmailアカウント@gmail.com'
,pass:'Gmailパスワード'
}
});
client.on('connect', function() {
console.log('connected');
client.openMailbox('INBOX', function(error) {
if (error) throw error;
});
});
client.connect();
client.on("new", function(message) {
console.log('日時:' + message.date);
console.log('送信者:' + message.from.name + '-' + message.from.address);
console.log('タイトル:' + message.title);
var stream = client.createMessageStream(message.UID);
simpleParser(stream)
.then(mail=> {
console.log('本文(HTMLテキスト):' + mail.textAsHtml);
})
.catch(err=> {
console.log(err);
});
//node.jsはデフォルトで非同期処理を行うため、
//asyncを用いてカメラがsnap.jpgを生成するのを待ち
//Gmailの送信(snap.jpgの添付)、snap.jpgの削除を行っている
//pi-cameraでは上書き保存ができないため、メール送信後に削除しておく。
const async = require('async'); //同期処理のためasync呼び出す
async.series([
function(callback) {
console.log('カメラの処理開始');
//pi-camera の動作ここから
const PiCamera = require('pi-camera');
const myCamera = new PiCamera({
mode: 'photo',
output: `${ __dirname }/snap.jpg`,
width: 640,
height: 480,
nopreview: true,
});
myCamera.snap()
.then((result) => {
// Your picture was captured
})
.catch((error) => {
// Handle your error
});
//pi-camera の動作ここまで
//安全をみて7秒ディレイ
setTimeout(callback, 7000);
}, function(callback) {
console.log('メールの返信開始');
//Gmailで送信ここから
var nodemailer = require('nodemailer')
var fs = require('fs');
// メッセージ内容
var message = {
from : '送信元@gmail.com',
to : '送信先@gmail.com',
subject : 'Reply to request',
text : 'Reply to request,Picture of the Pi-Camera !',
attachments : [{
filename: 'snap.jpg',
content: fs.readFileSync('snap.jpg') //カメラのデータ生成待ち
}]
};
var smtpConfig = {
host: 'smtp.gmail.com',
port: 465,
secure: true, // SSL
auth: {
user : 'Gmailアカウント@gmail.com',
pass : 'Gmailパスワード'
}
};
var transporter = nodemailer.createTransport(smtpConfig);
transporter.sendMail(message, function(err, response) {
console.log(err || response);
});
//ファイル削除
try {
fs.unlinkSync('snap.jpg');
console.log('snap.jpgを削除しました。');
} catch (error) {
throw error;
}
//Gmailで送信ここまで
setTimeout(callback, 1000);
}, function(callback) {
return console.log('処理終了');
}
], function(err, results) {
if (err) {
return console.log('err[' + err + ']');
}
});
}); // client.connect() を閉じる。
コマンド自体はプロンプト状態なので停止はcrtl+Zにて行う。
sshで操作する場合は、forever等で動かさないと、ターミナル閉じた瞬間に
Killされるので注意が必要。
◆◆動作部分解説◆◆
◆メール受信トリガー部分◆
node.jsのパッケージインストール
$ npm install inbox
$ npm install mailparser
まんま、@hideito2000様の掲載内容を使わせていただいた。
//ソース
client.on("new", function(message) {
console.log('日時:' + message.date);
console.log('送信者:' + message.from.name + '-' + message.from.address);
console.log('タイトル:' + message.title);
var stream = client.createMessageStream(message.UID);
simpleParser(stream)
.then(mail=> {
console.log('本文(HTMLテキスト):' + mail.textAsHtml);
})
.catch(err=> {
console.log(err);
});
//この部分にカメラ処理とメール送信を組み込む
});
//ソースここまで
◆pi-cameraのインストール◆
$ npm install pi-camera
作成者のページのサンプルをそのまま使う
//ソース
const PiCamera = require('pi-camera');
const myCamera = new PiCamera({
mode: 'photo',
output: `${ __dirname }/snap.jpg`,
width: 640,
height: 480,
nopreview: true,
});
myCamera.snap()
.then((result) => {
// Your picture was captured
})
.catch((error) => {
// Handle your error
});
//ソースここまで
◆nodemailer でメールを送信させるので、インストール◆ $ npm i -D nodemailer
ソースは皆さまの内容を参照させていただいた。
ありがとうございます。
//ソース
var mailer = require('nodemailer');
mailer.SMTP = {
host: 'smtp.gmail.com',
port: 465,
secure: true, // SSL
auth: {
user : 'Gmailのid@gmail.com,
pass : 'Gmailのパスワード'
}
};
fs.readFile("./snap.jpg", function (err, data) {
mailer.send_mail({
sender: '送信元@gmail.com',
to: '送信先@gmail.com',
subject: 'snapshot-Ent!',
body: 'Snapshot of the Entrance !',
attachments: [{'filename': 'snap.jpg', 'content': picture}]
}), function(err, success) {
if (err) {
// Handle error
}
}
});
//ソースここまで
◆ファイルの削除◆
try {
fs.unlinkSync('snap.jpg');
console.log('snap.jpgを削除しました。');
} catch (error) {
throw error;
}
fsは非同期だが、同じコマンドであれば記載の順に動くようだ。
駄目な場合は、 async の回数を増やせば良い。
◆同期処理◆
async.series([
function(callback) {
console.log('処理開始');
このcallback間にメソッドを記載
setTimeout(callback, 1000);
}, function(callback) { console.log('処理2開始');
setTimeout(callback, 1000);
});
}, function(callback) {
return console.log('処理終了');
}
],
期待した動きができたので、満足。
2019/05/08
CentOS(RedHat系) rootパスワードが分からない際の対策
CentOS7以降、レスキューモード(旧シングルユーザモード)、エマージェンシーモード
ともにrootパスワードを要求される。
しかし、管理者が不慮のアクシデントで対応できない状況となった際に、
どうしてもrootパスワードが必要なことが生じることがある。
今回、どうにもならない状況になってしまったため、操作した。
Procedure 25.6. Resetting the Root Password Using rd.break
いくつか手順を発見したので、残しておく
1.GRUB(ブートするOSを選択する画面)で「e」を押す。
2.rhgb quiet LANG*** を消して、systemd.debug の後ろにrw init=/bin/bashを加える。
3.Ctrl+x でboot開始
としてパスワードを強制上書きできるが、リラベリングに、えらく時間がかかった。
以下の手順でも再設定はできたので、間違いではないと思われる。
mozcの設定がうまくいっていなかったのかもしれないが、自分で構築していないので
どうにもならなかった・・・。
1.GRUB(ブートするOSを選択する画面)で「e」を押す。
2.rhgb quiet を消して、 rd.break enforcing=0 を書き加える。
(linux16の行と書いてあるが、同じ位置で問題なかった。)
※ enforcing=0はSELinuxの制御をオミットする意味とのこと。
3.Ctrl+x でboot開始
4.switch_root:/# mount -o remount,rw /sysroot を入力しエンター
※ファイルシステムを書き換え可能にする。
5.switch_root:/# chroot /sysroot を入力しエンター
※ファイルシステムをroot管理にする
6.sh-4.2# passwd でrootパスワードを設定する。
7.sh-4.2# exit を入力しエンター
8.switch_root:/# exit を入力しエンター
9.再起動し通常のユーザでログイン後ターミナルで新しいパスワードでroot化する。
10.# restorecon -v /etc/shadow を入力しエンター
※rd.breakで操作したrootパスワード格納のshadow定義をデフォルトにする。
※上記をしないと、再起動時にパスワードを誰も読めずログインできなくなる。
11.# setenforce 1 を入力しエンター
※SELinuxを有効にしておく。
以降は、再起動しても問題ない。
一般ユーザのパスワードはそのままで、rootは新しいパスワードが有効になる。
LUKS(Linux Unified Key Setup)を利用している場合は、
上記の操作を開始する時点でパスワードやファイルによる解除が必要となるそうだが、
LUKS は、膨大な (RHEL 7 では 512 文字) 平文テキストのパスフレーズと、非常に大きな (RHEL 7 では 8 MiB) のキーファイルを許可しているそうなので、
導入には、配慮が必要と改めて感じた。
ともにrootパスワードを要求される。
しかし、管理者が不慮のアクシデントで対応できない状況となった際に、
どうしてもrootパスワードが必要なことが生じることがある。
今回、どうにもならない状況になってしまったため、操作した。
Procedure 25.6. Resetting the Root Password Using rd.break
いくつか手順を発見したので、残しておく
1.GRUB(ブートするOSを選択する画面)で「e」を押す。
2.rhgb quiet LANG*** を消して、systemd.debug の後ろにrw init=/bin/bashを加える。
3.Ctrl+x でboot開始
4.bash-4.2# touch /.autorelabel でSELinuxを有効にする
5.bash-4.2# passwd でrootパスワードを設定する。
6.bash-4.2# exec /sbin/init 通常モードへ移行する。
6.bash-4.2# exec /sbin/init 通常モードへ移行する。
考察
switch_root:/# exit の再起動がうまくないようだ。
switch_root:/# exit の再起動がうまくないようだ。
rd.break enforcing=0 と宣言しなくとも、SELinuxは無効化される様子。
passwd <管理ユーザ>としてパスワードを強制上書きできるが、リラベリングに、えらく時間がかかった。
以下の手順でも再設定はできたので、間違いではないと思われる。
mozcの設定がうまくいっていなかったのかもしれないが、自分で構築していないので
どうにもならなかった・・・。
1.GRUB(ブートするOSを選択する画面)で「e」を押す。
2.rhgb quiet を消して、 rd.break enforcing=0 を書き加える。
(linux16の行と書いてあるが、同じ位置で問題なかった。)
※ enforcing=0はSELinuxの制御をオミットする意味とのこと。
3.Ctrl+x でboot開始
4.switch_root:/# mount -o remount,rw /sysroot を入力しエンター
※ファイルシステムを書き換え可能にする。
5.switch_root:/# chroot /sysroot を入力しエンター
※ファイルシステムをroot管理にする
6.sh-4.2# passwd でrootパスワードを設定する。
7.sh-4.2# exit を入力しエンター
8.switch_root:/# exit を入力しエンター
9.再起動し通常のユーザでログイン後ターミナルで新しいパスワードでroot化する。
10.# restorecon -v /etc/shadow を入力しエンター
※rd.breakで操作したrootパスワード格納のshadow定義をデフォルトにする。
※上記をしないと、再起動時にパスワードを誰も読めずログインできなくなる。
11.# setenforce 1 を入力しエンター
※SELinuxを有効にしておく。
以降は、再起動しても問題ない。
一般ユーザのパスワードはそのままで、rootは新しいパスワードが有効になる。
LUKS(Linux Unified Key Setup)を利用している場合は、
上記の操作を開始する時点でパスワードやファイルによる解除が必要となるそうだが、
LUKS は、膨大な (RHEL 7 では 512 文字) 平文テキストのパスフレーズと、非常に大きな (RHEL 7 では 8 MiB) のキーファイルを許可しているそうなので、
導入には、配慮が必要と改めて感じた。
2019/01/17
NTT αNXⅡ v4.00 webシステム設定 のjava
NTT αNXⅡ v4.00 webシステム設定
会社がNTTのネットコミュニティシステムαNXⅡを利用しているのだが、
ブラウザ上で電話帳や電話機の名称等の設定ができる。
javaのバージョンによっては動作しないので、
少し調べてみたので、オボエガキ
少し古い、αNX typeLのマニュアルの200ページくらいに
「次世代のJava Plug-inを有効にする 」設定を無効にする必要があると書いてある。
ところが、Oracleで確認すると、
末尾に
とあり、 Java Pluginが利用できなくなっている。
あわせて、次世代のJava Plug-inを有効無効の制御ができなくなったようだ。
一度、古めの6をインストールして、Webシステム設定を動作できる状況にしてから、
JDK8等をインストールすると両立できた。
会社がNTTのネットコミュニティシステムαNXⅡを利用しているのだが、
ブラウザ上で電話帳や電話機の名称等の設定ができる。
javaのバージョンによっては動作しないので、
少し調べてみたので、オボエガキ
少し古い、αNX typeLのマニュアルの200ページくらいに
「次世代のJava Plug-inを有効にする 」設定を無効にする必要があると書いてある。
ところが、Oracleで確認すると、
Changes in Java SE 6u171 b31
Please note that fixes from prior BPR (6u161 b32) are included in this version.末尾に
Known Issues
deploy
Windows - There is a non-functional Java icon in control panel after installing 6u171 or 7u161
Deployment features in 6u171 and 7u161 have been removed. Installing a
version of the JRE that has deployment technologies support AFTER
having installed the current JRE will cause the Windows Control Panel to
display a non-functional Java Control panel icon.
JDK-8185373 (not public)
とあり、 Java Pluginが利用できなくなっている。
あわせて、次世代のJava Plug-inを有効無効の制御ができなくなったようだ。
一度、古めの6をインストールして、Webシステム設定を動作できる状況にしてから、
JDK8等をインストールすると両立できた。
2018/11/16
postfix メールキューのエラー 大量のメールを誤送信してしまい、遅延がひどい場合の措置
サーバ内のメール転送プログラム実行中にエラーが生じた際に、
エラー警告メールを送信し、エスケープする処理を盛り込んだのだが、
エスケープの記述をしくじり、エンドレス送信が生じてしまった。
2時間程経過した際に以上に気づき、即座にプログラムは停止させ、/var/spool/mail/配下の指定アドレスの中身は処理したのだが、
postfixのキューに大量の残骸が残ってしまった。
遅延の遅延の遅延を繰り返し、頑張って送ってきてはいるが、
1万数千単位のメールが何時までも送られてくるため、当該ユーザの
通常のメールにも遅延が生じてしまっている状態。
そこで、postfixのキューを何とかして、通常の状態に戻してみた。
幸い、該当のメールのサイズが2kBと非常に小さいもので、他の遅延が殆どなかったので、
さらっと内容を確認して、該当のメールだけを削除する。
qmgr キューマネージャーにてメッセージはキューを通過する。
格納されている先
既に、 /var/spool/mail/配下の指定アドレスの中身は処理済みの場合、
問題は、
これで、正常な状態に戻っている(はず)
小生の環境では、これで正常に配信されるようになった。
この方の解説が非常にわかりやすかった。ありがとうございます。
kazupon.com様
エラー警告メールを送信し、エスケープする処理を盛り込んだのだが、
エスケープの記述をしくじり、エンドレス送信が生じてしまった。
2時間程経過した際に以上に気づき、即座にプログラムは停止させ、/var/spool/mail/配下の指定アドレスの中身は処理したのだが、
postfixのキューに大量の残骸が残ってしまった。
遅延の遅延の遅延を繰り返し、頑張って送ってきてはいるが、
1万数千単位のメールが何時までも送られてくるため、当該ユーザの
通常のメールにも遅延が生じてしまっている状態。
そこで、postfixのキューを何とかして、通常の状態に戻してみた。
幸い、該当のメールのサイズが2kBと非常に小さいもので、他の遅延が殆どなかったので、
さらっと内容を確認して、該当のメールだけを削除する。
qmgr キューマネージャーにてメッセージはキューを通過する。
格納されている先
/var/spool/postfix/incoming リモート受信した最新のメッセージ格納 /var/spool/postfix/active 処理中メッセージ /var/spool/postfix/bounce 配信できなかったメールID毎のログ /var/spool/postfix/corrupt postfixの形式に則ってないメッセージ格納
/var/spool/postfix/deferred 配信不能だがリトライする。 /var/spool/postfix/hold 無期限保存する際利用 /var/spool/postfix/defer 一時的に配送不能なメッセージリトライする。
既に、 /var/spool/mail/配下の指定アドレスの中身は処理済みの場合、
問題は、
deferredとdeferに残骸が有ると、何度もリトライを繰り返してしまう点にある。
そこで、 defer配下をfindしてファイルサイズ2kのものをxargsで渡して削除
# find /var/spool/postfix/defer/ -size 2k | xargs rm -rf
マジで全部消えるので、ほんとにそのサイズで大丈夫か?を確認すること
※ -execだとファイルの数だけコマンドを投げる仕様のようで、時間がかかってしまう。
今回1万数千回の実行は xargs の方が向いている。
同様に、deferredでも行う。
# find /var/spool/postfix/deferred/ -size 2k | xargs rm -rf
その後、 残った問題の無いものを強制送信。
# postfix flush
最後にキューをきれいにする
# postsuper -d ALL
キューがきれいになったか確認
# postqueue -p Mail queue is empty
これで、正常な状態に戻っている(はず)
小生の環境では、これで正常に配信されるようになった。
この方の解説が非常にわかりやすかった。ありがとうございます。
kazupon.com様
2018/11/06
SUBARU XV DBA-GT7 CADデータ
現行のSUBARU(スバル)XVのCADデータが見つからず・・・。
平面図が欲しかったが、SUBARUさんも3面図のみの掲載・・・。
平面図を作成するために、結局全部書いてしまった・・・。
誰トク?なCADデータだが、約2,500台/月の販売実績だし、
ちょっとリコール出てるけど、車に問題はないし、
オーナー様にご利用頂ければと思い、公開。
FC2に「SUBARU_XV_DBA_GT7.zip」でアップロードしてます。(JW_CAD)
SUBARU(スバル)XV 2017年5月~ DBA-GT7型 2.0i-Sアイサイト
平面図が欲しかったが、SUBARUさんも3面図のみの掲載・・・。
平面図を作成するために、結局全部書いてしまった・・・。
誰トク?なCADデータだが、約2,500台/月の販売実績だし、
ちょっとリコール出てるけど、車に問題はないし、
オーナー様にご利用頂ければと思い、公開。
FC2に「SUBARU_XV_DBA_GT7.zip」でアップロードしてます。(JW_CAD)
SUBARU(スバル)XV 2017年5月~ DBA-GT7型 2.0i-Sアイサイト
PHP 日本語メールの環境依存文字 文字化け対策
先般、SPF問題の解決の為、PHPMAILERにてメール送信を行うように仕様変更したが、
まだ、JIS-2022-JPの7bit問題が解決していない。
問題点としては、さまざまな環境のメールサーバやOSがアンドロイドでないフィーチャーフォン
(所謂ガラケー)では、8bitを許容していないようだが、ほとんどの動作環境下でUTF-8が
利用できるようになってきている。
と思われる。
そこで、今までは、JIS-2022-JP(7bit)の制約を受け、環境依存文字や半角カナ
が文字化けを起こす環境で運用を行っていたが、さすがに、ガラケーのみで
運用をするユーザが現役社会人である可能性は、万が一くらいでいいだろうと判断した。
前段が長くなってしまったが、
UTF-8でPHPMAILERのインスタンスを生成する際の記載をオボエガキ
前回との変更箇所をオレンジ表記
$mail->AddAttachment('./hogefile.pdf');日本語は極力使わない!!
大分後になって
$mail->CharSet = "UTF-8";
$mail->Encoding = "base64";
と宣言をするよりも、
$mail->CharSet = "iso-2022-jp";
$mail->Encoding = "7bit";
として、愚直に
mb_encode_mimeheader(mb_convert_encoding($fromname,"JIS","UTF-8"))
としたほうが、エンコード率が高いことが分かった。
まだ、JIS-2022-JPの7bit問題が解決していない。
問題点としては、さまざまな環境のメールサーバやOSがアンドロイドでないフィーチャーフォン
(所謂ガラケー)では、8bitを許容していないようだが、ほとんどの動作環境下でUTF-8が
利用できるようになってきている。
と思われる。
そこで、今までは、JIS-2022-JP(7bit)の制約を受け、環境依存文字や半角カナ
が文字化けを起こす環境で運用を行っていたが、さすがに、ガラケーのみで
運用をするユーザが現役社会人である可能性は、万が一くらいでいいだろうと判断した。
前段が長くなってしまったが、
UTF-8でPHPMAILERのインスタンスを生成する際の記載をオボエガキ
前回との変更箇所をオレンジ表記
smtp送信テストPHP(UTF-8送信)<?
require_once("/置いた所/vendor/autoload.php" ); //これを忘れると動かない!! require_once("/置いた所/vendor/phpmailer/phpmailer/class.phpmailer.php"); //これを忘れると動かない!!
mb_language("japanese");
mb_internal_encoding("UTF-8");
$to = "XXXX@gmail.com"; $subject = "SMTP587テスト"; $body = "smtpサーバ経由のメールテスト";
$from = "hoge@hogehoge.com"; $fromname = "送信テスト君"; $mail = new PHPMailer();//インスタンス生成 $mail->CharSet = "UTF-8";//UTF-8の宣言をすること $mail->Encoding = "base64";//記述しないと正しく認識しないサーバが存在するらしい。 $mail->IsSMTP(); //smtp利用宣言 $mail->SMTPAuth = TRUE;//smtp認証宣言 $mail->Host = 'mail.xxxx.jp:587'; // ホストアドレス:ポート25or587 $mail->Username = 'hoge'; //smtp認証ユーザ $mail->Password = 'hogehoge'; //smtp認証パス $mail->AddAddress($to);
$mail->From = $from;
$mail->FromName = $fromname;
$mail->Subject = $subject; $mail->Body = $body;
//メールを送信 if (!$mail->Send()){ echo("Failed to send mail. Error:".$mail->ErrorInfo); }else{ echo("Send mail OK."); }
?>
大分後になって
$mail->CharSet = "UTF-8";
$mail->Encoding = "base64";
と宣言をするよりも、
$mail->CharSet = "iso-2022-jp";
$mail->Encoding = "7bit";
として、愚直に
mb_encode_mimeheader(mb_convert_encoding($fromname,"JIS","UTF-8"))
としたほうが、エンコード率が高いことが分かった。
2018/10/24
composerで配置したPHPMailerの アクセス権限について
昨日、home直下のユーザディレクトリで作業を行ない、
/home/user/vendorという状況でテストを行ったが
例えば、/ver/www/htmlの配下から
/home/user/vendorにリクエストをする際に、パーミッションエラーが起こり
phpのプログラムが止まってしまった。
autoload.phpが正しくrequireされているかを確認するのが、厄介だった。
また、home以下のディレクトリのパーミッションを流石にすべて777にしたくないので、
/ver/www/html側に
composerから再度PHPMailerを配置し、お茶を濁した。
/home/user/vendorという状況でテストを行ったが
例えば、/ver/www/htmlの配下から
/home/user/vendorにリクエストをする際に、パーミッションエラーが起こり
phpのプログラムが止まってしまった。
autoload.phpが正しくrequireされているかを確認するのが、厄介だった。
また、home以下のディレクトリのパーミッションを流石にすべて777にしたくないので、
/ver/www/html側に
composerから再度PHPMailerを配置し、お茶を濁した。
2018/10/23
メールの到達率を高める。 SPF逆引き対策
受付完了のメールなどを、社内のサーバから送信しているのだが、
セキュアな対策を行っているメールサーバを利用している方に、メールが届かない
というケースが生じてきた。
SPF(Sender Policy Framework) という技術だそうで、
FORMのIPアドレスがDNSの逆引きで実在するかをチェックするという動きのようだ。
わざわざレンタルサーバ上でメールを作成して送信も手間なので、
今までは、特段気にしていなかったが、基幹システム化しつつあるため、そうも言ってられなくなった。
要は、実在するSMTPサーバを経由してメールを送ればいいので、少し調べた所
いくつか方法があった。
1.
1.は設定変更等が生じた際に面倒な気がしてならないので、保留。
2.は魅力的だが、php7.0以降でサポートしていないようなので、後ろ髪惹かれつ第2候補に
というわけで、PHPMailerをインストールしてみる。
依存関係を考慮しつつライブラリを使えるようにしてくれる
composerという PHPのパッケージ管理システムを使って
PHPMailerを導入してみる。
セキュアな対策を行っているメールサーバを利用している方に、メールが届かない
というケースが生じてきた。
SPF(Sender Policy Framework) という技術だそうで、
FORMのIPアドレスがDNSの逆引きで実在するかをチェックするという動きのようだ。
わざわざレンタルサーバ上でメールを作成して送信も手間なので、
今までは、特段気にしていなかったが、基幹システム化しつつあるため、そうも言ってられなくなった。
要は、実在するSMTPサーバを経由してメールを送ればいいので、少し調べた所
いくつか方法があった。
1.
postfixのmain.cf にリレーさせる
2.Qdsmtpというhal456さんが作成したライブラリを利用させて頂き、smtpサーバ経由にする。
3.PHPMailerという老舗のライブラリを利用させて頂きsmtpサーバを経由にする。
1.は設定変更等が生じた際に面倒な気がしてならないので、保留。
2.は魅力的だが、php7.0以降でサポートしていないようなので、後ろ髪惹かれつ第2候補に
というわけで、PHPMailerをインストールしてみる。
依存関係を考慮しつつライブラリを使えるようにしてくれる
composerという PHPのパッケージ管理システムを使って
PHPMailerを導入してみる。
# mkdir comp 適当な作業ディレクトリを作成。
# cd comp
# php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
# php composer-setup.php
All settings correct for using Composer
Downloading...
Composer (version 1.7.2) successfully installed to: /root/composer.phar
Use it: php composer.phar
# rm -f composer-setup.php もう要らないので、消す
# mv composer.phar /usr/local/bin/composer システム全般で使えるように移動
セキュリティホールになるからルートで使うなと言われるらしいので、 一般ユーザで確認
$ composer
でロゴとか出れば、OK
続けて、ライブラリ
phpmailer
を入れる。
任意のユーザの任意のディレクトリで行うこと
$ composer require phpmailer/phpmailer
Using version ^5.2 for phpmailer/phpmailer
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
- Installing phpmailer/phpmailer (v5.2.26): Downloading (100%)
phpmailer/phpmailer suggests installing league/oauth2-google (Needed for Google XOAUTH2 authentication)
Writing lock file
Generating autoload files
何処に置いたか忘れたら、これで探すようかな?
$ find -name vendor -type d
smtp送信テストPHP<?
require_once("/置いた所/vendor/autoload.php" ); //これを忘れると動かない!! require_once("/置いた所/vendor/phpmailer/phpmailer/class.phpmailer.php"); //これを忘れると動かない!!
mb_language("japanese");
mb_internal_encoding("UTF-8");
$to = "XXXX@gmail.com"; $subject = "SMTP587テスト"; $body = "smtpサーバ経由のメールテスト";
$from = "hoge@hogehoge.com"; $fromname = "送信テスト君"; $mail = new PHPMailer();//インスタンス生成 $mail->CharSet = "iso-2022-jp"; $mail->Encoding = "7bit"; $mail->IsSMTP(); //smtp利用宣言 $mail->SMTPAuth = TRUE;//smtp認証宣言 $mail->Host = 'mail.xxxx.jp:587'; // ホストアドレス:ポート25or587 $mail->Username = 'hoge'; //smtp認証ユーザ $mail->Password = 'hogehoge'; //smtp認証パス $mail->AddAddress($to);
$mail->From = $from; $mail->FromName = mb_encode_mimeheader(mb_convert_encoding($fromname,"JIS","UTF-8"));
$mail->Subject = mb_encode_mimeheader(mb_convert_encoding($subject,"JIS","UTF-8")); $mail->Body = mb_convert_encoding($body,"JIS","UTF-8"); //メールを送信 if (!$mail->Send()){ echo("Failed to send mail. Error:".$mail->ErrorInfo); }else{ echo("Send mail OK."); }
?>
テスト送信が届いたら、
念のため、SMTPサーバの/var/log/maillog も確認し、上手くいってるようだ。
稼働中のプログラムの置き換えをして完了。
明日できれば置き換えよう
うん、がんばろう・・・。
2018/10/10
tesseractの数字と一部の記号のみ識字させる方法
https://code-examples.net/ja/q/4b73be
此処に記載があった。
outputbase digits のオプションでは、何故か上手く行かなかったので、
此処に記載があった。
outputbase digits のオプションでは、何故か上手く行かなかったので、
少し調べてみたところ
標準出力にオプションでキャラクタの設定が出来るとあった。
標準出力にオプションでキャラクタの設定が出来るとあった。
stdout -c tessedit_char_whitelist=指定したい内容
これは上手くいったので、一旦標準出力させたものを無理やりファイル出力させた。
正規の方法は、学習させることだと思うが、
数字とハイフンのみ識別させればよかったので、この方法を採った。
数字の認識のみさせるであれば余程特殊なフォントでなければ、かなりの精度で認識した。
ファイル出力する場合
$ tesseract test.png stdout -c tessedit_char_whitelist=0123456789- >test.txt
ファイル出力する場合
$ tesseract test.png stdout -c tessedit_char_whitelist=0123456789- >test.txt
このようにすると良い。
デフォルトのライブラリを通すと、~や#に誤認識することが有り、
上手くなかったので、探してみたところ有益な情報が見つかったので、オボエガキ
2018/09/12
MSSQLへPHPで接続(PDO接続)
表題の、PHPでMSSQLへの接続時のオボエガキ
もともとは、mssql_connectにてMS SQLServerに接続していたが、
サーバの仕様変更と、php7から利用できなくなることもありPDO(PHP Data Objects の略)
接続へ切り替えた。
設定は、/etc/odbc.iniにてODBCのIDとfreetdsドライバーを関連付
/etc/odbcinst.iniに freetdsドライバーを追加
[freetds]
Description = MS SQL database access with Free TDS
Driver = /usr/local/lib/libtdsodbc.so
UsageCount = 1
Trace = Yes
freetdsをリポジトリからインストールするとSSLサポートされないので、
手動でインストールが必要だった。
https://stackoverflow.com/questions/39395548/how-to-configure-pymssql-with-ssl-support-on-ubuntu-16-04-lts/39395549
先駆者様ありがとうございます。
python-pip と libssl-dev をインストール後、
freeTDSは0.95のtar.gzを展開し、ディレクトリ内でmakeインストールする。
# ./configure --with-openssl=/usr/include/openssl --with-tdsver=7.3
# make
# make install
freetdsで接続する際に参照される接続先の定義は、/home/ユーザ名/.freetds.confに記載する。
##.freetds.confの中身##
# $Id: freetds.conf,v 1.12 2007-12-25 06:02:36 jklowden Exp $
#
# This file is installed by FreeTDS if no file by the same
# name is found in the installation directory.
#
# For information about the layout of this file and its settings,
# see the freetds.conf manpage "man freetds.conf".
# Global settings are overridden by those in a database
# server specific section
[global]
# TDS protocol version
; tds version = 4.2
# Whether to write a TDSDUMP file for diagnostic purposes
# (setting this to /tmp is insecure on a multi-user system)
; dump file = /tmp/freetds.log
; debug flags = 0xffff
# Command and connection timeouts
; timeout = 10
; connect timeout = 10
# If you get out-of-memory errors, it may mean that your client
# is trying to allocate a huge buffer for a TEXT field.
# Try setting 'text size' to a more reasonable limit
text size = 64512
# A typical Sybase server
[hoge] ←この変数を 'odbc:hoge' で読み込む。
host = hoge-sql.database.windows.net
port = 1433
tds version = 7.3
database = DEMODB
encryption = require
【PHPの中身】
//MSSQLにPDO接続
//基本:$pdo = new PDO($dsn, $username, $password, $driver_options);
try {
$pdo = new PDO('odbc:hoge','ログインユーザ名@hoge-sql.database.winwdows.net','パスワード');
$pdo->exec('SET CHARACTER SET utf8');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
}catch(PDOException $Exception){
die('接続エラー:' .$Exception->getMessage());
}
//クエリ取得
try{
$sql= "select * from [テーブル名] where 条件";
$stmh = $pdo->prepare($sql);
$stmh->execute();
}catch(PDOException $Exception){
die('接続エラー:' .$Exception->getMessage());
}
while($col = $stmh->fetch(PDO::FETCH_ASSOC)){
print($col['カラム名']);
//変数等を定義する場合も普通に行える。
}
}//クエリの取得終了
//sqlServerの接続を解除
$pdo = null;
もともとは、mssql_connectにてMS SQLServerに接続していたが、
サーバの仕様変更と、php7から利用できなくなることもありPDO(PHP Data Objects の略)
接続へ切り替えた。
設定は、/etc/odbc.iniにてODBCのIDとfreetdsドライバーを関連付
/etc/odbcinst.iniに freetdsドライバーを追加
[freetds]
Description = MS SQL database access with Free TDS
Driver = /usr/local/lib/libtdsodbc.so
UsageCount = 1
Trace = Yes
freetdsをリポジトリからインストールするとSSLサポートされないので、
手動でインストールが必要だった。
https://stackoverflow.com/questions/39395548/how-to-configure-pymssql-with-ssl-support-on-ubuntu-16-04-lts/39395549
先駆者様ありがとうございます。
python-pip と libssl-dev をインストール後、
freeTDSは0.95のtar.gzを展開し、ディレクトリ内でmakeインストールする。
# ./configure --with-openssl=/usr/include/openssl --with-tdsver=7.3
# make
# make install
$ tsql -C
Compile-time settings (established with the "configure" script)
Version: freetds v0.95
freetds.conf directory: /usr/local/etc
MS db-lib source compatibility: no
Sybase binary compatibility: no
Thread safety: yes
iconv library: yes
TDS version: 7.3
iODBC: no
unixodbc: yes
SSPI "trusted" logins: no
Kerberos: no
OpenSSL: yes ←ここが重要
GnuTLS: no
freetdsで接続する際に参照される接続先の定義は、/home/ユーザ名/.freetds.confに記載する。
##.freetds.confの中身##
# $Id: freetds.conf,v 1.12 2007-12-25 06:02:36 jklowden Exp $
#
# This file is installed by FreeTDS if no file by the same
# name is found in the installation directory.
#
# For information about the layout of this file and its settings,
# see the freetds.conf manpage "man freetds.conf".
# Global settings are overridden by those in a database
# server specific section
[global]
# TDS protocol version
; tds version = 4.2
# Whether to write a TDSDUMP file for diagnostic purposes
# (setting this to /tmp is insecure on a multi-user system)
; dump file = /tmp/freetds.log
; debug flags = 0xffff
# Command and connection timeouts
; timeout = 10
; connect timeout = 10
# If you get out-of-memory errors, it may mean that your client
# is trying to allocate a huge buffer for a TEXT field.
# Try setting 'text size' to a more reasonable limit
text size = 64512
# A typical Sybase server
[hoge] ←この変数を 'odbc:hoge' で読み込む。
host = hoge-sql.database.windows.net
port = 1433
tds version = 7.3
database = DEMODB
encryption = require
【PHPの中身】
//MSSQLにPDO接続
//基本:$pdo = new PDO($dsn, $username, $password, $driver_options);
try {
$pdo = new PDO('odbc:hoge','ログインユーザ名@hoge-sql.database.winwdows.net','パスワード');
$pdo->exec('SET CHARACTER SET utf8');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
}catch(PDOException $Exception){
die('接続エラー:' .$Exception->getMessage());
}
//クエリ取得
try{
$sql= "select * from [テーブル名] where 条件";
$stmh = $pdo->prepare($sql);
$stmh->execute();
}catch(PDOException $Exception){
die('接続エラー:' .$Exception->getMessage());
}
while($col = $stmh->fetch(PDO::FETCH_ASSOC)){
print($col['カラム名']);
//変数等を定義する場合も普通に行える。
}
}//クエリの取得終了
//sqlServerの接続を解除
$pdo = null;
2018/08/09
postfixのTLS設定
gmailで暗号化されていないと赤い鍵が表示されて何か気になるので対策してみる。
ファイアーウォールは適宜解放のこと
25、587、465
ローカルのSSL/TLSの設定は行っているが、
postfixのサーバ間の接続については、細かく設定していなかった。(MTA間通信)
これをTLSやS/MIMEに対応させていないと、gmailで赤い鍵が表示されてしまう仕様のようだ。
postfixの設定見直しはSMTP関連は次のようにしておく
赤い鍵が消えた。よかった。
ファイアーウォールは適宜解放のこと
25、587、465
ローカルのSSL/TLSの設定は行っているが、
postfixのサーバ間の接続については、細かく設定していなかった。(MTA間通信)
これをTLSやS/MIMEに対応させていないと、gmailで赤い鍵が表示されてしまう仕様のようだ。
postfixの設定見直しはSMTP関連は次のようにしておく
# nano /etc/postfix/master.cf 頭の方に記載がある
【中身】
smtp inet n - n - - smtpd
↑必須 submission inet n - n - - smtpd ↑587ポートを使う場合
-o smtpd_tls_security_level=may
↑587の時これをencriptにすると、STARTTLSをしてから送れ、と言われてしまうので、どっちも許容のmayがよい
-o smtpd_sasl_auth_enable=yes
↑SMTP認証を使う場合はyesにする
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
↑SMTP-AUTHを通ったものを許可する。rejectは細かく指定するとそこは蹴れる。
# nano /etc/postfix/main.cf TLSは末尾に記載されているので、そこを編集
【中身】
## TLS
# Transport Layer Security
#
smtpd_use_tls = yes
smtp_use_tls = yes
#smtpd_tls_auth_only = yes
↑これを有効にするとTLSでないと蹴るので、コメントアウトのままにしておく smtpd_tls_key_file = /usr/local/ssl/private/キーファイル.key smtpd_tls_CAfile = /usr/local/ssl/crt/SSL証明書ファイル.crt smtpd_tls_loglevel = 3
↑これを1にすると、ログにTLSの事が記載されるらしい。
smtpd_tls_received_header = yes
tls_random_source = dev:/dev/urandom
smtpd_tls_security_level=may
↑25ポートからのSTARTTLSを使う場合は、master.cfでなく、main.cfに記載するとの事。postfixを再起動して内容反映
# systemctl restart postfix
オレンジ色の部分を記載すると、
相手がTLSを受け付けてくれる場合は、MTA間通信をSSL/TLSにて行える
2018/06/27
指定ディレクト配下のPDFのファイル名を変更する。
はじめに、OCRをさせる為、Tesseract-OCRをmake installする
その事前準備のライブラリをインストールする
途中のmakeでmakeでICU(文字コード変換ライブラリ)が必要になるらしいが、
パッケージが無いので、
Leptonica という画像解析ライブラリも必要なので、
こちらも、makeからインストール 1.76が最新
tesseract-ocrと辞書のインストール
# mv 3.04.01.tar.gz tesseract3.01.01.tar.gz
# tar -zxvf tesseract3.01.01.tar.gz
# cd tesseract-3.04.01/
$ pdftoppm /storage1/scanedPdf/20180613133511305.pdf -f 1 -l 1 -mono -x 110 -y 45 -W 140 -H 35 -png /storage1/scanedPdf/mono
こんな感じで使う。
mono-1.pngをocrに掛ける。
$ tesseract /storage1/scanedPdf/mono-1.png /storage1/scanedPdf/mono
mono.txtが生成されるので、
これをトリミングして、
欲しい部分だけにする。
$ cat ./mono.txt|tr -d '\n''' > ./mono0.txt
$ cat ./mono0.txt|tr -d ' ' > ./mono1.txt
これで、mono1.txtには
10xx-1XXXXXX が記載されている。
これを使って元のPDFのリネームを行いたい。
ハイフンの全角「ー」と「-」半角を認識する様で、
全角で読み込んでしまうことが有ったので、
nkf コマンドですべて半角にしてしまう事にする。
# yum install nkf
コマンドの際は、
cat $filename-0.txt|nkf -Z4 > $filename.txt
シェルスクリプトの例
#!/bin/bash
#tesseractのパスを通す
export PATH="/usr/local/bin:$PATH"
#ディレクトリ移動
echo "ディレクトリを移動"
cd /storage1/scanedPdf/
#while用にディレクトリ内のファイル数をカウント
count=$(ls | wc -w)
echo "ディレクトリ内のファイル数:"$count
#カウントが0以上なら、ループ処理を行う。
#-ne not equal
while [ $count -ne 0 ]
do
#一行づつ処理するために念のため仕掛ける。いきなり変数でも問題ない。
for file in `\find . -maxdepth 1 -name '*.pdf'| head -n1`; do
basename $file .pdf
done
#変数定義
filename=$(basename $file .pdf)
#pdftoppmでpdfデータの左上(0,0)基準の座標(100,45)から座標(290,80)までを切り出しモノクロのpngを生成する。
pdftoppm $filename.pdf -f 1 -l 1 -mono -x 100 -y 45 -W 190 -H 35 -png /storage1/scanedPdf/$filename
#上記のpngをOCRで読み取り、テキストファイルを生成する。
#-1は「ファイル名-1.png」が生成されてしまうため、この-1が必要となる。
tesseract $filename-1.png -psm 6 $filename-1
#テキストデータ内の半角スペースを削除する
cat $filename-1.txt|tr -d ' ' > $filename-2.txt
#テキストデータ内の全角―を半角-に書き換える
cat $filename-2.txt|nkf -Z4 > $filename.txt
#変数定義
pdfname=$(head -n 1 $filename.txt)
echo $pdfname
#pdfの名称を1xxx-1xxxxxの形に変更して、/storage1/pdf/に移動
mv ./$filename.pdf /storage1/pdf/$pdfname.pdf
#作業ファイルを削除
rm $filename*
#カウントのデクリメント
count=$(( count -1))
done
上手く動いた。
当初、パスを通していなかったため、上手く動かなかったが、cronでも問題なく動いた。
複合機で一つ一つのファイルを開いて中身を確認して名称を付けるのは非常に面倒くさいし、もの凄い時間を浪費する。
これは、かなり便利だと思う。
その事前準備のライブラリをインストールする
# yum install autoconf automake libtool # yum install libpng-devel libjpeg-devel libtiff-devel zlib-devel # yum install libicu-devel # yum install pango-devel
途中のmakeでmakeでICU(文字コード変換ライブラリ)が必要になるらしいが、
パッケージが無いので、
icu4c をmakeからインストールする
# cd /usr/local/src/ # sudo wget http://download.icu-project.org/files/icu4c/56rc/icu4c-56_rc-src.tgz # tar zxf icu4c-56_rc-src.tgz # cd icu/source/ # ./configure # make # make install
Leptonica という画像解析ライブラリも必要なので、
こちらも、makeからインストール 1.76が最新
# cd /usr/local/src/# wget http://www.leptonica.com/source/leptonica-1.76.0.tar.gz
# tar -xzvf leptonica-1.76.0.tar.gz # cd leptonica-1.76.0 # ./configure # make # make install
tesseract-ocrと辞書のインストール
# cd /usr/local/src/# wget https://github.com/tesseract-ocr/tesseract/archive/3.04.01.tar.gz
# mv 3.04.01.tar.gz tesseract3.01.01.tar.gz
# tar -zxvf tesseract3.01.01.tar.gz
# cd tesseract-3.04.01/
#./autogen.sh
# LDFLAGS="-L/usr/local/lib" CFLAGS="-I/usr/local/include" ./configure --with-training-tools
# make
# make install
# ldconfig
更に、設定ファイルを定義
取敢えず英語の場合、
tesseract-ocr-3.02.eng.tar.gzをどこからか探してくる。
/usr/local/share/tessdate/配下に 中身をコピーする。
これで、ようやくocrが使える。
# pdftoppm 0000.pdf 0000out これで、0000ont.ppmが生成されるので、
これをocrに掛ける。
画像が大きい場合は、optionでトリミングしたりする。
$ pdftoppm /storage1/scanedPdf/20180613133511305.pdf -f 1 -l 1 -mono -x 110 -y 45 -W 140 -H 35 -png /storage1/scanedPdf/mono
こんな感じで使う。
mono-1.pngをocrに掛ける。
$ tesseract /storage1/scanedPdf/mono-1.png /storage1/scanedPdf/mono
mono.txtが生成されるので、
これをトリミングして、
欲しい部分だけにする。
$ cat ./mono.txt|tr -d '\n''' > ./mono0.txt
$ cat ./mono0.txt|tr -d ' ' > ./mono1.txt
これで、mono1.txtには
10xx-1XXXXXX が記載されている。
これを使って元のPDFのリネームを行いたい。
ハイフンの全角「ー」と「-」半角を認識する様で、
全角で読み込んでしまうことが有ったので、
nkf コマンドですべて半角にしてしまう事にする。
# yum install nkf
コマンドの際は、
cat $filename-0.txt|nkf -Z4 > $filename.txt
-Zで 全角⇒半角だが、 helpによると-Z4は
JISX0208 Katakana to JISX0201 Katakanaとなっており、
どうもこの方が精度が良いようなので、-Z4でやってみる。
#!/bin/bash
#tesseractのパスを通す
export PATH="/usr/local/bin:$PATH"
#ディレクトリ移動
echo "ディレクトリを移動"
cd /storage1/scanedPdf/
#while用にディレクトリ内のファイル数をカウント
count=$(ls | wc -w)
echo "ディレクトリ内のファイル数:"$count
#カウントが0以上なら、ループ処理を行う。
#-ne not equal
while [ $count -ne 0 ]
do
#一行づつ処理するために念のため仕掛ける。いきなり変数でも問題ない。
for file in `\find . -maxdepth 1 -name '*.pdf'| head -n1`; do
basename $file .pdf
done
#変数定義
filename=$(basename $file .pdf)
#pdftoppmでpdfデータの左上(0,0)基準の座標(100,45)から座標(290,80)までを切り出しモノクロのpngを生成する。
pdftoppm $filename.pdf -f 1 -l 1 -mono -x 100 -y 45 -W 190 -H 35 -png /storage1/scanedPdf/$filename
#上記のpngをOCRで読み取り、テキストファイルを生成する。
#-1は「ファイル名-1.png」が生成されてしまうため、この-1が必要となる。
tesseract $filename-1.png -psm 6 $filename-1
#テキストデータ内の半角スペースを削除する
cat $filename-1.txt|tr -d ' ' > $filename-2.txt
#テキストデータ内の全角―を半角-に書き換える
cat $filename-2.txt|nkf -Z4 > $filename.txt
#変数定義
pdfname=$(head -n 1 $filename.txt)
echo $pdfname
#pdfの名称を1xxx-1xxxxxの形に変更して、/storage1/pdf/に移動
mv ./$filename.pdf /storage1/pdf/$pdfname.pdf
#作業ファイルを削除
rm $filename*
#カウントのデクリメント
count=$(( count -1))
done
上手く動いた。
当初、パスを通していなかったため、上手く動かなかったが、cronでも問題なく動いた。
複合機で一つ一つのファイルを開いて中身を確認して名称を付けるのは非常に面倒くさいし、もの凄い時間を浪費する。
これは、かなり便利だと思う。
2018/06/19
リモートデスクトップ接続が出来ない(windowsアップデートによる)
WindowsServer2012へリモートデスクトップ接続を行なおうとすると、
認証エラー
要求された関数はサポートされません
サーバ:192.168.0.xxx
のダイアログが表示されて接続できない。
環境
サーバ
Windows 2012R2
クライアント
windows7 Home(セキュリティパッチのみ)
2018 年 5 月の更新プログラム適用によるリモート デスクトップ接続への影響
https://blogs.technet.microsoft.com/askcorejp/2018/05/02/2018-05-rollup-credssp-rdp/
4-2. リモート デスクトップ接続元 (クライアント) での回避策
リモートデスクトップ接続元にて以下レジストリを手動もしくは REG ADD コマンドで追加いただくことでも回避策 1 と同様の効果が得られます。
レジストリ パス : HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters
値 : AllowEncryptionOracle
データの種類 : DWORD
値 : 2
REG ADD コマンドで追加いただく場合には以下のコマンド ラインとなります。
REG ADD HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters /v AllowEncryptionOracle /t REG_DWORD /d 2
とのこと。
コマンドプロンプトを監理者権限で起動し、
REG ADD HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters /v AllowEncryptionOracle /t REG_DWORD /d 2
を叩くと接続できた。
根本的な解決は、サーバ側に更新プログラムを適用させろ
との事なので、早めにやろう。
2018/06/04
postgresql 初期化と接続 外部からのdump
postgresqlがインストールされているか確認。
pgsql --version
psql (PostgreSQL) 9.2.18
起動テストをしてみる。
# systemctl start postgresql.service
Job for postgresql.service failed because the control process exited with error code. See "systemctl status postgresql.service" and "journalctl -xe" for details.
初期化が必要だった。
# service postgresql initdb
Hint: the preferred way to do this is now "postgresql-setup initdb"
Initializing database ... OK
動かしてみる。
# systemctl start postgresql.service
[root@localhost ~]# systemctl status postgresql.service
● postgresql.service - PostgreSQL database server
Loaded: loaded (/usr/lib/systemd/system/postgresql.service; disabled; vendor preset: disabled)
Active: active (running) since 月 2018-06-04 18:54:47 JST; 12s ago
Process: 1627 ExecStart=/usr/bin/pg_ctl start -D ${PGDATA} -s -o -p ${PGPORT} -w -t 300 (code=exited, status=0/SUCCESS)
Process: 1619 ExecStartPre=/usr/bin/postgresql-check-db-dir ${PGDATA} (code=exited, status=0/SUCCESS)
Main PID: 1630 (postgres)
CGroup: /system.slice/postgresql.service
tq1630 /usr/bin/postgres -D /var/lib/pgsql/data -p 5432
tq1631 postgres: logger process
tq1633 postgres: checkpointer process
tq1634 postgres: writer process
tq1635 postgres: wal writer process
tq1636 postgres: autovacuum launcher process
mq1637 postgres: stats collector process
6月 04 18:54:46 localhost.localdomain systemd[1]: Starting PostgreSQL database server...
6月 04 18:54:47 localhost.localdomain systemd[1]: Started PostgreSQL database server.
動いた。
一旦停止して、外部からのアクセスが出来るようにする。
# nano /var/lib/pgsql/data/postgresql.conf
L60位のlisten_addressを許容
listen_addresses = '*' # what IP address(es) to listen on;
# nano /var/lib/pgsql/data/pg_hba.conf
末尾にIPアドレスの設定
# TYPE DATABASE USER ADDRESS METHOD
# "local" is for Unix domain socket connections only
local all all trust
# IPv4 local connections:
host all all 127.0.0.1/32 trust
# IPv6 local connections:
host all all ::1/128 trust
# Allow replication connections from localhost, by a user with the
# replication privilege.
#local replication postgres trust
#host replication postgres 127.0.0.1/32 trust
#host replication postgres ::1/128 trust
# for server
host all all 192.168.xxx.0/24 password
host all all 192.168.xxx.0/24 password
host all all 192.168.xxx.0/24 password
# for vendor
host all all xxx.xxx.xxx.xxx/28 password
firewallを開放
# firewall-cmd --add-service=postgresql --permanent
success
# systemctl restart firewalld.service
再度起動
恐らく問題なく接続できている。
pg_dumpで外部サーバに接続する場合は、同じユーザを作成し、ルートに .pgpass を作成
書き方は
192.168.0.XXX:5432:DB名:ユーザ名:パスワード
複数のDBがある時は、
192.168.0.xxx:5432:*:user:password でOK
$ chmod 600 .pgpass パーミッションは600指定
パーミッション600にしないと、エラーになった。
$ pg_dump -Ft -h 192.168.0.xxx -p 5432 -U user -w dbName > /home/user/dbName_`date '+%y%m%d%H%M'`
-wがパスワード請求無しのオプション
こんな感じでdump出来るので、これをシェルスクリプトにして、crontabに書いて終了。
pgsql --version
psql (PostgreSQL) 9.2.18
起動テストをしてみる。
# systemctl start postgresql.service
Job for postgresql.service failed because the control process exited with error code. See "systemctl status postgresql.service" and "journalctl -xe" for details.
初期化が必要だった。
# service postgresql initdb
Hint: the preferred way to do this is now "postgresql-setup initdb"
Initializing database ... OK
動かしてみる。
# systemctl start postgresql.service
[root@localhost ~]# systemctl status postgresql.service
● postgresql.service - PostgreSQL database server
Loaded: loaded (/usr/lib/systemd/system/postgresql.service; disabled; vendor preset: disabled)
Active: active (running) since 月 2018-06-04 18:54:47 JST; 12s ago
Process: 1627 ExecStart=/usr/bin/pg_ctl start -D ${PGDATA} -s -o -p ${PGPORT} -w -t 300 (code=exited, status=0/SUCCESS)
Process: 1619 ExecStartPre=/usr/bin/postgresql-check-db-dir ${PGDATA} (code=exited, status=0/SUCCESS)
Main PID: 1630 (postgres)
CGroup: /system.slice/postgresql.service
tq1630 /usr/bin/postgres -D /var/lib/pgsql/data -p 5432
tq1631 postgres: logger process
tq1633 postgres: checkpointer process
tq1634 postgres: writer process
tq1635 postgres: wal writer process
tq1636 postgres: autovacuum launcher process
mq1637 postgres: stats collector process
6月 04 18:54:46 localhost.localdomain systemd[1]: Starting PostgreSQL database server...
6月 04 18:54:47 localhost.localdomain systemd[1]: Started PostgreSQL database server.
動いた。
一旦停止して、外部からのアクセスが出来るようにする。
# nano /var/lib/pgsql/data/postgresql.conf
L60位のlisten_addressを許容
listen_addresses = '*' # what IP address(es) to listen on;
# nano /var/lib/pgsql/data/pg_hba.conf
末尾にIPアドレスの設定
# TYPE DATABASE USER ADDRESS METHOD
# "local" is for Unix domain socket connections only
local all all trust
# IPv4 local connections:
host all all 127.0.0.1/32 trust
# IPv6 local connections:
host all all ::1/128 trust
# Allow replication connections from localhost, by a user with the
# replication privilege.
#local replication postgres trust
#host replication postgres 127.0.0.1/32 trust
#host replication postgres ::1/128 trust
# for server
host all all 192.168.xxx.0/24 password
host all all 192.168.xxx.0/24 password
host all all 192.168.xxx.0/24 password
# for vendor
host all all xxx.xxx.xxx.xxx/28 password
firewallを開放
# firewall-cmd --add-service=postgresql --permanent
success
# systemctl restart firewalld.service
再度起動
恐らく問題なく接続できている。
pg_dumpで外部サーバに接続する場合は、同じユーザを作成し、ルートに .pgpass を作成
書き方は
192.168.0.XXX:5432:DB名:ユーザ名:パスワード
複数のDBがある時は、
192.168.0.xxx:5432:*:user:password でOK
$ chmod 600 .pgpass パーミッションは600指定
パーミッション600にしないと、エラーになった。
$ pg_dump -Ft -h 192.168.0.xxx -p 5432 -U user -w dbName > /home/user/dbName_`date '+%y%m%d%H%M'`
-wがパスワード請求無しのオプション
こんな感じでdump出来るので、これをシェルスクリプトにして、crontabに書いて終了。
2018/05/29
JDK8(171)とtomcatとgroupsessionのインストール CentOS7
1.Java SE Development Kit 8u171のインストール
http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
JDK10はgroupsessionが未対応なので、8の最新をダウンロード
rpmパッケージをダウンロードして、ローカルインストールする。
# yum install jdk-8u171-linux-x64.rpm
既にパッケージがインストールされているときは、最新を認識させる必要がある。
# alternatives --config java
3 プログラムがあり 'java' を提供します。
選択 コマンド
-----------------------------------------------
1 java-1.7.0-openjdk.x86_64 (/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.131-2.6.9.0.el7_3.x86_64/jre/bin/java)
*+ 2 java-1.8.0-openjdk.x86_64 (/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-2.b11.el7_3.x86_64/jre/bin/java)
3 /usr/java/jdk1.8.0_171-amd64/jre/bin/java
Enter を押して現在の選択 [+] を保持するか、選択番号を入力します:
最新になっているので、問題ない。
JDK10はgroupsessionが未対応なので、8の最新をダウンロード
rpmパッケージをダウンロードして、ローカルインストールする。
# yum install jdk-8u171-linux-x64.rpm
既にパッケージがインストールされているときは、最新を認識させる必要がある。
# alternatives --config java
3 プログラムがあり 'java' を提供します。
選択 コマンド
-----------------------------------------------
1 java-1.7.0-openjdk.x86_64 (/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.131-2.6.9.0.el7_3.x86_64/jre/bin/java)
*+ 2 java-1.8.0-openjdk.x86_64 (/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-2.b11.el7_3.x86_64/jre/bin/java)
3 /usr/java/jdk1.8.0_171-amd64/jre/bin/java
Enter を押して現在の選択 [+] を保持するか、選択番号を入力します:
最新になっているので、問題ない。
# echo $JAVA_HOME でパスが通っているか確認。
何も出なければ、とおっていないので、在処を探す。
# readlink $(readlink $(which java))
/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-2.b11.el7_3.x86_64/jre/bin/java
設定し、反映させる
# echo "export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-2.b11.el7_3.x86_64/jre" >> /root/.bashrc
# source /root/.bashrc
# echo $JAVA_HOME
/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-2.b11.el7_3.x86_64/jre
何も出なければ、とおっていないので、在処を探す。
# readlink $(readlink $(which java))
/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-2.b11.el7_3.x86_64/jre/bin/java
設定し、反映させる
# echo "export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-2.b11.el7_3.x86_64/jre" >> /root/.bashrc
# source /root/.bashrc
# echo $JAVA_HOME
/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-2.b11.el7_3.x86_64/jre
2.tomcatユーザを作成、パスワード
# useradd tomcat
# passwd tomcat
# passwd tomcat
3.tomcatをインストール
http://tomcat.apache.org/
gsessionはJ2EEコンテナは6,7,8が対象なので、apache-tomcat-8.5.31.tar.gzをダウンロードし、
展開 ⇒ /usr/localへ移動 ⇒ 所有者をtomcatに ⇒ シンボリックリンクを作成
# tar xvfz apache-tomcat-8.5.31.tar.gz
# mv apache-tomcat-8.5.31 /usr/local
# cd /usr/local
# chown -R tomcat:tomcat apache-tomcat-8.5.31
# ln -s apache-tomcat-8.5.31 tomcat
gsessionはJ2EEコンテナは6,7,8が対象なので、apache-tomcat-8.5.31.tar.gzをダウンロードし、
展開 ⇒ /usr/localへ移動 ⇒ 所有者をtomcatに ⇒ シンボリックリンクを作成
# tar xvfz apache-tomcat-8.5.31.tar.gz
# mv apache-tomcat-8.5.31 /usr/local
# cd /usr/local
# chown -R tomcat:tomcat apache-tomcat-8.5.31
# ln -s apache-tomcat-8.5.31 tomcat
4.環境変数の定義
JAVA_HOMEとCATALINA_HOMEを定義する。
CentOSの場合、/etc/profileが既にあるので、この後ろに書く。
# nano /etc/profile
末尾に
JAVA_HOME=/usr/java/default
CATALINA_HOME=/usr/local/tomcat
export JAVA_HOME CATALINA_HOME
を加える。
CentOSの場合、/etc/profileが既にあるので、この後ろに書く。
# nano /etc/profile
末尾に
JAVA_HOME=/usr/java/default
CATALINA_HOME=/usr/local/tomcat
export JAVA_HOME CATALINA_HOME
を加える。
5.systemdの起動用にtomcat.serviceを作成。
# nano /usr/lib/systemd/system/tomcat.service
[Unit]
Description=Apache Tomcat Web Application Container
After=network.target
[Service]
Type=forking
Environment=JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-2.b11.el7_3.x86_64/jre/
Environment=CATALINA_OPTS=-Xmx3072M -2048XmsM
ExecStart=/usr/local/apache-tomcat-8.5.31/bin/startup.sh
ExecStop=/usr/local/apache-tomcat-8.5.31/bin/shutdown.sh
ExecReStart=/usr/local/apache-tomcat-8.5.31/bin/shutdown.sh;/usr/local/apache-tomcat-8.5.31/bin/startup.sh
[Install]
WantedBy=multi-user.target
実行権限を付与
# chmod 755 /usr/lib/systemd/system/tomcat.service
ヒープメモリを
Environment=CATALINA_OPTS=-Xmx3072M -2048XmsM
Description=Apache Tomcat Web Application Container
After=network.target
[Service]
Type=forking
Environment=JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-2.b11.el7_3.x86_64/jre/
Environment=CATALINA_OPTS=-Xmx3072M -2048XmsM
ExecStart=/usr/local/apache-tomcat-8.5.31/bin/startup.sh
ExecStop=/usr/local/apache-tomcat-8.5.31/bin/shutdown.sh
ExecReStart=/usr/local/apache-tomcat-8.5.31/bin/shutdown.sh;/usr/local/apache-tomcat-8.5.31/bin/startup.sh
[Install]
WantedBy=multi-user.target
実行権限を付与
# chmod 755 /usr/lib/systemd/system/tomcat.service
ヒープメモリを
Environment=CATALINA_OPTS=-Xmx3072M -2048XmsM
で設定しないで、~/tomcat/bin/startup.shから直接起動時に反映させたい場合は、
~/tomcat/bin 配下に setenv.sh を作成して、その中に書けば良い
#!/bin/sh
JAVA_OPTS="-server -Xms2048M -Xmx3072M"
export JAVA_OPTS
これで々ように起動時にヒープメモリが設定される。
6.firewall 8080ポートの開放
# firewall-cmd --add-port=8080/tcp --permanent
success
# firewall-cmd --reload
# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: em1
sources:
services: dhcpv6-client ssh
ports: 8080/tcp
protocols:
masquerade: no
forward-ports:
sourceports:
icmp-blocks:
rich rules:
8080が開いた。
7.起動、停止テスト
# systemctl start tomcat停止は、
# systemctl stop tomcat
自動起動は
# systemctl enable tomcat
稼働確認
groupsessionのインストール
最新版をダウンロード
https://groupsession.jp/dl/gsession_war_4_8_1-dl1.html
から、gsession.warをダウンロード
# systemctl stop tomcat でtomcatを停止してから、
/usr/local/apache-tomcat-8.5.31/webappsにgsession.warを置く。
# systemctl start tomcat で起動。
# systemctl stop tomcat でtomcatを停止してから、
/usr/local/apache-tomcat-8.5.31/webappsにgsession.warを置く。
# systemctl start tomcat で起動。
2018/05/21
centOS7にntfsのhddをマウントさせる
ntfsドライブをマウントするためのパッケージは
fuse
fuse-ntfs-3g
dkms
dkms-fuse
# yum -y --enablerepo=epel install dkms fuse-ntfs-3g
yumでインストールするが、
epelリポジトリのパッケージをインストールする時は --enablerepo=epel と文句言われるので-y
のパラメータを追加すること。
内部の構成を確認する、パーティションを変更したりする場合で2TBを超える場合は、
fdiskではなく parted -l とかで、処理をすること
マウント先を、適宜指定する
# mkdir /mnt/usbhdd
マウント
# mount -t ntfs-3g /dev/sdb1 /mnt/usbhdd
アンマウント
# umount /mnt/usbhdd
以上
fuse
fuse-ntfs-3g
dkms
dkms-fuse
# yum -y --enablerepo=epel install dkms fuse-ntfs-3g
yumでインストールするが、
epelリポジトリのパッケージをインストールする時は --enablerepo=epel と文句言われるので-y
のパラメータを追加すること。
内部の構成を確認する、パーティションを変更したりする場合で2TBを超える場合は、
fdiskではなく parted -l とかで、処理をすること
マウント先を、適宜指定する
# mkdir /mnt/usbhdd
マウント
# mount -t ntfs-3g /dev/sdb1 /mnt/usbhdd
アンマウント
# umount /mnt/usbhdd
以上
2018/05/19
Linux find 今日作業したファイルを検索
作業したファイのバックアップを取る際に、広域に跨ってると意外に探すのが面倒だったりする。
いつ頃作業したかがわかれば、findで割と容易に見つけられる。
オプション
-type f :ファイルのみを対象に検索
-type d :ディレクトリを対象に検索
-mmin -60 :60分以内に更新
-amin -60 :60分以内にアクセス
-mtime -2 :2日以内に更新
-atime -2 :2日以内にアクセス
-anewer :後述のファイルの日付より後に更新されたものを抽出
今日アクセスしたファイルやディレクトを検索
$ find /home/aaa/bbb/ -atime 0
60分以内に更新したファイルを検索
$ find /home/aaa/bbb/ -type f -mmin -60
元.vmファイルより新しいファイルを検索
$ find /home/aaa/bbb/ -anewer ./work/元.vm
いつ頃作業したかがわかれば、findで割と容易に見つけられる。
オプション
-type f :ファイルのみを対象に検索
-type d :ディレクトリを対象に検索
-mmin -60 :60分以内に更新
-amin -60 :60分以内にアクセス
-mtime -2 :2日以内に更新
-atime -2 :2日以内にアクセス
-anewer :後述のファイルの日付より後に更新されたものを抽出
今日アクセスしたファイルやディレクトを検索
$ find /home/aaa/bbb/ -atime 0
60分以内に更新したファイルを検索
$ find /home/aaa/bbb/ -type f -mmin -60
元.vmファイルより新しいファイルを検索
$ find /home/aaa/bbb/ -anewer ./work/元.vm
2018/05/17
SQL JOIN時に絞り込み条件付加
join on を指定する際に、条件を付けてjoinできるのを知った。
select <テーブルA>.<カラム1>,<テーブルA>.<カラム2>・・・・,<テーブルB>.<カラム5>,<テーブルC>.<カラム2> from <テーブルA> inner join <テーブルB> on <テーブルB>.<カラム1>=<テーブルA>.<カラム1> and <テーブルB>.<カラム1>=true and <テーブルB>.<カラム2>=0
left join <テーブルC> on <テーブルC>.<カラム1>=<テーブルA>.<カラム1> where 更に条件;¥
このような感じで、join on の際に、複数の条件を付与して連結できる。
LeftJoinの場合は、従の条件を絞ってから連結 というような動きにはならないようだ。
あくまで、 主の条件が絞られていれば、絞ってから連結とする模様。
where以下に条件を書かなくても絞り込めるので、where以下がスッキリする、整理しやすい
というメリットがある。
select <テーブルA>.<カラム1>,<テーブルA>.<カラム2>・・・・,<テーブルB>.<カラム5>,<テーブルC>.<カラム2> from <テーブルA> inner join <テーブルB> on <テーブルB>.<カラム1>=<テーブルA>.<カラム1> and <テーブルB>.<カラム1>=true and <テーブルB>.<カラム2>=0
left join <テーブルC> on <テーブルC>.<カラム1>=<テーブルA>.<カラム1> where 更に条件;¥
このような感じで、join on の際に、複数の条件を付与して連結できる。
LeftJoinの場合は、従の条件を絞ってから連結 というような動きにはならないようだ。
あくまで、 主の条件が絞られていれば、絞ってから連結とする模様。
where以下に条件を書かなくても絞り込めるので、where以下がスッキリする、整理しやすい
というメリットがある。
grepを使った絞り込み ファイル単位で複数の行に条件を設けて抽出する場合
grepを使った絞り込み
条件
ディレクトリA
aaa.xml
bbb.xml
ccc.xml
・
・
・
zzz.xml
aaa.xml
・
・
bbb.xml
・
・
ccc.xml
・
・
ccc.xml
・
・
ディレクトリAの中にあるxmlで、typeが0、nameが0463のファイルを抽出したい場合
一回のgrepで抽出しようとしたが、行が異なると判定されてしまうので、上手くいかず。
-P '検索箇所頭[\s\S]*?検索箇所末尾' の Pオプションを使った場合、
ファイルサイズが大きく、ファイス数が多いとかなりの負荷がかかる。
また、改行の\nを削除したファイルに置換するものコピーの手間がかかる。
今回の対象ファイル数が、25,000ファイル位あった。
こんなの一つづつはご免蒙る。
そこで、次の手順を取った。
1.取得したい条件を一旦ファイルにする。
$ grep -r -l "
$ grep -r -l "
-rで回帰
-l でファイル名のみ抽出させる。(行数やパターンが出ると、2でgrepした際に重ならない)
2.grepで重なる部分を取得する。
$ grep -f {type,name}.txt
結果
aaa.xml
ccc.xml
・
・
のように抽出したいファイルが絞り込める。
実際は、
/home/ディレクトリA/ディレクトリB_1000/1/20180301_134814.xm ディレクトリBのレベルで判別したいので、一旦マージ用のファイルを生成し、
$ grep -f {type,name}.txt >merge.txt
この段で、P オプションとoオプション(only-matching)を使って絞り込む
$ grep -oP 'ディレクトリB[\s\S]*?/' merge.txt | uniq -d
ディレクトリB/ ←この部分を取得したい。
uniq -d ユニークで重複を表示させない。
結果
ディレクトリB_1000
ディレクトリB_1010
ディレクトリB_1012
・
・
・
ディレクトリ
期待値が取れた。
登録:
投稿 (Atom)