ブログトップ 記事一覧 ログイン 無料ブログ開設

ぴょぴょぴょ? - Linuxとかプログラミングの覚え書き - このページをアンテナに追加 RSSフィード

2016-07-12

pdfのファイルサイズを小さくする方法

|  pdfのファイルサイズを小さくする方法を含むブックマーク  pdfのファイルサイズを小さくする方法のブックマークコメント

pdfファイルに高解像度の画像を埋め込むと,ファイルサイズ無駄に大きくなります.この場合,以下のスクリプトで画像の解像度を下げると,効率よくファイル圧縮できます.コマンドラインで実行できるので,複数のpdfファイルを一括で変換することも可能でとても便利です.

なおこのスクリプトLinuxMac OS Xの両方で動作します

スクリプトの中身

#!/bin/bash

error()
{
    echo "$@"
    exit 1
}

if [ $# -ne 2 ]; then
    cat<<EOF
usage:
   $0   <input-pdf>  <output-pdf>
EOF
    exit 1
fi

input=$1
output=$2

[ -f "$input" ] || error "no such input file, $input"
[ -f "$output" ] && error "$output already exists"

gs \
   -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 \
  -dDownsampleColorImages=true \
  -dColorImageResolution=300 \
  -dNOPAUSE -dBATCH \
  -sOutputFile="$output"  "$input"

使い方

上記の内容をパスが通っているディレクトリ,例えば /usr/bin/以下に,pdf_reduce.sh という名前で保存します.次にパーミッションを設定します

$ sudo chmod  a+x /usr/bin/pdf_reduce.sh

実行方法は以下の通りです.

$ pdf_reduce.sh  original.pdf  output.pdf

ここで,original.pdf は元のファイル , output.pdf が出力ファイルの名前になります.

複数のpdfを一括変換する場合は次のようにします

$ mkdir  output
$ for x in *.pdf; do  pdf_reduce.sh $x output/$x; done

出力ファイルの保存先として "output"というディレクトリを作成して,カレントディレクトリにあるpdfをまとめて変換し,同じファイル名で outputディレクトリ以下に保存します.

解説


gsコマンドを使って pdf を読み込んで,再度pdf形式で書き出しています

ポイントは,以下の3点です

A4の紙に印刷する程度であれば解像度は300dpi程度で十分です

トラックバック - http://d.hatena.ne.jp/pyopyopyo/20160712

2016-06-04

MBR(bios)でもESP(uefi)でも起動できるgrub2の設定方法

|  MBR(bios)でもESP(uefi)でも起動できるgrub2の設定方法を含むブックマーク  MBR(bios)でもESP(uefi)でも起動できるgrub2の設定方法のブックマークコメント

Linuxを起動する方法はたくさんあります.本エントリでは

の2つを共存させたディスクを作成する方法についてまとめます

前者は,従来のBIOS経由での起動方法で,古いマザーボードだと必須となる方法です.後者は,EFI経由の起動方法で,最近のマーザーボードで使える"新しくて便利な"方法となります.

具体的な手順について

以下,実例として

の場合について手順を詳細に説明します

SSDは64GB で /dev/sdb に繋いであるものとします

なお既存のディスクを MBR/ESP両対応に変換する手順については,後日別エントリに書く予定です.

事前準備

事前知識として

  • MBRを使う場合は,ディスクの先頭に1MB程度の領域を確保しておいて,そこに grub2を入れる事
  • ESPを使う場合は,ディクスのパーティションテーブルを GPT という形式で設定する事
  • ESPFAT32 または FAT16でフォーマットする事

という条件があります

そこで,予め gptを使うために gdisk, fat でフォーマットするので dosfstools をインストールしておきます

$ sudo apt-get install gdisk dosfstools

grub-efiインストールしておきます

$ sudo apt-get install grub-efi
gdisk を使ったパーティション設定

gdisk で

sudo /sbin/gdisk /dev/sdb

次のように表示されます

GPT fdisk (gdisk) version 1.0.1

Partition table scan:
  MBR: not present
  BSD: not present
  APM: not present
  GPT: not present

Creating new GPT entries.

Command (? for help):

初期化SSDなのでパーティションテーブルがありません


まず expert モードに遷移,sector alignment value を 1に変更します

Command (? for help): x

Expert command (? for help): l

Enter the sector alignment value (1-65536, default = 2048): 1

Expert command (? for help): m

Command (? for help):

コマンドを説明すると,

  • まず"x"でexpertモードに突入
  • "l"でsector alignment value の変更
  • 値を1 に設定
  • "m"で元のモードに戻る

となります

続いて第一パーティションを作成します.このパーティションMBRgrub が使う領域になります

Command (? for help): n
Partition number (1-128, default 1): 1
First sector (34-125045390, default = 34) or {+-}size{KMGTP}:  34
Last sector (34-125045390, default = 125045390) or {+-}size{KMGTP}: 2047
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300): EF02
Changed type of partition to 'BIOS boot partition'

コマンドを説明すると,

と設定しています.これで "BIOS boot partition" が作成されます

念の為,"p"コマンドパーティションテーブルを表示させて,状態を確認します

Command (? for help): p
Disk /dev/sdb: 125045424 sectors, 59.6 GiB
Logical sector size: 512 bytes
Disk identifier (GUID):XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 125045390
Partitions will be aligned on 1-sector boundaries
Total free space is 125043343 sectors (59.6 GiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1              34            2047   1007.0 KiB  EF02  BIOS boot partition


Command (? for help):

34セクタから2047セクタに EF02 で BIOS boot parttion が作成されていることが確認できます

うまく行ったら sector alignment value を 2048 に戻します

Command (? for help): x

Expert command (? for help): l
Enter the sector alignment value (1-65536, default = 2048): 2048

Expert command (? for help): m

Command (? for help):
  • "x"でexportモードに突入
  • "l"でsector alignment value の変更
  • 値を 2048 に設定
  • "m"で元のモードに戻る

となります

次に EFI System パーティションを作成します

Command (? for help): n
Partition number (2-128, default 2): 2
First sector (2048-125045390, default = 2048) or {+-}size{KMGTP}: 2048
Last sector (2048-125045390, default = 125045390) or {+-}size{KMGTP}: 256M
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300): EF00
Changed type of partition to 'EFI System'

と設定します.これで "EFI System" パーティションが作成されました

続けて Linux 用のパーティションを作成します.今回はディスクの残りの領域をすべて "/" パーティションに割り当てることにします

Command (? for help): n
Partition number (3-128, default 3): 
First sector (524289-125045390, default = 526336) or {+-}size{KMGTP}: 
Last sector (526336-125045390, default = 125045390) or {+-}size{KMGTP}: 
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300): 
Changed type of partition to 'Linux filesystem'

となっています

最後に "p" でパーティション情報を表示させます

Command (? for help): p
Disk /dev/sdb: 125045424 sectors, 59.6 GiB
Logical sector size: 512 bytes
Disk identifier (GUID):XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 125045390
Partitions will be aligned on 2048-sector boundaries
Total free space is 2047 sectors (1023.5 KiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1              34            2047   1007.0 KiB  EF02  BIOS boot partition
   2            2048          524288   255.0 MiB   EF00  EFI System
   3          526336       125045390   59.4 GiB    8300  Linux filesystem

問題なければ "w" でパーティション情報をディスクに書き込みます

Command (? for help): w

Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!

Do you want to proceed? (Y/N): Y
OK; writing new GUID partition table (GPT) to /dev/sdb.

問題なければ "Y" を押します."Y"を押すまではディスクには何も書き込まれないので,不安だったら

Ctrk-C とか "N" を押せば変更はキャンセルできます



パーティションのフォーマット

再度パーティションを確認します

$ sudo /sbin/gdisk  -l /dev/sdb
Number  Start (sector)    End (sector)  Size       Code  Name
   1              34            2047   1007.0 KiB  EF02  BIOS boot partition
   2            2048          526335   256.0 MiB   EF00  EFI System
   3          526336       125045390   59.4 GiB    8300  Linux filesystem

第1パーティションのフォーマットは不要です.grubが直接セクタを書き換えるためです

第2パーティション /dev/sdb2 は vfat 32 でフォーマットします.これはEFIのルールです

$ sudo /sbin/mkfs.vfat -F32 /dev/sdb2 

第3パーティション /dev/sdb3 は ext4 でフォーマットしました

$ sudo /sbin/mkfs.ext4  /dev/sdb3

第三パーティションはディスクラベルも指定しておきます.ラベルは"ROOT"にします

$ sudo /sbin/e2label /dev/sdb3 ROOT

今時のLinuxはUUIDでパーティションを特定しますが,私は必ずラベルを設定するようにしています.

なぜなら,サーバ障害時などの緊急時には最悪SSDを取り外して,別のLinux BOXに繋いでマウントという手段を取ることがあり,その際はラベルを指定しておくと作業が円滑におこなえるためです.


システムのコピー

長いので別エントリにしています. linux環境を複製する方法 - ぴょぴょぴょ? - Linuxとかプログラミングの覚え書き - こちらをご覧ください

grubインストール

新しいディスク上を /mntマウントして,そこに chroot した環境で作業します

$ sudo mount /dev/sdb3 /mnt
$ sudo mount --bind /dev /mnt/dev
$ sudo mount --bind /proc /mnt/proc
$ sudo chroot /mnt
MBR用grub2のインストール

従来のBIOSブートで使用するブートローダとして grub2 をインストールします

# /usr/sbin/grub-install --target=i386-pc /dev/sdb

ここでエラーが出る場合は "BIOS boot partition"がうまく用意できていません.パーティションテーブルの内容を再度チェックしましょう

EFI用grub2のインストール

まず"EFI System"パーティションを /boot/efiマウントします

# mkdir -p /boot/efi
# mount /dev/sdb2 /boot/efi

続けてgrub2をインストール

# /usr/sbin/grub-install --target=x86_64-efi /dev/sdb

LinuxEFIで起動していない場合は,ここで

efibootmgr: EFI variables are not supported on this system.
efibootmgr: EFI variables are not supported on this system.

という警告がでます

この警告が出る場合は再起動時にマザーボードBIOS/EFIの設定画面に行き,ブートローダーとしてgrubを使うように設定する必要があります

2016-05-31

gpg の使い方

|  gpg の使い方を含むブックマーク  gpg の使い方のブックマークコメント

gpg コマンドの使い方を表で整理します

よく使うコマンド一覧

操作コマンド
鍵の管理
公開鍵の一覧を見る gpg --list-keys
秘密鍵の一覧を見る gpg --list-secret-keys
公開鍵を stdout に出力 gpg -a --export [ID]
秘密鍵を stdout に出力 gpg -a --export-secret-keys [ID]
公開鍵を stdinから取り込む gpg --import
秘密鍵を stdinから取り込む gpg --import
公開鍵を削除する gpg --delete-key [ID]
秘密鍵を削除する gpg --delete-secret-key [ID]
ファイル暗号化・復号・署名
ファイル暗号化する gpg -e -r [ID] hogehoge.txt
復号するgpg hogehoge.txt.gpg
ファイル hogehoge.txt を署名する gpg --digest-algo SHA512 -u [ID] -bao hogehoge.txt.gpg hogehoge.txt
clearsign gpg --clearsign hogehoge.txt
鍵の新規作成・登録
鍵を作る gpg --gen-key
鍵を鍵サーバーに登録 gpg --send-keys key [ID] --keyserver [SERVER]

応用例

鍵のコピー

鍵をリモートサーバーにコピーする場合は ssh と組み合わせると便利です

例えばローカルの鍵を,リモートにコピーするときは

$ gpg -a --export [ID] | ssh [REMOTEのHOST名]  gpg --import

リモートの鍵を,ローカルにコピーするときは

$ ssh [REMOTEのHOST名] gpg -a --export [ID] | gpg --import

秘密鍵をコピーするときは --export を --export-secret-keys に変えるだけです

注意事項

"-a"オプションの順番
"-a"は最初に付けましょう
鍵を削除するときは,秘密鍵が先
秘密鍵が登録されていると対応する公開鍵は削除できません.
トラックバック - http://d.hatena.ne.jp/pyopyopyo/20160531

2016-05-28

memtest86をEFI経由で起動する方法

|  memtest86をEFI経由で起動する方法を含むブックマーク  memtest86をEFI経由で起動する方法のブックマークコメント

memtest86EFI 経由で起動する方法が予想以上に便利だったので設定方法を紹介します

この方法を使うと Linux 側で以下のコマンドを実行するだけで

$ sudo efibootmgr -n 2

PC再起動後は自動で memtest86 が起動します

そしてmemtest86終了後も再起動するだけで,元のLinuxが起動します

設定方法

大まかな方針は

だけです



設定は予めEFIブートを有効にしておいた debian で行いました.EFIブートが有効なっていれば 他のディストーション,つまり ubunturedhat でも同じ手順で作業できるはずです


まずUSBブート用のイメージをダウンロードします.

http://www.memtest86.com/から memtest86-usb.tar.gz を落とします

$ wget http://www.memtest86.com/downloads/memtest86-usb.tar.gz

展開します

$ tar xvfz http://www.memtest86.com/downloads/memtest86-usb.tar.gz
memtest86-usb.img
README

memtest86-usb.img がUSBメモリ用のイメージファイルになります.fileコマンドを使い,中身を確認します

$ file memtest86-usb.img
Disk /tmp/memtest86-usb.img: 150 MiB, 157286400 bytes, 307200 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: B4A8751D-AF62-43BF-BE47-D2CF3ECE3458

Device                   Start    End Sectors Size Type
/tmp/memtest86-usb.img1   2048 102400  100353  49M Microsoft basic data
/tmp/memtest86-usb.img2 104448 307166  202719  99M EFI System

パーティションが2つあります.必要なのは 2番めのパーティションの中のファイルです.2番目のパーティションは104448 セクタから始まり 307166セクタで終了していることがわかります.またセクタサイズは512bytesです

2番目のパーティションだけマウントします.

ディスクイメージから特定のパーティションを選んでマウントする方法はたくさんありますが,一番簡単なのはおそらく次の方法です.

$ sudo mount -o loop,offset=$((104448*512)) memtest86-usb.img /mnt/

loopデバイス経由で memtest86-usb.img を /mntマウントします.この時 offset オプションを併用することで memtest86-usb.img を先頭から使わずに, 104448*512 バイト後ろにずらした領域をマウントします.これで第2パーティションが /mntマウントできます

マウントしたパーティションを覗いてみます

$ cd /mnt
$ find

ファイルがたくさん表示されます

./EFI
./EFI/BOOT
./EFI/BOOT/BOOTIA32.efi
./EFI/BOOT/Benchmark
./EFI/BOOT/BOOTX64.efi
./EFI/BOOT/unifont.bin
./EFI/BOOT/mt86.png
./help
./help/MemTest86_User_Guide_UEFI.pdf
./license.rtf
./src
./src/memtest86-src.tar.gz
./syslinux
./syslinux/memtest
./syslinux/boot.txt
./syslinux/isolinux.bin
./syslinux/syslinux.cfg

必要なファイルEFI ディレクトリの中身だけです

EFI/memtest だけ HDDEFI領域にコピーします

$ sudo cp -r EFI/memtest /boot/efi

以上でインストールは終了です.

設定

まず efi に memtest を登録します.登録も Linuxコマンドで行います

まずブートイメージの登録状況を確認します

$ efibootmgr -v

たとえば次のような出力の場合は,2つ登録があることになります

BootCurrent: 0000
Timeout: 1 seconds
BootOrder: 0000,0001
Boot0000* debian        HD(2,GPT,省略)/File(\EFI\debian\grubx64.efi)
Boot0001* Hard Drive  省略
||< 

このリストにmemtest86を追加します
>|sh|
$  sudo efibootmgr -c --disk /dev/sda --part 2 --loader /EFI/memtest/BOOTX64.efi --label "memtest"

意味は

という意味です

確認します

$ sudo efibootmgr -v
BootCurrent: 0000
Timeout: 1 seconds
BootOrder: 0002,0000,0001
Boot0000* debian        HD(2,GPT,省略)/File(\EFI\debian\grubx64.efi)
Boot0001* Hard Drive  省略
Boot0002* memtest       HD(2,GPT,省略)/File(\EFI\memtest\BOOTX64.efi)

Boot0002 で memtest のエントリが増えたことがわかります

この出力の BootOrder が起動順になります.このままではデフォルトが memtest,つまり電源を入れるとデフォルトでは memtest が起動してしまいます.

デフォルトdebian に戻します

$ sudo efibootmgr -o 0,2,1

以上で設定はすべて完了です

使い方

再起動時に debian と memtest のどちらが起動するかは 以下のコマンドで確認できます

$ sudo efibootmgr -v
BootCurrent: 0000
BootOrder: 0000,0002,0001
Boot0000* debian        HD(2,GPT,省略)/File(\EFI\debian\grubx64.efi)
Boot0001* Hard Drive  省略
Boot0002* memtest       HD(2,GPT,省略)/File(\EFI\memtest\BOOTX64.efi)

なら debian が起動します

ここで

$ sudo efibootmgr -n 2

を実行すると,次回の再起動時だけ memtest が起動します. もう一度再起動すると debian が起動する状態に戻ります

トラックバック - http://d.hatena.ne.jp/pyopyopyo/20160528

2016-05-15

c++でプログレス・バーを表示する方法

|  c++でプログレス・バーを表示する方法を含むブックマーク  c++でプログレス・バーを表示する方法のブックマークコメント

boostboost/progress.hpp を使えばOK

#include <boost/progress.hpp>

#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/thread/thread.hpp> 

int main(int argc,char *argv[]) 
{
        const unsigned long expected_count=100;
        boost::progress_display show_progress( expected_count );
        for(int i=0; i<expected_count;++i)
        {
	     boost::this_thread::sleep(boost::posix_time::milliseconds(10));

             ++show_progress;
        }
        return 0;
} 

boost/progress.hpp 自体は追加でライブラリリンクする必要はなく,ヘッダファイルをinclude するだけで良い

ただし上記サンプルコードは boost/thread/thread.hpp の sleepを使っているので,ビルド時に,ライブラリ libboost_thread と libboost_system のリンクする必要がある

GCCビルドするなら

$ g++ sample.cpp -lboost_system -lboost_thread
トラックバック - http://d.hatena.ne.jp/pyopyopyo/20160515