20200529のLinuxに関する記事は7件です。

Developing Cipher Algorithms(2/2)

https://www.kernel.org/doc/html/latest/crypto/devel-algos.html

Docs » Linux Kernel Crypto API » Developing Cipher Algorithms

Hashing [HASH]

Example of transformations: crc32, md5, sha1, sha256,…

Registering And Unregistering The Transformation

There are multiple ways to register a HASH transformation, depending on whether the transformation is synchronous [SHASH] or asynchronous [AHASH] and the amount of HASH transformations we are registering. You can find the prototypes defined in include/crypto/internal/hash.h:

HASH transformationを登録するための複数の方法があります。変換が同期的(synchronous)か[SHASH]、非同期的(asynchromous) [AHASH]、そして登録しようとするHASH transformations の数に応じて変わります。プロとライプは、include/crypto/internal/hash.hで見つけることができます。

int crypto_register_ahash(struct ahash_alg *alg);

int crypto_register_shash(struct shash_alg *alg);
int crypto_register_shashes(struct shash_alg *algs, int count);

The respective counterparts for unregistering the HASH transformation are as follows:

HASH transformationを登録解除するためのそれぞれの方法は以下となります。

void crypto_unregister_ahash(struct ahash_alg *alg);

void crypto_unregister_shash(struct shash_alg *alg);
void crypto_unregister_shashes(struct shash_alg *algs, int count);

Cipher Definition With struct shash_alg and ahash_alg

Here are schematics of how these functions are called when operated from other part of the kernel. Note that the .setkey() call might happen before or after any of these schematics happen, but must not happen during any of these are in-flight. Please note that calling .init() followed immediately by .finish() is also a perfectly valid transformation.

以下に、カーネルの他の部分から処理を呼び出されたときに、これらの関数がどのように呼び出されるのかの図です。.setkry()の呼び出しは、これらの図の発生する前、あるいは発生した後に発生することに気を付けてください。しかし、処理実行中には呼び出されません。.init()が突然呼ばれた直後に.finish()を呼び出す事も、有効な変換であることに注意してください。

I)   DATA -----------.
                     v
      .init() -> .update() -> .final()      ! .update() might not be called
                  ^    |         |            at all in this scenario.
                  '----'         '---> HASH

II)  DATA -----------.-----------.
                     v           v
      .init() -> .update() -> .finup()      ! .update() may not be called
                  ^    |         |            at all in this scenario.
                  '----'         '---> HASH

III) DATA -----------.
                     v
                 .digest()                  ! The entire process is handled
                     |                        by the .digest() call.
                     '---------------> HASH

Here is a schematic of how the .export()/.import() functions are called when used from another part of the kernel.

ここで、カーネルの他の部分つかう時に.export()/.import()関数がそのように呼ばれるのかを示します。

KEY--.                 DATA--.
     v                       v                  ! .update() may not be called
 .setkey() -> .init() -> .update() -> .export()   at all in this scenario.
                          ^     |         |
                          '-----'         '--> PARTIAL_HASH

----------- other transformations happen here -----------

PARTIAL_HASH--.   DATA1--.
              v          v
          .import -> .update() -> .final()     ! .update() may not be called
                      ^    |         |           at all in this scenario.
                      '----'         '--> HASH1

PARTIAL_HASH--.   DATA2-.
              v         v
          .import -> .finup()
                        |
                        '---------------> HASH2

Note that it is perfectly legal to “abandon” a request object: - call .init() and then (as many times) .update() - not call any of .final(), .finup() or .export() at any point in future

要求するオブジェクトを"破棄"することが、完全に想定していることであることに注意してください。 init()を呼び出し(そして複数回) .update()を、最後に将来いつでも.final()やexport()は呼び出したり呼び出さなかったりします。

In other words implementations should mind the resource allocation and clean-up. No resources related to request objects should remain allocated after a call to .init() or .update(), since there might be no chance to free them.

言い換えると、実装ではresource allocation と clean-upについて注意をしなければなりません。request objectと関係がないリソースは、.init()や.update()を呼び出した後に残りを確保しなければならなく、それらは解放されるチャンスがありません。

Specifics Of Asynchronous HASH Transformation

Some of the drivers will want to use the Generic ScatterWalk in case the implementation needs to be fed separate chunks of the scatterlist which contains the input data. The buffer containing the resulting hash will always be properly aligned to .cra_alignmask so there is no need to worry about this.

ドライバーの中には、入力データに含まれているscatterlistの分割されたchunksを処理するため実装が必要となるケースでは、Generic ScatterWalkを使おうとするものもあります。結果のhashを含むバッファーは、常に、.cra_alignmaskに適切に配置されるため、これを考慮する必要はありません。


もともと、Linux Kernelのソースコードの一部なので、GPLv2扱いになる(はずの認識)。

https://www.kernel.org/doc/html/latest/index.html

Licensing documentation

The following describes the license of the Linux kernel source code (GPLv2), how to properly mark the license of individual files in the source tree, as well as links to the full license text.

https://www.kernel.org/doc/html/latest/process/license-rules.html#kernel-licensing

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

LinuxをDiscord Botで操作してみた

初めに

この記事は僕がPythonで作ったDiscord Botを簡単に共有できればと思い書いたものです
あまり詳しくは書きませんが誰かの役に立てれば幸いです

このBotで出来ること

Discord からLinuxを操作できます
「ls」コマンドや 「less」コマンドなど基本的に何でも使えます。
ただvimやsudoなどユーザーが追加で入力するものなどは使えません(コード追加すれば可能だと思われ)
二千文字の制限がDiscordにあるのでそれ以上のものは送信できません。
あとエラー処理してないのでvimなど開こうとするとbotが飛びます。

実行環境

Debian 10
Python 3.7.3

コード

import subprocess

# インストールした discord.py を読み込む
import discord

# 自分のBotのアクセストークンに置き換えてください
TOKEN = 'ボットのトークン'

# 接続に必要なオブジェクトを生成
client = discord.Client()

# 起動時に動作する処理
@client.event
async def on_ready():
    # 起動したらターミナルにログイン通知が表示される
    print('ログインしました')

async def job(message):
    await message.channel.send('そろそろ寝ましょう!')

# メッセージ受信時に動作する処理
@client.event
async def on_message(message):
    # メッセージ送信者がBotだった場合は無視する
    if message.author.bot:
        return
    # 「/neko」と発言したら「にゃーん」が返る処理

    if message.content == '/neko':
        await message.channel.send('にゃーん')

    if message.content == '/konn':
        await message.channel.send("こん")

    if message.author.id == DiscordのユーザーID:
        messStr = str(message.content)#ユーザーのメッセージを取得
        messList = messStr.split(" ")#ユーザーのメッセージをスペース区切りで配列にする

        res = subprocess.check_output(messList)#そのコマンドを実行、出力をresに代入
        res = res.decode("utf-8")#resをutf-8ででデコード
        await message.channel.send(res)#メッセージを送信
    else:
        await message.channel.send("権限がありません")

client.run(TOKEN)

ユーザーIDについて

途中で出てきたユーザーIDというのはDiscordで確認できます。
そのIDを使ってコマンドを実行してよいユーザーなのかを判定しています。

IDを表示する方法

ユーザー設定→テーマ→開発者モード をオンにします
そしてDiscordのユーザーを右クリックしてIDをコピーから参照できます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

LinuxでDeepL翻訳

LinuxでDeepL翻訳

DeepLを論文読みなどに使ってらっしゃる方多いですよね.
公式アプリケーションを使えば,Ctrl(Cmd) + Cを2回押すことによりポップアップが表示され,DeepLで翻訳してくれます.改行なども取り除いてくれます.

しかしこのアプリケーション,WindowsとMacでしか動きません.そこで,Linuxで同じ機能を実現するシェルスクリプトを作ったので紹介します.
deepl-clip.gif

インストール

インストールは簡単で
Ubuntu (Debian系) なら

sudo apt install xclip nkf
git clone git@github.com:masan4444/deepl-clip.git
chmod u+x deepl-clip/app.sh

CentOS (RedHat系) なら

yum install epel-release
yum install xclip nkf
git clone git@github.com:masan4444/deepl-clip.git
chmod u+x deepl-clip/app.sh

シェルスクリプトだけダウンロードして用いることも可能です.

使い方

使い方も簡単で

sh deepl-clip/app.sh

ブラウザでDeepLのサイトを開いて,クリップボードの中身を貼り付けてくれます.

しかし,この機能が便利なのは,ショートカットを設定してからです.
Ubuntu18.04なら設定 > デバイス > キーボード > 独自のショートカットからショートカットを設定することで,公式アプリのような機能を実現します.

その際,スクリプトのフルパスを指定しないといけません.
deepl-clip_shortcut.png
あとはCtrl+Cx2が設定できれば完璧なのですが..
基本的には

  1. Ctrl+Cでクリップボードにコピー
  2. Ctrl+?でスクリプトを起動

という使い方をします.

最後に

バグ報告,要望などがあればIssuesやこの記事のコメントに投稿してただけると幸いです.

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

GPGコマンドで暗号化・復号

LPIC102を学習中にGPGコマンドを初めて知ったので、実際に使用して理解を深めることにした。

環境

[ec2-user@ip-172-31-33-30 ~]$ cat /etc/os-release
NAME="Amazon Linux"
VERSION="2"
ID="amzn"
ID_LIKE="centos rhel fedora"
VERSION_ID="2"
PRETTY_NAME="Amazon Linux 2"
ANSI_COLOR="0;33"
CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2"
HOME_URL="https://amazonlinux.com/"

鍵ペアの作成

gpg --gen-keyコマンドで以下のように対話形式でキーペアを作成する。
鍵の種類:デフォルトのままにする
鍵長:鍵長は長いほどセキュリティが強いので、最大にしておく。
鍵の有効期間:流出した時に、有効期限を過ぎると無効になるので設定しておく。

[ec2-user@ip-172-31-33-30 ~]$ gpg --gen-key
gpg (GnuPG) 2.0.22; Copyright (C) 2013 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

ご希望の鍵の種類を選択してください:
   (1) RSA と RSA (デフォルト)
   (2) DSA と Elgamal
   (3) DSA (署名のみ)
   (4) RSA (署名のみ)
あなたの選択は? 1
RSA 鍵は 1024 から 4096 ビットの長さで可能です。
鍵長は? (2048) 4096
要求された鍵長は4096ビット
鍵の有効期限を指定してください。
         0 = 鍵は無期限
      <n>  = 鍵は n 日間で期限切れ
      <n>w = 鍵は n 週間で期限切れ
      <n>m = 鍵は n か月間で期限切れ
      <n>y = 鍵は n 年間で期限切れ
鍵の有効期間は? (0)2y
鍵は2022年05月29日 03時48分32秒 UTCで期限切れとなります
これで正しいですか? (y/N) y

GnuPGはあなたの鍵を識別するためにユーザIDを構成する必要があります。

本名: r_saiki
電子メール・アドレス: r_saiki@example.com
コメント: 
次のユーザIDを選択しました:
    "r_saiki <r_saiki@example.com>"

名前(N)、コメント(C)、電子メール(E)の変更、またはOK(O)か終了(Q)? o
秘密鍵を保護するためにパスフレーズがいります。

パスフレーズを要求される。
image.png

作成した鍵の確認。
公開鍵の確認オプション:--list-public-keysもしくは-k
秘密鍵の確認オプション:--list-secret-keysもしくは-K

[ec2-user@ip-172-31-33-30 ~]$ gpg --list-public-keys
/home/ec2-user/.gnupg/pubring.gpg
---------------------------------
pub   4096R/0C8FB274 2020-05-29 [有効期限: 2022-05-29]
uid                  r_saiki <r_saiki@example.com>
sub   4096R/038BE8AA 2020-05-29 [有効期限: 2022-05-29]

[ec2-user@ip-172-31-33-30 ~]$ gpg --list-secret-keys
/home/ec2-user/.gnupg/secring.gpg
---------------------------------
sec   4096R/0C8FB274 2020-05-29 [有効期限: 2022-05-29]
uid                  r_saiki <r_saiki@example.com>
ssb   4096R/038BE8AA 2020-05-29

ファイルの暗号化

ファイルを暗号化する。
暗号化:--encryptもしくは-e
受取人の公開鍵情報を指定:--recipientもしくは-r <今回はメールアドレス>

[ec2-user@ip-172-31-33-30 ~]$ cat file
TEST

[ec2-user@ip-172-31-33-30 ~]$ gpg --encrypt --recipient r_saiki@example.com file
[ec2-user@ip-172-31-33-30 ~]$ ls
file  file.gpg

ファイルの複合

pgpに暗号化ファイル名で複合する。

[ec2-user@ip-172-31-33-30 ~]$ gpg file.gpg

次のユーザの秘密鍵のロックを解除するには
パスフレーズがいります:"r_saiki <r_saiki@example.com>"
4096ビットRSA鍵, ID 038BE8AA作成日付は2020-05-29 (主鍵ID 0C8FB274)

gpg: 4096-ビットRSA鍵, ID 038BE8AA, 日付2020-05-29に暗号化されました
      "r_saiki <r_saiki@example.com>"
ファイル「file」は既に存在します。上書きしますか? (y/N) y
[ec2-user@ip-172-31-33-30 ~]$ cat file
TEST

途中パスフレーズを求められる。
image.png

終わりに

今回はファイルの暗号化・復号のみやってみた。深堀するとlpic受験前に息切れしそうなので、詳しく知りたい場合は以下を参考。
GPG でファイルを暗号化, 復号化, 署名, 検証する方法

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Linuxで.NETの開発をする

(An English version of this article is also available.)

筆者は複数のマシンを持っていますが、そのうちの一台はLinuxが入っています。デスクトップ機である関係上、これを開発に使うことも多いのですが、その環境に関して紹介していきたいと思います。

何ができるのか?

.NET Coreは複数のプラットフォーム対応がなされているため、開発に関してもほとんどWindowsと同じようなことができます。

可能なこと

筆者が可能であると確認しているのは以下のとおりです。

  • コマンドラインツールの開発とデバッグ。
  • ウェブアプリケーション(ASP.NETBlazorなど)の開発とデバッグ。
  • PowerShell (旧PowerShell Core)バイナリモジュールの開発とデバッグ(プロセスにアタッチしてのデバッグ)。
  • .NET Core Tools(Entity FrameworkML.NETなど)の取得と実行。
  • Unityを使用した開発。(以前はWindows、Macのみでしたが、Beta期間を経て、正式に利用できるようになりました。)

不可能(または困難)なこと

  • WinFormやWPFなどのGUIアプリケーションの開発。
  • .NET Frameworkをターゲットにする開発。
  • Xamarinを使用した開発。(サポートされていないものの、厳密にはできないことはないようです。例えば、xamarin-androidはJenkinsから取り出してくることで、使用できるようです。)

環境の作り方

.NET Core

.NET Coreはほとんどのメジャーなディストリビューションで使用することができ、また各種パッケージも提供されていますが、おすすめしたいのは、シェルスクリプトを使用したインストールです。

シェルスクリプト経由のインストールを行うことで、複数のバージョンの.NET Coreランタイムやライブラリのインストールが容易になります。

例えば、LTS版をインストールする場合は、以下のような形です。

./dotnet-install.sh --channel LTS

尚、追加でインストールが必要なライブラリが必要になるかもしれません。一般的にあまり通常では入っていないと思われるものはlibicuです。

インストール先はユーザーが書き込める場所でなくとも構いません。追加のテンプレートやツールなどはそれぞれのユーザーの管理下に置かれます。

開発環境

Visual Studio Code

無料で開発環境を揃えたいのであれば、以下のような組み合わせがおすすめになります。

上記で、開発が開始できる環境にすることができます。

JetBrains Rider

開発環境にお金を出してもいい、という方は、JetBrains Riderを検討するもの一つの選択肢になります。JetBrains社はVisual Studio用のリファクタリングプラグインであるReSharperを開発している会社でもあり、高度なコーディング支援が提供されるため、快適に開発することができます。

RiderはRider単体、RiderとReSharper同梱版、全IDE製品を含んだAll Products Packが存在しています。詳しくは購入ページを参照して下さい。(筆者は他の言語のものも使用することがあるため、All Products Packを個人的に契約しています。)尚、Riderに限らず、JetBrains社のほとんどのIDEはWindowsなどの他の環境でも使用できるため、複数のOSで同じIDEを使用できるという点においても重宝しています。

また、NuGetパッケージ管理などもグラフィカルにできるため、C#を行う機会が多い、という方におすすめです。

その他

尚、OmniSharp(上記の拡張でも使用)を用いることで、Language Server Protocolに対応したお好みのエディタで開発することも可能です。この方法はエディタによって変わってくるのでここでは割愛します。

早速試してみる

プロジェクト作成

環境を揃えると開発を開始することができます。

プロジェクトを作成するのにはdotnetコマンドを使用します。

dotnet new console -o myapp

以下の用に、引数を入れずに実行すると使用できるテンプレートが表示されます。

dotnet new
Usage: new [options]

Options:
  -h, --help          Displays help for this command.
  -l, --list          Lists templates containing the specified name. If no name is specified, lists all templates.
  -n, --name          The name for the output being created. If no name is specified, the name of the current directory is used.
  -o, --output        Location to place the generated output.
  -i, --install       Installs a source or a template pack.
  -u, --uninstall     Uninstalls a source or a template pack.
  --nuget-source      Specifies a NuGet source to use during install.
  --type              Filters templates based on available types. Predefined values are "project", "item" or "other".
  --dry-run           Displays a summary of what would happen if the given command line were run if it would result in a template creation.
  --force             Forces content to be generated even if it would change existing files.
  -lang, --language   Filters templates based on language and specifies the language of the template to create.
  --update-check      Check the currently installed template packs for updates.
  --update-apply      Check the currently installed template packs for update, and install the updates.


Templates                                         Short Name               Language          Tags                                 
----------------------------------------------------------------------------------------------------------------------------------
Console Application                               console                  [C#], F#, VB      Common/Console                       
Class library                                     classlib                 [C#], F#, VB      Common/Library                       
WPF Application                                   wpf                      [C#]              Common/WPF                           
WPF Class library                                 wpflib                   [C#]              Common/WPF                           
WPF Custom Control Library                        wpfcustomcontrollib      [C#]              Common/WPF                           
WPF User Control Library                          wpfusercontrollib        [C#]              Common/WPF                           
Windows Forms (WinForms) Application              winforms                 [C#]              Common/WinForms                      
Windows Forms (WinForms) Class library            winformslib              [C#]              Common/WinForms                      
Worker Service                                    worker                   [C#]              Common/Worker/Web                    
Unit Test Project                                 mstest                   [C#], F#, VB      Test/MSTest                          
NUnit 3 Test Project                              nunit                    [C#], F#, VB      Test/NUnit                           
NUnit 3 Test Item                                 nunit-test               [C#], F#, VB      Test/NUnit                           
xUnit Test Project                                xunit                    [C#], F#, VB      Test/xUnit                           
Razor Component                                   razorcomponent           [C#]              Web/ASP.NET                          
Razor Page                                        page                     [C#]              Web/ASP.NET                          
MVC ViewImports                                   viewimports              [C#]              Web/ASP.NET                          
MVC ViewStart                                     viewstart                [C#]              Web/ASP.NET                          
Blazor Server App                                 blazorserver             [C#]              Web/Blazor                           
Blazor WebAssembly App                            blazorwasm               [C#]              Web/Blazor/WebAssembly               
ASP.NET Core Empty                                web                      [C#], F#          Web/Empty                            
ASP.NET Core Web App (Model-View-Controller)      mvc                      [C#], F#          Web/MVC                              
ASP.NET Core Web App                              webapp                   [C#]              Web/MVC/Razor Pages                  
ASP.NET Core with Angular                         angular                  [C#]              Web/MVC/SPA                          
ASP.NET Core with React.js                        react                    [C#]              Web/MVC/SPA                          
ASP.NET Core with React.js and Redux              reactredux               [C#]              Web/MVC/SPA                          
Razor Class Library                               razorclasslib            [C#]              Web/Razor/Library/Razor Class Library
ASP.NET Core Web API                              webapi                   [C#], F#          Web/WebAPI                           
ASP.NET Core gRPC Service                         grpc                     [C#]              Web/gRPC                             
dotnet gitignore file                             gitignore                                  Config                               
global.json file                                  globaljson                                 Config                               
NuGet Config                                      nugetconfig                                Config                               
Dotnet local tool manifest file                   tool-manifest                              Config                               
Web Config                                        webconfig                                  Config                               
Solution File                                     sln                                        Solution                             
Protocol Buffer File                              proto                                      Web/gRPC      

足りないテンプレートに関してはオンライン取得して、インストールすることができます。

dotnet install hoge

これで、myappディレクトリ内にコンソールアプリケーションのボイラープレートコードが生成されますので、エディタを開き、このまま開発を開始できます。(Visual Studio Codeは初回起動にはC#プラグインの必要コンポーネントとダウンロードが行われるため、ネット環境が必要であり、また少し次回がかかるかもしれません。)

Riderを使用している場合は、専用ダイアログからプロジェクトを作成できます。

riderproject.png

対応していないテンプレートもあるので、その場合はコマンドラインからプロジェクトを作成する形になります。

.NET Coreツール

dotnetコマンドを使用することで、プロジェクトの作成や操作を行う他.NET Coreツールという形で各種のツールもインストールすることができます。

例えば、PowerShellも.NETの一部としてインストールすることができ、その場合は以下のようになります。

dotnet tool install -g powershell

これは他にもML.NETツールなどをインストールしたい場合も同様です。

dotnet tool install -g mlnet

デバッグ

Visual Studio Codeでデバッグすることも可能で、通常のVisual Studioのような使用感で行うことができます。
vscode.png

ただし、設定はlaunch.jsonなどを書き換えていく必要があるため、少し慣れが必要かもしれません。以下、その例を示します。

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": ".NET Core Launch (console)",
            "type": "coreclr",
            "request": "launch",
            "WARNING01": "*********************************************************************************",
            "WARNING02": "The C# extension was unable to automatically decode projects in the current",
            "WARNING03": "workspace to create a runnable launch.json file. A template launch.json file has",
            "WARNING04": "been created as a placeholder.",
            "WARNING05": "",
            "WARNING06": "If OmniSharp is currently unable to load your project, you can attempt to resolve",
            "WARNING07": "this by restoring any missing project dependencies (example: run 'dotnet restore')",
            "WARNING08": "and by fixing any reported errors from building the projects in your workspace.",
            "WARNING09": "If this allows OmniSharp to now load your project then --",
            "WARNING10": "  * Delete this file",
            "WARNING11": "  * Open the Visual Studio Code command palette (View->Command Palette)",
            "WARNING12": "  * run the command: '.NET: Generate Assets for Build and Debug'.",
            "WARNING13": "",
            "WARNING14": "If your project requires a more complex launch configuration, you may wish to delete",
            "WARNING15": "this configuration and pick a different template using the 'Add Configuration...'",
            "WARNING16": "button at the bottom of this file.",
            "WARNING17": "*********************************************************************************",
            "preLaunchTask": "build",
            "program": "${workspaceFolder}/bin/Debug/netcoreapp3.1/myapp.dll",
            "args": [],
            "cwd": "${workspaceFolder}",
            "console": "internalConsole",
            "stopAtEntry": false
        },
        {
            "name": ".NET Core Attach",
            "type": "coreclr",
            "request": "attach",
            "processId": "${command:pickProcess}"
        }
    ]
}

設定ファイル自体は自動生成する機能がありますが、プラットフォーム名(netcoreapp3.1)やアプリケーション名(myapp.dll)などは各自設定する必要があります。

Riderを使用する場合は、設定に関しては自動的に行ってくれる部分も多いのでかなり楽です。
rider.png

最後に

.NET Core登場以前はMonoなどがあったものの、やはり.NETはWindowsの環境という性格が強かったのですが、.NET Core登場以後はツール周りも含めて、Linux環境下でも遜色ない開発ができるようになってきました。

特にデプロイ先がLinuxである場合など、Linuxで開発できると便利、という場面もあるかもしれません。そのような場合に、Linuxでも開発環境が作れるというのは大きな利点だと思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Linux基礎12 -正規表現-

はじめに

Linuxでは多くのテキストファイルを扱います。そんな中で重要なのは、テキストから指定したパターンを探し出す検索機能です。
Linuxで文字列検索を行うにはgrepコマンドを使用します。grepコマンドはLinuxの中でも非常に使用頻度の高い重要なコマンドです。grepコマンドでは、単に文字列を検索するだけでなく、正規表現と呼ばれる形式で指定することで、様々なパターンを検索することができます。
今回はgrepコマンドと、そこで使用する正規表現について紹介します。

grepコマンドと正規表現

grepコマンド

grepコマンドは文字列を検索するコマンドで、Linuxではよく使われます。

grepコマンド
$ grep [オプション] <検索パターン> <ファイル名> #検索パターンが一致することを「マッチする」と言います

次の例では、/etc/passwdファイルからbashという文字列を含む行を検索しています。
スクリーンショット 2020-05-29 9.03.34.png
grepコマンドには様々なオプションがありますが、ここではよく使われる代表的なものを3つ紹介します。

オプション 内容
-n 行番号をつけてマッチ結果を表示
-i 大文字・小文字を区別しないで検索
-v マッチしなかった行を表示

他のフィルタと同様に、grepコマンドも対象のファイルを指定しない場合には、標準入力から読み込みます。したがって、別のコマンドの結果をgrepで検索するというのがよく使われます。次の例では、lsコマンドの結果にgrepを使用しています。
スクリーンショット 2020-05-29 9.10.23.png
なお、grepコマンドはマッチした部分だけでなく、マッチした行全体を表示します。

正規表現とは?

条件に合致する文字列集合を表現するための記法正規表現です。例えば、アルファベットのみで数値を含まない行とか、先頭がcronで始まる行とかを検索する時に使ったりします。

例として、cronで始まるファイルを検索してみましょう。
スクリーンショット 2020-05-29 9.19.24.png
上の例では、正規表現を'' (シングルクォート)で囲んで指定しています。これはシェルに正規表現を展開させないためです。
正規表現では、* {} $などの記号が特別な意味を持ちます。これらをメタ文字と呼びます。メタ文字の多くはシェルに対してもまた別の意味を持つことがあります。例えば*をシェルに渡すと、パス名展開のワイルドカード記号として解釈されてしまいます。正規表現で使用するメタ文字の中には、' 'で囲む必要のないものもありますが、通常は常に囲むようにしてしまって問題ないでしょう。

また、上の例では ^という記号を用いていました。これは正規表現で行の先頭を意味しています。そのため'^cron'と書くと、「行の先頭がcronという文字列である」という意味の正規表現になります。

文字にマッチするメタ文字

以下の表に今回紹介する文字にマッチするメタ文字を示します。

メタ文字 意味
. 任意の1文字
[ ] [ ]の中に含まれる、いずれかの1文字
[^ ] [ ]の中に含まれない、いずれかの1文字
\ 直後のメタ文字の意味を打ち消す

では順番に例を示していきます。検索対象のテキストファイルを用意します。
スクリーンショット 2020-05-29 9.37.33.png

まずは、この中から、tで始まって、任意の1文字を挟んで、stで終わるというパターンを検索しましょう。.を使用して、任意の1文字を指定しています。
スクリーンショット 2020-05-29 9.39.41.png
メタ文字は連続で使用できますので、t..stのように指定すると、任意の2文字を指定することもできます。
スクリーンショット 2020-05-29 9.42.29.png
また、.は記号にもマッチします。
スクリーンショット 2020-05-29 9.43.44.png
.で任意の1文字ではなく.(ドット)そのものに一致させたい場合は、直後のメタ文字の意味を打ち消す\(バックスラッシュ)を使用します。これをメタ文字をエスケープすると言います。
スクリーンショット 2020-05-29 9.45.51.png

特定の文字を指定したい場合には[ ]というメタ文字を使用します。これは[ ]ないのいずれかに一致するものという意味になりますので、次のようにt[ez]stのように書くと、testまたはtzstの文字列にマッチします。
スクリーンショット 2020-05-29 9.52.28.png
例えばアルファベットの小文字のみ検索したいとなった場合に、[abcdefghijk....]と並べるのは辛いので、この場合は、文字の範囲を意味する-(ハイフン)を利用して[a-z]と書くことができます。-を利用したパターンをさらに続けて書くこともできますから、[a-zA-Z]とすれば、アルファベットの文字全てにマッチします。
スクリーンショット 2020-05-29 9.56.54.png
[ ]を利用して、指定した文字列以外をマッチさせることも可能です。この場合は[^ ]のようにカッコの先頭に^を指定します。
スクリーンショット 2020-05-29 9.59.02.png

位置にマッチする正規表現

位置にマッチするメタ文字は、他のメタ文字と組み合わせて、マッチする箇所を指定するために利用されます。

メタ文字 意味
^ 行頭
$ 行末

例えば、netという文字列を検索したい場合はgrepコマンドでnetを指定することで検索できますが、この場合は行頭、行末関係なくnetを含む行を検索します。
スクリーンショット 2020-05-29 10.29.00.png
このとき、行頭のnetのみを検索したい場合は^netと指定してあげればいいわけです。
スクリーンショット 2020-05-29 10.30.39.png
文末の場合はnet$で検索できます。
スクリーンショット 2020-05-29 10.31.40.png
なお、^と$を組み合わせることもできます。例えば^$と指定することで、行頭の直後が行末なので、空行にマッチします。grepコマンドの-vオプションで^$を指定してあげれば、空行を取り除いて表示することができます。

繰り返しを指定するメタ文字

繰り返しを表すメタ文字を紹介します。これは他の正規表現の後に置いて、直前の正規表現が一定回数繰り返されることを意味します。まずは、繰り返しを指定するメタ文字を表に示します。

基本正規表現 拡張正規表現 意味
* * 0回以上の繰り返し
なし + 1回以上の繰り返し
なし ? 0回または1回の繰り返し
\{m,n\} {m,n} m回以上n回以下の繰り返し
\{m\} {m} ちょうどm回の繰り返し
\{m,\} {m,} m回以上の繰り返し
正規表現 意味
基本正規表現 正規表現が使えるコマンド全てで利用できる
拡張正規表現 使えるメタ文字を増やした正規表現。コマンドにオプションをつけることで使用できる(ex: grep -E)

拡張正規表現を使用する場合、grepコマンドでは-Eオプションを指定します。なお、-Eオプションを指定せずとも、\を用いることで一部の拡張正規表現を表現することも可能です。

ここからは拡張正規表現を前提として、紹介します

サンプルファイルを用意します。
スクリーンショット 2020-05-29 10.37.47.png
*の利用例をいくつか示します。
Be*rを指定すると、eが0文字以上の繰り返しのある条件で検索します。
スクリーンショット 2020-05-29 10.54.18.png
B[ea]*rと指定すれば、eとaのいずれかの文字が0文字以上の条件で検索します。
スクリーンショット 2020-05-29 10.57.18.png
+を指定すると、1文字以上なので、Brにはマッチしなくなります。
スクリーンショット 2020-05-29 11.03.05.png
?は0回または1回の繰り返しなので、次のようにスペースがあってもなくてものような条件で検索できます。
スクリーンショット 2020-05-29 11.05.01.png
繰り返しの回数を指定したい場合には{m,n}を使います。これは郵便番号や携帯番号などをマッチさせる時に使います。例えば郵便番号なら[0-9]{3}-[0-9]{4}という表現になりますね。今回は、eが3回以上連続する場合のみ抜き出すことにしましょう。
スクリーンショット 2020-05-29 11.08.19.png

その他のメタ文字

これまでに紹介したメタ文字以外で、使用頻度の高いものを紹介します。

基本正規表現 拡張正規表現 意味
\(\) () グループ化する
なし |(パイプ) 複数の正規表現をORで連結する

( )は正規表現をグループ化するためのメタ文字です。例えばWineWineWineのように単語が繰り返しているものをマッチさせたい時に、Wine{2,}のような検索パターンを指定しても、Wineのeにのみ2回以上という条件が作用してしまいます。このようなケースでWineという単語をグループ化する()を使用します。(Wine){2,}と書くことで、Wineという単語の繰り返しをマッチさせることができるようになります
スクリーンショット 2020-05-29 11.16.26.png
|(パイプ)は多くの場合、()とセットで用いられます。次のようにVodkaまたはWineに一致させたい時に使います。
スクリーンショット 2020-05-29 11.18.44.png

正規表現の利用

ここまではgrepコマンドによる正規表現の利用に焦点を当てて紹介してきましたが、正規表現は、Vimやlessコマンドでの検索の時にも使用できます。多くのプログラミング言語でも正規表現は使用されており、テキスト処理を行うには必須の知識と言えるでしょう。

Vimでの使用例を示します。
スクリーンショット 2020-05-29 11.22.25.png

参考資料

新しいLinuxの教科書

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

EC2でのボリューム追加

AWSのEC2とかで、ボリュームを追加してもそのまま使えません。
ボリュームをマウントした上で、ドキュメント領域を移動する必要があります。

参考:https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ebs-using-volumes.html

現状の確認

1. diskの確認

lsblkコマンドで確認します

$ lsblk

NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0   8G  0 disk
`-xvda1 202:1    0   8G  0 part /
xvdb    202:16   0   8G  0 disk

AWSのコンソールでも見えているように、8GiBのディスクが2つ認識されています
image.png

2. ディスクの利用状況の確認

dfコマンドで確認します

$ df

Filesystem     1K-blocks    Used Available Use% Mounted on
devtmpfs          482556       0    482556   0% /dev
tmpfs             506492       0    506492   0% /dev/shm
tmpfs             506492   25804    480688   6% /run
tmpfs             506492       0    506492   0% /sys/fs/cgroup
/dev/xvda1       8377344 2516396   5860948  31% /
tmpfs             101300       0    101300   0% /run/user/1001

FileSystemには xvda1しか割り当てられていないのが分かります

で、xvdbをマウントするとOSから利用可能になるのですが、ファイル容量が必要なログディレクトリとか/var/www/htmlとかは /配下にあるので、そのディレクトリをマウントする必要があります。

とはいえ、新しく増やした領域を /var/www/htmlにマウントすると全て見えなくなってしまうので、
別のディレクトリにマウントした上で、ファイルを退避してディレクトリを書き替える必要が出てきます

ファイルシステムがあるかどうかを確認します

$ sudo file -s /dev/xvdb
/dev/xvdb: data

3. ファイルシステムを作成する

未加工のブロックデバイスなので、ボリュームにファイルシステムを作成します

$ sudo mkfs -t xfs /dev/xvdb
meta-data=/dev/xvdb              isize=512    agcount=4, agsize=524288 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=0, sparse=0
data     =                       bsize=4096   blocks=2097152, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal log           bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0

再度ファイルシステムを確認します

# sudo file -s /dev/xvdb
/dev/xvdb: SGI XFS filesystem data (blksz 4096, inosz 512, v2 dirs)

4. ディレクトを作成してマウント

移動したいファイルを一旦退避してコピーする

$sudo mv /var/www /var/www2
$ sudo mkdir /var/www
$ sudo mount /dev/xvdb /var/www

※ 心配があるならば、自動マウントの設定、確認をしてから移動をした方がいいかも・・

退避したディレクト以下のディレクトリを移動します

$ sudo mv /var/www2/cgi-bin /var/www/cgi-bin
$ sudo mv /var/www2/html /var/www/html

ディレクトリが移動されていることを確認

$ df
Filesystem     1K-blocks    Used Available Use% Mounted on
devtmpfs          482556       0    482556   0% /dev
tmpfs             506492       0    506492   0% /dev/shm
tmpfs             506492   25812    480680   6% /run
tmpfs             506492       0    506492   0% /sys/fs/cgroup
/dev/xvda1       8377344 2273452   6103892  28% /
tmpfs             101300       0    101300   0% /run/user/1001
/dev/xvdb        8378368  277444   8100924   4% /var/www

5. 自動マウントの設定

まずは、デバイスのUUIDをblkidで確認します

$ sudo blkid
/dev/xvda1: UUID="388a99ed-9486-4a46-aeb6-06eaf6c47675" TYPE="xfs"
/dev/xvdb: UUID="719d9ce5-984d-4dd8-89e8-ca9fb0934508" TYPE="xfs"

fstabファイルをバックアップを取った上で編集します

$ sudo cp /etc/fstab /etc/fstab.orig
$ sudo vi /etc/fstab

UUID=388a99ed-9486-4a46-aeb6-06eaf6c47675 /                       xfs     defaults        0 0
UUID=719d9ce5-984d-4dd8-89e8-ca9fb0934508 /var/www                xfs     defaults        0 2

fstabが動作することの確認
ディスクを取り外して(unmount : コマンドはumountだけど)、設定ファイル通りにマウントを試す

$ sudo umount /var/www
$ sudo mount -a

エラーが出なければ問題なし!
ここで何かあったら、こちらを確認して下さい
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ebs-using-volumes.html

6. 最後にインスタンスを再起動して動作確認!

再起動してwebサイトにアクセスしたらつながらなくて焦ったのですが、httpdが起動していなかっただけでした。 systemct enable httpd をしてなかった?

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む