リモートマシンのファイル群のtarアーカイブをリモートマシンに一時ファイルを作成しないでsshで取得する

ありがちな方法(一時ファイル作成)

リモートマシンのファイル群をtarアーカイブとして取得する場合、以下のようのリモートマシンで一度tarアーカイブを作成することは、よく見る状況である。
  1. リモートマシンにSSHでログイン
  2. リモートマシンで、tarコマンドを実行してtarアーカイブを作成する
  3. ローカルマシンからscpで、リモートマシンのtarアーカイブをコピー
  4. リモートマシンで、tarアーカイブを削除
この方法の欠点は、リモートマシンに一時的にtarアーカイブを保存する空き容量が必要なことである。 大量のファイルをローカルにコピーするときは、これがネックになる。

一時ファイルを作らない方法

リモートマシンremoteの/home/foo以下をすべてtarアーカイブfoo.tar.gzとしてバックアップする場合、 ローカルマシンで以下のように入力する。
ssh remote tar czf - /home/foo > foo.tar.gz
上記の青字の部分は、リモートマシンで実行されるコマンドである。リモートで実行したコマンドの標準出力は、ローカルのsshコマンドそのものの標準出力に出力される。上記でtarの出力ファイルとして-(標準出力)を指定しているので、結果としてローカルのsshの標準出力にtarアーカイブの内容が出力される。そこで> foo.tar.gzでローカルのファイルにリダイレクトすれば、そのままtarアーカイブとなる。これを図にすると次のイメージである。
なお、標準入出力については下記を参照。 また、tarをカレントディレクトリが/home/fooで実行させるには以下のようにする。
ssh remote "(cd /home/foo; tar czf - .)" > foo.tar.gz

多段SSHごしでのtarアーカイブ取得

local -> remote -> remote2のようにremoteを介してremote2へ多段SSHして、remote2のファイル群のtarアーカイブを直接取得することもできる。
ssh -J remote remote2 tar czf - /home/goo > goo.tar.gz

lxc-createでバージョンを指定してDebianコンテナを作成する

例:Debian 12 (bookworm)をインストール

# lxc-create -n name -t debian -- -r bookworm
他のバージョンをインストールする場合、上記の青字の部分を下のcode nameに置換する。
versioncode name
10buster
11bullseye
12bookworm

[付録] 初期状態のでプロセス

Debain 10

UID          PID    PPID  C STIME TTY      TIME     CMD
root           1       0  0 18:53 ?        00:00:00 /sbin/init
root          39       1  0 18:53 ?        00:00:00   /lib/systemd/systemd-journald
root          63       1  0 18:53 ?        00:00:00   /sbin/dhclient -4 -v -i -pf /run/dhclient.eth0.pid -lf /var/lib/dhcp/dhclient.eth0.leases -I -df /var/lib/dhcp/dhclient6.eth0.leases eth0
root          85       1  0 18:54 ?        00:00:00   /usr/sbin/sshd -D
root          86       1  0 18:54 pts/0    00:00:00   /sbin/agetty -o -p -- \u --noclear --keep-baud console 115200,38400,9600 vt220

Debian 11

UID          PID    PPID  C STIME TTY      TIME     CMD
root           1       0  0 18:55 ?        00:00:00 /sbin/init
root          38       1  0 18:55 ?        00:00:00   /lib/systemd/systemd-journald
root          63       1  0 18:55 ?        00:00:00   /sbin/dhclient -4 -v -i -pf /run/dhclient.eth0.pid -lf /var/lib/dhcp/dhclient.eth0.leases -I -df /var/lib/dhcp/dhclient6.eth0.leases eth0
root          89       1  0 18:55 pts/0    00:00:00   /sbin/agetty -o -p -- \u --noclear --keep-baud console 115200,38400,9600 vt220
root          90       1  0 18:55 ?        00:00:00   sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups

Debian 12

UID          PID    PPID  C STIME TTY      TIME     CMD
root           1       0  0 18:59 ?        00:00:00 /sbin/init
root          38       1  0 18:59 ?        00:00:00   /lib/systemd/systemd-journald
root          70       1  0 18:59 ?        00:00:00   dhclient -4 -v -i -pf /run/dhclient.eth0.pid -lf /var/lib/dhcp/dhclient.eth0.le
root          97       1  0 18:59 pts/0    00:00:00   /sbin/agetty -o -p -- \u --noclear --keep-baud - 115200,38400,9600 vt220
root          98       1  0 18:59 ?        00:00:00   sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups

参考

LXCの記事一覧

make入門 #4 組み込みルール

組み込みルールの概要

前回(make入門 #3 自動変数とパターンルール)は以下のようなパターンルールについて説明しました。
prog2: main.o sub.o
        gcc -o $@ $^

%.o: %.c
        gcc -c -o $@ $<

main.o: main.c sub.h
sub.o: sub.c sub.h
ここで青字で示されるパターンルールをMakefileから削除してみます。
prog2: main.o sub.o
        gcc -o $@ $^

main.o: main.c sub.h
sub.o: sub.c sub.h
このMakefileをカレントディレクトリに配置してmakeを実行します。
$ make
cc    -c -o main.o main.c
cc    -c -o sub.o sub.c
gcc -o prog2 main.o sub.o
なんと、このMakefileでもビルドが成功します。 とくに驚くべきことは、*.cから*.oを作成する方法を指定しなていにもかかわらず、コンパイルが実行されています。 実は、makeはデフォルトのパータンルールを持っており、パターンルールが明示されていない場合、そのデフォルトのルールが使用されます。 このパターンルールを組み込みルールと呼びます。

C言語用の組み込みルール

以下のGNU Makeの公式マニュアルに組み込みルールが列挙されています。 この中で*.cから*.oを作成する組み込みルールは以下のように記載されています。
$(CC) $(CPPFLAGS) $(CFLAGS) -c
さらに、上記の変数の$(CC)なども組み込みのデフォルト値があります。以下に記載されています。 上記のサイトに記載されている、それぞれの変数のデフォルト値を以下に示します。
変数デフォルト値
CC cc
CPPFLAGS (なし)
CFLAGS (なし)
これらの変数をMakefile内で以下のように上書きできます。
CFLAGS = -g3 -O2

prog2: main.o sub.o
        gcc -o $@ $^

main.o: main.c sub.h
sub.o: sub.c sub.h
このMakefileを使ってmakeを実行すると以下のようにCFLAGSに設定したオプションが付与されています。
cc -g3 -O2   -c -o main.o main.c
cc -g3 -O2   -c -o sub.o sub.c
gcc -o prog2 main.o sub.o

まとめ

本記事では、組み込みルールについて説明しました。

以下には、make入門の全記事がリストアップされています。

私の.screenrcを紹介します

エスケープキーを^Tに設定

escape ^Tt

スタートアップメッセージを非表示

startup_message off

キャプション(ステータスライン)の設定

# %`   : バクチクコマンドの結果
# %-w  : カレントウィンドウより前のウィンドウリスト
# %{= wk} : w: 白, k: 黒 (1つ目文字と2つ目の文字は、それぞれ前景色と背景食)
# %n   : ウィンドウ番号
# %{-} : 色をリセット
# %n   : ウィンドウタイトル
# %+w  : カレントウィンドウより後のウィンドウリスト
caption always "%?%F%{= Wk}%:%{= wK}%? %`%-w%?%P%{= b.}%:%{= k.}%?%?%F%{= .C}%:%{= wk}%?%50> %n %?%F%{= .W}%:%{= wk}%?%?%t %?%?%F%{= Wk}%:%{= wK}%?%+w %<"
上記の設定によるステータスラインの例。白い背景色のラインで、カレントウィンドウは白黒を反転。ウィンドウ番号は水色。

ハードステータスを無視

hardstatus ignore

文字コードをUTF8に

encoding utf8

スクロールバック行数を設定

defscrollback 1024

画面を分割したときの、ウィンドウの移動やサイズ変更のためのキーバインド

bind r eval 'echo Resize window' 'command -c resize'
bind -c resize ^] command
bind -c resize k eval 'resize +1' 'command -c resize'
bind -c resize j eval 'resize -1' 'command -c resize'
bind -c resize l eval 'resize +1' 'command -c resize'
bind -c resize h eval 'resize -1' 'command -c resize'

bind _ resize max
bind = resize =

bind w focus
bind j focus down
bind l focus right
bind k focus up
bind h focus left
bind K kill

誤ってフローコントロール操作(XON/XOFF)をしないよう、それらのキーバインドを無効化

通常、フローコントロールを必要とすることはほぼないが、端末でフローコントロールを有効にしてしまうと 文字が入力できなくなり、すこしビックリする。そのため、徹底的にフローコントロールが発生しないようにキーバインドを設定。

フローコントロール開始・終了のキーバインドを無効化

bind s
bind ^s
bind q
bind ^q

フローコントロールモード変更のキーバインドを無効化

bind f
bind ^f

デフォルトのフローコントロールをOFFにして、現在設定もOFFに

defflow off
flow off

レジスタをペーストするためのキーバインド

bind P paste

レジスタaの内容をペーストするキー操作

  • ^t P a

レジスタaに文字列を登録

  • ^t :register a [登録する文字列]

ウィンドウのタイトルを設定

shelltitle "$ |bash"

ヴィジュアルベルをOFFに

vbell off

256色表示設定

term screen-256color

ログを有効化

deflog on
logfile .screen-logs/%Y%m%d.%S.%n.log
logtstamp on
logtstamp string "\n-- SCREEN [%Y/%m/%d %02c:%s] %n:%t --\n"

make入門 #3 自動変数とパターンルール

前回(make入門 #2 複数のルール)は、複数のルールからなるMakefileについて説明しました。 その際に気づいた方もいるかもしれませんが、ファイル名などが反復して使用されています。 今回は、反復した記述を少なくし、よりシンプルにMakefileを記述するための機能である自動変数とパターンルールを説明します。

自動変数を使って記述

以下は前回のMakefileです。
prog2: main.o sub.o
        gcc -o prog2 main.o sub.o

main.o: main.c sub.h
        gcc -c -o main.o main.c

sub.o: sub.c sub.h
        gcc -c -o sub.o sub.c
これを自動変数を使うと次のように記述することができます。$@$^のように$から始まる単語が自動変数です。 それぞれの意味を下の表に示します。
prog2: main.o sub.o
        gcc -o $@ $^

main.o: main.c sub.h
        gcc -c -o $@ $<

sub.o: sub.c sub.h
        gcc -c -o $@ $<
自動変数 説明
$@ ターゲット(入力)ファイル(コロンの左側)
$^ すべての依存(出力)ファイル(コロンの右側のファイル全て)
$< 最初の依存ファイル(コロンの右側の最初のファイル)
このMakefileをカレントディレクトリに配置してmakeを実行すると以下のように自動変数が、具体的なファイル名に置換されて実行されていることが分かります。
$ make
gcc -c -o main.o main.c
gcc -c -o sub.o sub.c
gcc -o prog2 main.o sub.o

パターンルール

上記の自動変数を使ったMakefileでmain.oとsub.oを作成するコマンドが同じになっています。ソースコードが増えていっても、同様の記述になるでしょう。 Makefileは、*.cから*.oを作成するような同じコマンドになるルールを共通化する仕組みを持っています。この仕組みをパターンルールと呼びます。 パターンルールを使って、記載したMakefileの例を以下に記載します。
prog2: main.o sub.o
        gcc -o $@ $^

%.o: %.c
        gcc -c -o $@ $<

main.o: main.c sub.h
sub.o: sub.c sub.h

青字で示した%.o: %.cという行があります。これは、*.cから*.oを作るルールという意味です。 そのコマンドとして、gccを使ったコンパイル処理が記述されています。ここでの$@$<は 実際のファイルに置換されるため、自動変数を使うとファイル名だけ異なる類似の処理をひとつのコマンドとして記載できます。

また、main.oとsub.oのルールにはコマンドがありません。具体的なコマンドはパターンルールで定義してあるため、 ここでは入出力(依存)関係のみを記述すればよくなります。

まとめ

本記事では、自動変数とパターンルールについて説明しました。

以下には、make入門の全記事がリストアップされています。

Linuxカーネルの主要なCONFIG

Linuxの主要なCONFIGを以下のテーブルに記載します。とくにmake defconfigで有効化されないものを中心に記載します。 また、この記事の内容はLinux 6.2.7をベースに作成されています。
CONFIG 説明
BRIDGE ブリッジ機能
SQUASHFS squashfsサポート
SQUASHFS_XATTR squashfsでのxattrのサポート
OVERLAY_FS オーバイレイFSのサポート。Dockerなどで使用されている。
FUSE_FS FUSE FSのサポート

CONFIGの追加例

CONFIG_BRIDGEを有効にする例を示します。Linuxのソースディレクトリで次のコマンドを実行すると、最初は以下のように無効化されています。
$ cat .config | grep CONFIG_BRIDGE
# CONFIG_BRIDGE is not set
有効化するには以下を実行します。
scripts/config --enable BRIDGE
再度.configを確認すると有効化されています。
$ cat .config | grep CONFIG_BRIDGE
CONFIG_BRIDGE=y
また、この変更に伴って新たに設定可能になったCONFIGを以下で確認できます。
$ make listnewconfig
CONFIG_BRIDGE_NF_EBTABLES=n
CONFIG_BRIDGE_IGMP_SNOOPING=y
CONFIG_BRIDGE_MRP=n
CONFIG_BRIDGE_CFM=n
これらについて個別に設定しても良いですし、以下のようにするとデフォルトに設定できます。
make olddefconfig

参考記事

make入門 #2 複数のルール

前回の記事(make入門 #1 makeとは)では、makeがどのようなものかを説明しました。 今回は、C言語を使った開発などでよくある複数のソースファイルから1つの実行ファイルを作成するMakefileの書き方を説明します。

処理のフロー

図のように3つのソースファイルを用意します。それぞれのファイルの概要は次のとおりです。
ファイル名 説明
main.c メインのソースコード
sub.c ユーザ定義関数を含むソースコード
sub.h ユーザ定義関数のヘッダファイル
*.o *.cファイルをコンパイルして生成したオブジェクトファイル
prog2 2つのオブジェクトファイルをリンクして作成される実行ファイル
これを行うMakefileは次のようになります。
prog2: main.o sub.o
        gcc -o prog2 main.o sub.o

main.o: main.c sub.h
        gcc -c -o main.o main.c

sub.o: sub.c sub.h
        gcc -c -o sub.o sub.c
各ソースコードについては、末尾に掲載します。

Makefileの説明

処理ルールと入力ファイル

図の青い部分は、処理を表しています。Makefileでもそれに対応して、3つのルールが記載されています。 前回は、:の右側の入力ファイルがひとつだけの例を紹介しました。今回の例のように入力ファイルを複数記述することも可能です。 その場合、入力ファイルのどれか一つでも変更があれば、出力ファイルを作成するための処理が実行されます。

ルール記述の順序

Makefileの中でprog2の作成ルールが最も先頭に記載されています。例えば、main.oの作成ルールを先頭にすることはできません。 なぜなら、Makefileは、複数のルールが記述されていた場合、先頭のルールで記述された出力ファイルを作成しようとするからです。 つまり、main.oの作成ルールが先頭にあると、makeを実行してもmain.oが作成されて動作が完了します。

prog2の入力ファイルとしてmain.oとsub.oが記述されています。 初めてmakeを実行する場合、これらのファイルが存在しません。 その場合、makeは、次のようにmain.oとsub.oの作成ルールにしたがって、それらを作成します。

$ make
gcc -c -o main.o main.c
gcc -c -o sub.o sub.c
gcc -o prog2 main.o sub.o

一部のファイルを更新

ここで、sub.cだけを更新してみます。実際には内容を更新しますが、ここではmakeの動作を確かめるのが目的なので、touchコマンドでタイムスタンプのみ更新します。
touch sub.c
makeを実行するとsub.oが再作成され、それに依存しているprog2も再作成されました。 main.oについては、その入力ファイルであるmain.cが更新されていないため、なにも処理が行われませんでした。 このように依存関係にしたがって、必要な処理のみを実行することがmakeの利点です。
$ make
gcc -c -o sub.o sub.c
gcc -o prog2 main.o sub.o

ヘッダファイルの更新

sub.hは、main.cでもsub.cでも使われており、main.oおよびsub.o両方の入力ファイルとしてMakefileに記載されています。 このヘッダファイルを更新すると、以下のようにどちらの.oファイルが更新されて、それに依存するprog2も再作成されます。
$ touch sub.h 
$ make
gcc -c -o main.o main.c
gcc -c -o sub.o sub.c
gcc -o prog2 main.o sub.o

ソースコード

main.c

#include <stdio.h>
#include "sub.h"

int main() {
    printf("Calculated result: %d\n", calc(1, 3));
    return 0;
}

sub.h

int calc(int a, int b);

sub.c

int calc(int a, int b)
{
    return a * 2 + b - 1;
}

まとめ

本記事では、複数のルールをMakefileに記述する方法について説明しました。 次回は、自動変数と拡張子ルールという機能を説明します。

以下には、make入門の全記事がリストアップされています。