TL;DR
- alpine の
readlink -f
は挙動の差があり、絶対パスが取れないケースがある - alpine がベースイメージの docker コンテナでシェルスクリプトを動かすときは、思わぬ罠にはまる場合があるので注意しよう
通常の readlink -f の挙動
readlink -f <PATH>
で相対パス PATH を絶対パスに変換できます。
$ readlink -f .bashrc
/home/nakatt/.bashrc
Ubuntu や CentOS などの通常の readlink では、パスの最後の要素だけは存在しなくてもかまいません。(man readlink の -f オプションの説明にそう書かれています。)
$ readlink -f no_exist_file # 存在しないファイル名
/home/nakatt/no_exist_file
alpine の readlink -f の挙動
alpine では、readlink -f に存在しないパスを渡すと空文字が返る場合があります。
/ # readlink -f no_exist_file # 存在しないファイル名
/ # 何も出力されない!
私の場合、シェルスクリプトの中で real_path=$(readlink -f $path)
としていたので変数が空になって罠にはまりました。
alpine の readlink は GNU coreutils ではなく busybox を使っているので、必ずしも細かい仕様は一致しないようです。
$ readlink
BusyBox v1.30.1 (2019-06-12 17:51:55 UTC) multi-call binary.
Usage: readlink [-fnv] FILE
Display the value of a symlink
-f Canonicalize by following all symlinks
-n Don't add newline
-v Verbose
docker で何かを動かす場合は軽量な alpine を使うことが多いですが、それなり以上の規模のシェルスクリプトを docker で運用したい場合は、ベースイメージに alpine を使うのは避けたほうが良いかもしれません。