概要
自動化の際に知っておくと幸せになれるメモ
前提
- bash (GNU bash, version 5.0.3(1)-release)
- apt (1.8.2 (amd64))
基本形
# /usr/bin/env bash
set -eu # エラーキャッチと未定義変数を禁止
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")"&>/dev/null&&pwd)" # ついでに書いときました。スクリプトのディレクトリ
export DEBIAN_FRONTEND=noninteractive # 対話promptを開かない設定
apt-get update >/dev/null || exit 1
apt-get upgrade -qq -y >/dev/null || exit 2 # upgradeの出力も完全に消せます
apt-get install -y vim >/dev/null || exit 3
(curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg|sudo apt-key add -) >/dev/null || exit 4 # 複数コマンドの結果を>/dev/nullしたい場合はカッコで囲みます。囲まないと色々困ります。
各コマンドは基本的に失敗しないはずで、仮に失敗した場合、作成者に相談が来ると思います。
なので経験上&>/dev/null
とか>/dev/null 2>&1
のようなエラー出力まで捨てる行為はしない方が良さそうです。
export DEBIAN_FRONTEND=noninteractive
について
選択肢を明示したい場合はdebconf-set-selections
を使うとよいです。
例えばiptables-persistent
ではこんな感じです。
echo "iptables-persistent iptables-persistent/autosave_v4 boolean true"|debconf-set-selections
echo "iptables-persistent iptables-persistent/autosave_v6 boolean true"|debconf-set-selections
apt-get install -y iptables-persistent
DEBIAN_FRONTENDのsource: https://manpages.debian.org/buster/debconf-doc/debconf.7.en.html
ifの省略について
ifは省略できますが、しないほうが良さそうです。例えば次の式は同等に見えますが、
if [ -f "${TARGET_FILE}" ];then
echo "ls do EXISTS!"
fi
[ -f "${TARGET_FILE}" ] && echo "ls do EXISTS!"
下の方は、評価の失敗時に終了コードが0以外で返ります。
後ろに||
で繋げられることを考えれば当然なのですが、残念ながらset -e
にキャッチされません。
関数内に書いてたりすると悲しいことになります。
また、if 文の条件式下ではset -e
にキャッチされません。
Warning: apt-key output should not be parsed (stdout is not a terminal)
curl "${gpg_key_server}"|apt-key add -
とかすると発生します。
export APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=1
値は1でなくても何でも良いです。dockerfileとかだとDontWarnにしてる例が多いです。
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
apt update|grep 'Hit'
とかaptの結果をパイプすると発生します。
apt-get, apt-cache
とかを使いましょう。
aptは「綺麗に出力してくれるとかの気遣いがあるので出力内容は保証しない」とのことです。