まるまろぐ

本ブログに記載の情報は全て飼い犬が書いたものであり、その内容に誤りや欠陥があった場合にも、私は一切の責任を負いません。

aptでインストール済みのパッケージ構成を(他のサーバで)復元する

古いサーバにaptでインストールされているパッケージたちを新しいサーバにもインストールする必要があり、とりあえずググって出てきた方法で試したがうまくいかず、他にないか探していたらちょうどいいものがあったのでメモ。

環境

移行前、移行先のサーバ共にUbuntu Server 18.04 LTS

手順

1. 移行前のサーバ

sudo apt update & upgrade
sudo apt install apt-clone
sudo apt-clone clone ~/hoge

すると、インストールできないパッケージ等の情報が標準出力に出るとともに、hoge.apt-clone.tar.gzが生成されるので、scpなどで移行先のサーバに送ってください(自分はディレクトリがマウントされていたので送る必要はなかったけど)。

2. 移行先のサーバ

sudo apt update & upgrade
sudo apt install apt-clone
sudo apt-clone restore ~/hoge.apt-clone.tar.gz

以上でインストールは完了です。

余談

もともとはこちらなどに書かれているように、dselectを使ってインストールしようとしていました。しかし、 f:id:hidamarumaru:20181109202928p:plain という警告が出て、まあ入れ直すのだから大丈夫だろうとは思いつつも、highly recommendedと言われてるし、ググってもこの警告に関して言及してる人が見当たらなかったこと、そもそも手順がややこしくpippip freeze > requirements.txtpip -r requirements.txtみたいにあっさり移行できる方法がないのかと思ったこともあり、改めて他の手段を探すことにした結果、apt-cloneを見つけて使うことにしました。そのとき日本語の情報が見当たらなかったのでこの記事を書くことにしました。

上のダイアログでNoを選んでも無事インストールできていたのか気になる……。

参考

https://github.com/mvo5/apt-clone

Hugo + Academic + Netlify で一瞬でウェブサイトを作って公開する

記事タイトルで一瞬でウェブサイトを作るとか言ってるので、何が起きているのかの説明は後回しにして、まずは最短の手順を示したいと思います。

1. GitHub 上に Academic のテンプレートをダウンロードしつつ Netlify と連携

以下のリンクを踏んで緑色のボタンをポチポチしてください。GitHub アカウントを持っていない場合は作ってください。

https://app.netlify.com/start/deploy?repository=https://github.com/sourcethemes/academic-kickstart

するとこんな感じの画面になると思います。 f:id:hidamarumaru:20180820200141p:plain これでもうウェブサイトは完成し公開されました。上の画像で言うと https://objective-sammet-5a4f1a.netlify.com がウェブサイトのURLで既にアクセスできるわけですが、もしこの自動的に割り当てられたURLが嫌な場合は Site settings から Change site name ボタンを押すことで変えられます。独自ドメインも使えますがここでは触れません。

2. GitHub から更新する

次はウェブサイトの内容を編集します。先ほどの手順によって GitHubリポジトリが作成されているはずです。リポジトリ名を変更していなければURLは https://github.com/username/academic-kickstart になっているはずです(username は適宜置き換えてください)。 まずはconfig.tomlを編集してみましょう。git cloneしてもいいのですが、ここでは簡単のため GitHub 上で直接いじります。config.tomlのページに移動したあと、ペンっぽいアイコンをクリックしてください (下の画像で矢印が指してる先です)。

f:id:hidamarumaru:20180820204419p:plain

すると編集できるようになるので、
title = "Academic"
となっているところを
title = "Test"
と書き換えてください (もちろん Test じゃなくても自分の名前でもなんでも良いです)。 それから、59行目の
color_theme = "default"

  • ocean
  • forest
  • coffee
  • dark
  • 1950s

のいずれかに変えてください。

できたらページの一番下までスクロールして Commit changes をクリックしましょう。しばらく待つと自動的にウェブサイトの内容が更新されているはずです。同様の方法でconfig.tomlcontentディレクトリ内の様々なファイルを編集し commit すればウェブサイトの各コンテンツを更新できます。ファイルを見ればどこをどう編集すればよいかというのはだいたいわかると思います。たとえば、Biography を編集したい場合はcontent/home/about.mdを開いて一番下の

# Biography

Lena Smith is a professor of artificial intelligence at the Stanford AI Lab. Her research interests include distributed robotics, mobile computing and programmable matter. She leads the Robotic Neurobiology group, which develops self-reconfiguring robots, systems of self-organizing robots, and mobile sensor networks.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed neque elit, tristique placerat feugiat ac, facilisis vitae arcu. Proin eget egestas augue. Praesent ut sem nec arcu pellentesque aliquet. Duis dapibus diam vel metus tempus vulputate. 

となっている部分を

# 自己紹介

こんにちは

と書き換えてください。もちろん、これはただの Markdown 記法なので、見出しを追加したり、シンタックスハイライトをつけたりすることもできます。 f:id:hidamarumaru:20180820222147p:plain より高度な編集をしたい場合は 公式ドキュメント を参照してください。

何が起きているのか?

Hugo

上記の手順では全く表に出てきませんでしたが、このウェブサイトを作る上で裏では Hugo という静的ウェブサイトのジェネレータが動いています。Academic は Hugo のテーマのひとつです。リポジトリthemesを開いてみると入っているのがわかると思います。テーマの一覧は

Complete List | Hugo Themes

で見ることができ、Netlify との連携を提供してくれているテーマであれば Academic 以外のテーマでも今回のようなことができます。

Netlify

Netlify は静的サイト用のホスティングサービスです。本来であれば更新をサイトに反映するには Hugo がページを生成するためにhugoコマンドを打ち、それから生成したファイル群をサーバにデプロイしなければいけないのですが、Netlify が そのへんのことを GitHub に変更が加えられるたびに勝手にやってくれています。そして、その勝手にやってもらうための設定もテーマの製作者が用意して提供してくれているので、もはや我々は何もする必要がなかったわけですね。ただ、Netifly は本当に簡単なのでやろうと思えばすぐに自分でも自動化できます。ちなみに設定はリポジトリnetlify.tomlや Netlify 上の Settings の Build & deploy にあります。

Ubuntu のユーザにあとからホームディレクトリを設定する方法

日本語で「Ubuntu ホームディレクトリ あとから」とググってもなぜか誰も言及してる人がいなくて、ないのか……と思ったが英語で検索してみたらあったのでメモ。

mkhomedir_helper <username>

と打てばそのユーザーのホームディレクトリがuseradd-mオプションを指定した時のようにいい感じで作成されます。

参考:Ubuntu Manpage: mkhomedir_helper - Helper binary that creates home directories

[Python]ファイルオブジェクトを特定の文字列で分割しながら読み込む

実行環境


たとえば、次のような txt ファイルがあったとします。

寒い冬が北方から、狐の親子の棲んでいる森へもやって来ました。
EOS
 或朝洞穴から子供の狐が出ようとしましたが、
「あっ」と叫んで眼を抑えながら母さん狐のところへころげて来ました。
EOS
「母ちゃん、眼に何か刺さった、ぬいて頂戴早く早く」と言いました。
EOS

このテキストをEOSごとに分割して何かをすることを考えます。 一番簡単な方法は、一度read()で読み込んでしまい、split()を使って分割することです。

with open('example.txt') as f:
    txt = f.read()
    txt_list = txt.split('EOS')
    for lines in txt_list:
        # 何か操作をする

これはうまくいきます。しかしファイルオブジェクトを一度に読み込んでしまっているので、ファイルサイズが小さい時は良いですが、大きすぎる時には避けたい手段です。
そこで、素直にEOSが来るまで各行をappend()してリストに保持しておき、EOSが来たらそのリストを処理することを考えます。

with open('example.txt') as f:
    lines = []
    for line in f:
        if line == 'EOS\n':
            for li in lines:
                # 何か操作をする
            lines = []
        else:
            lines.append(line)

これは先ほどより良いやり方ですが、EOSの間隔が極端に大きかった場合、結局一度にたくさん読み込んでしまうことになります。それに、できれば一度forで回したものを保持してまたforで回すというのは同じことの繰り返しなのでやりたくありません。
そこで、iter()を使うことを考えてみます。iter()公式ドキュメントにも記載されているように、第二引数に文字列を与えることで、その文字列が出てくると止まるイテレータを作ることができ、特定の文字列までファイルオブジェクトを読み込みたいときに便利です。

with open('example.txt') as f:
    while True:
        for line in iter(f.readline, 'EOS\n'):
            if line == '':
                break
            # 何か操作をする
        else:
            continue
        break

readlineは終端まで行くと空文字列を返すので、それを利用してループを抜けています。多重ループを抜けるためにfor-elsecontinueを使っています。これらについては公式ドキュメントのチュートリアルが、またPythonの多重ループの抜け方についてはこちらの記事が参考になるかと思います。
この方法は先ほどの問題を解決していますが、コードが複雑になります。そこで明示的にファイルの終端を求めることを考えてみます。

with open('example.txt') as f:
    f.seek(0,2)
    size = f.tell()
    f.seek(0)
    while f.tell() < size:
        for line in iter(f.readline, 'EOS\n'):
            # 何か操作をする

この方法は多重ループを抜けるために複雑な制御構文を書く必要がなく、for文を内包表記にすることも可能ですが、Pythonではファイルオブジェクトのサイズを一発で知ることはできないため、何行か余計に書く必要があります。 また、ファイルオブジェクト以外にこの手法を取ることはできません。

色々と検討してきましたが、どれも一長一短でたったひとつの冴えたやり方を見つけだすには至りませんでした。
最初の方法以外は一行ごとの読み込みであり純粋な分割ではないのも気になるところではあります(ほとんどの場合はメリットとして働くでしょうけど)。

指摘、追加、修正、質問などあればコメントまでよろしくお願いします。

技術系のブログをはじめようと思います

最近はパソコンを使ってなんやかんやすることも多くなってきたので、備忘録として新しくブログを始めることにしました。

検索エンジンから来た人が記事を読むことを全く想定しないわけではないですが、きっちり書くのであれば自前のブログを用意するよりQiitaとかに投げたほうがいいのかな、という気もするので、あくまで日記的なノリで書いていこうかなと思っています。