シェルスクリプト備忘録

apt
インストール済みの一覧を取得
apt list --instaled
にて一覧を取得できる。
username@penguin:~$ apt list --installed
一覧表示...
adduser/stable,now 3.134 all [インストール済み]
adwaita-icon-theme/stable,now 43-1 all [インストール済み、自動]
alsa-topology-conf/stable,now 1.2.5.1-2 all [インストール済み、自動]

パッケージ名のみで良い場合は、awk
を使って出力を /
区切りにし、最初のフィールドのみ抽出する。
username@penguin:~$ apt list --installed | awk -F '/' '{print $1}'
一覧表示...
adduser
adwaita-icon-theme
alsa-topology-conf

Visual Studio Code のインストール
公式サイトの deb
ファイルを使ったインストールでなく、マイクロソフトのリポジトリを登録して apt
経由でインストールする方法について。
# 0. HTTPS経由でリポジトリにアクセスするためのソフトをインストール
sudo apt install -y apt-transport-https
# 1. マイクロソフト公開鍵の取得
curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > packages.microsoft.gpg
# 2. 鍵をインストール
sudo install -o root -g root -m 644 packages.microsoft.gpg /usr/share/keyrings/
# 3. インストールして不要となった鍵を削除
rm packages.microsoft.gpg
# 4. apt に登録
sudo sh -c 'echo "deb [arch=amd64 signed-by=/usr/share/keyrings/packages.microsoft.gpg] https://packages.microsoft.com/repos/vscode stable main" > /etc/apt/sources.list.d/vscode.list'
# 5. リポジトリ情報を更新し、VSCode をインストール
sudo apt update
sudo apt install -y code

0. HTTPS経由でリポジトリにアクセスするためのソフトをインストール
マイクロソフトのリポジトリは https://packages.microsoft.com/repos/ にあり、HTTPS通信で取得することになる。
ここでは apt
で HTTPS 経由でアクセスする際の apt-transport-https
をインストールしている。
1. マイクロソフト公開鍵の取得
ここでは curl
経由でマイクロソフトの公開鍵を取得し、GPG(GNU Privacy Guard:公開鍵を利用した暗号化ソフトウェア)で鍵データをカレントディレクトリに出力している。
マイクロソフトの公開鍵は下記のようになっているため、gpg --dearmor
で OpenPGP ASCII armor 形式のバイナリデータに変換している。
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.7 (GNU/Linux)
■■■ ここに鍵情報 ■■■
-----END PGP PUBLIC KEY BLOCK-----
2. 鍵をインストール
install
コマンドを使い、所有者や権限情報等を設定した上で 特定のディレクトリにコピーすることができる。
ここでは前述の鍵データを /usr/share/keyrings/
に、所有者及びグループを root
、アクセス権は 644
(-rw-r--r--
)の形でコピーしている。
3. インストールして不要となった鍵を削除
カレントディレクトリにある鍵データは不要になったので、rm
コマンドで削除している。
4. apt に登録
apt
に各種情報(公開鍵をどこに設置しているか、リポジトリの場所 など)を登録している。
5. リポジトリ情報を更新し、VSCode をインストール
先程の登録情報を反映するため、一旦 apt update
で更新をかけている。その後は code
でインストールが可能に。
参考文献

test
コマンド
test
コマンドは、評価式を受け取り真偽値(≒ 0
, 1
の終了ステータス)を返す。
基本的な構文
基本的な構文は、test EXPRESSION
の形となる。
# 基本的な構文
test EXPRESSION
# 評価式の真偽を反転
test ! EXPRESSION
複数式の評価
複数式をまとめて評価する場合は、AND や OR を表すオプションを使用する。
# EXP_A かつ EXP_B
test EXP_A -a EXP_B
# EXP_A または EXP_B
test EXP_A -o EXP_B
また丸括弧によるグルーピングを用いることで、優先度を調整することができる。
# EXP_A または 「EXP_B かつ EXP_C」
# ※ `-a` と `-o` の両方が指定されている場合、`-a` が優先される
test EXP_A -o EXP_B -a EXP_C
# 「EXP_A または EXP_B」かつ EXP_C
test \( EXP_A -o EXP_B \) -a EXP_C
コマンドの省略
test
コマンドは、角括弧を使うことで省略して書ける。
# 基本的な構文
[ EXPRESSION ]
# 評価式の真偽を反転
[ ! EXPRESSION ]
# EXP_A かつ EXP_B
[ EXP_A -a EXP_B ]
# EXP_A または EXP_B
[ EXP_A -o EXP_B ]
# EXP_A または 「EXP_B かつ EXP_C」
[ EXP_A -o EXP_B -a EXP_C ]
# 「EXP_A または EXP_B」かつ EXP_C
[ \( EXP_A -o EXP_B \) -a EXP_C ]
各種テスト
ここでは、分野別に代表的なテスト例を示す。他のオプションについての詳細は man test
で確認できる。
整数のテスト
式 | 意味 | 説明 |
---|---|---|
int1 -eq int2 |
equal |
int1 と int2 が等しい |
int1 -ne int2 |
not equal |
int1 と int2 が等しくない |
int1 -lt int2 |
less than |
int1 が int2 より小さい |
int1 -le int2 |
less than or equal |
int1 が int2 以下 |
int1 -gt int2 |
greater than |
int1 が int2 より大きい |
int1 -ge int2 |
greater than or equal |
int1 が int2 以上 |
ファイル関係のテスト
式 | 説明 |
---|---|
-f file |
file が通常ファイルか |
-d file |
file がディレクトリか |
-e file |
file が何かしらの形で存在するか |
-r file |
file が読み取り可能か |
-w file |
file が書き込み可能か |
-x file |
file が実行可能か |
-s file |
file のサイズが 0 以上か |
-O file |
file の所有者がログイン中のユーザーであるか |
file1 -nt file2 |
file1 が file2 より新しいか |
file1 -ot file2 |
file1 が file2 より古いか |
文字列のテスト
式 | 説明 |
---|---|
string |
string が null でないか |
-z string |
string の長さが 0 バイトか |
-n string |
string の長さが 0 でないか |
str1 -n str2 |
str1 と str2 が等価 |
str1 = str2 |
str1 と str2 が等しい |
str1 != str2 |
str1 と str2 が等しくない |

[[
を使った高度なテスト
test
コマンドは [
を使うことで省略することができる。一方で [[
を使うと、より高度な条件でテストをすることができる。
空白文字と論理演算子
二重角括弧では、空白文字の問題を軽減してくれる。また、-a
や -o
でなく &&
, ||
の論理演算子も利用可能。
FILE="./my file.txt" # 空白文字が使われているファイル
# 変数を展開すると、空白文字によって別々の引数と認識されてしまう
[ -f $FILE -a -r $FILE ] && cat $FILE
# -> bash: [: too many arguments
# 引用符で囲むことで、単一の引数として扱える
[ -f "$FILE" -a -r "$FILE" ] && cat "$FILE"
# 二重角括弧を使う別解、引用符を省略し論理演算子を使用
#(※ cat 側には引用符が必要)
[[ -f $FILE -a -r $FILE ]] && cat "$FILE"
パターンマッチングと正規表現
単純な文字列のマッチングだけでなく、パターンを使ったマッチングも可能になる。
[[ $FILE = *.txt ]] && ls "$FILE"
# 正規表現を使った場合
[[ $FILE =~ \.txt$ ]] && ls "$FILE"
上記の例のように、正規表現を使いたい場合にも二重角括弧は利用される。
# 正規表現 `u?` により、u を省略可能に
if [[ $REPLY =~ colou?r ]] ; then

((
を使った算術演算
bash 等では算術演算をする場合、組み込みコマンド let
が使える。その他にも二重丸括弧を使うことで算術展開が可能である。
(※ ただしパラメータ名を二重丸括弧の外で指定する場合は、$
が必要となる)
let a=2+3
(( a = 2 + 3 ))
a=$(( 2 + 3 ))
また、++
や --
といったインクリメント(デクリメント)演算子も利用可能
COUNT=0
(( COUNT++ ))
echo $COUNT # -> 1
そして二重丸括弧では算術テストにも使うことができる。
SCORE=100
(( SCORE > 70 )) && echo "Congratulations, you passed!"

IFS
:内部フィールドセパレータ
IFS
(Internal Field Separator) はフィールドを区切るための文字を扱う変数であり、デフォルトではスペース、タブ、改行の文字が設定されている。
パラメータ展開, コマンド置換, 算術展開の後、シェルは二重引用符内で発生しなかった展開および置換の結果をフィールド分割のために走査し、その際 複数のフィールドが生成される場合がある。
IFS
は区切りとして使う文字を扱っており、これを弄ることで処理内容を制御することができる。
# カレントディレクトリにサンプルテキストのファイルを生成
cat <<EOF > ./sample.txt
line1 test
line2 sample
line3
EOF
FILE=./sample
# 想定:ファイル内のテキストを、各行単位で出力したい
for var in $(cat $FILE)
do
echo "$var"
done
ユーザー側としては「各行ごとに内容を出力する」のを期待しているが、IFS
が空白, タブ, 改行文字のため、結果は下記のようになる。
line1
test
line2
sample
line3
IFS
を調整することで、想定通りの処理にできる。
FILE=./sample.txt
# IFS を改行のみに更新(+もとに戻す用にデフォルト値を退避)
defaultIFS=$IFS
IFS=$'\n'
for var in $(cat $FILE)
do
echo "$var"
done
# 結果は下記となり、ユーザーの想定と一致する。
# line1 test
# line2 sample
# line3
# 処理後はデフォルト設定に戻しておく
IFS=$defaultIFS