🌟

bashでワイルドカードを展開させたりさせなかったりする

2022/12/06に公開約1,100字

ワイルドカードを受け付けるオプションとファイルを受け付けるオプションが混在してるコマンドがあるとします。
こういうときに展開させるかどうかって結構困ります。

GitHub Actions だと改行区切りで入力したかったりするのでさらに扱いに困ってしまいます。

「改行は引数を区切りとして判定して欲しいがワイルドカードを展開してほしいかは場合による」みたいな状況になってしまいました。

echo/action.yml
inputs:
  glob:
    description: glob を展開したくない
    required: true
    default: |
      **
      .*
  files:
    description: glob を展開したい
    required: true
    default: |
      .github/workflows/*
      .*

結論

set -f を使う!

bash では set -f でワイルドカード展開を無効、set +f で有効化してくれます。

# ワイルドカードを展開せずに glob パターンとして渡したい
GLOB="a*
b0*"

# ワイルドカードを展開してファイルのリストとして渡したい
FILES="a*
b0*"

touch a00 a01 a10
touch b00 b01 b10
touch c00 c01 c10
echo "import sys
print(sys.argv)" > echo.py

python echo.py -g $GLOB -f $FILES
# ['echo.py', '-g', 'a00', 'a01', 'a10', 'b00', 'b01', '-f', 'a00', 'a01', 'a10', 'b00', 'b01']
# クォートなしだと展開されてしまう


python echo.py -g "$GLOB" -f "$FILES"
# ['echo.py', '-g', 'a*\nb0*', '-f', 'a*\nb0*']
# クォートありだと一つの引数として扱われてしまう

set -f
python echo.py -g $GLOB -f $(set +f && echo $FILES)
# ['echo.py', '-g', 'a*', 'b0*', '-f', 'a00', 'a01', 'a10', 'b00', 'b01']
# set -f のあとにクォートなし展開されない!
# 展開したい方はサブシェルで set +f したらOK

Discussion

ログインするとコメントできます