13
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Bashで引数で使うワイルドカード展開を抑制する

Last updated at Posted at 2017-08-25

シェルスクリプトで aws の s3 sync について --exclude にワイルドカードを指定するのに、うまく指定できなくて調べた結果をまとめておく。ちゃんと指定しないとクオートやエスケープの文字自体も受け渡されてしまって --exclude が意図したとおりに指定できなかった。

直接使う場合

Bashでワイルドカード展開を抑制する方法はいくつかあります。

bash - Stop shell wildcard character expansion? - Stack Overflow より

$ # quote it
$ foo '*'

$ # or escape it
$ foo \*

$ # or disable the glob (noglob)
$ set -f
$ foo *

変数で使う場合

変数にワイルドカード文字を代入すると、とたんに難しくなります。

文字列だけ

sh での変数とワイルドカードの落とし穴|てくめも@ecoop.net

のように、"$A" でダブルクオートで括れば展開されないが、空白で区切られた複数のオプションを含む場合にコマンド引数で使用しようとすると不具合が出る。空白も含めて1つの文字列として受け渡されてしまいます。

引数で使う場合

今のところ、以下の2つで解決できるようです。

  • eval を使う
  • set -f を使う

eval を使う

aws s3 syncするシェルスクリプトでワイルドカードでexcludeしたときのメモ

実験

環境

$ ll
合計 1024
-rw-r--r--+ 1 xxx Users   0 8月  24 18:27 1.txt
-rw-r--r--+ 1 xxx Users   0 8月  24 18:27 2.txt
-rw-r--r--+ 1 xxx Users   0 8月  24 18:27 3.txt
-rwxr-xr-x+ 1 xxx Users 269 8月  24 19:10 sample.sh*
sample.sh
#!/bin/bash

subject1="--exclude '*' --include '*.txt'"
subject2="--exclude * --include *.txt"
subject3='--exclude \* --include \*.txt'

set -x
#
:
echo ${subject1}
:
echo "${subject2}"
:
eval "echo ${subject1}"
:
set -f
echo ${subject2}
set +f
:
echo ${subject3}
:
#

結果

ワイルドカード文字が * だけになっていると良い。

$ ./sample.sh
+ :
+ echo --exclude ''\''*'\''' --include ''\''*.txt'\'''
--exclude '*' --include '*.txt'
+ :
+ echo '--exclude * --include *.txt'
--exclude * --include *.txt
+ :
+ eval 'echo --exclude '\''*'\'' --include '\''*.txt'\'''
++ echo --exclude '*' --include '*.txt'
--exclude * --include *.txt
+ :
+ set -f
+ echo --exclude '*' --include '*.txt'
--exclude * --include *.txt
+ set +f
+ :
+ echo --exclude '\*' --include '\*.txt'
--exclude \* --include \*.txt
+ :

1番目は、展開後なのに引数の文字列としてシングルクオートが含まれてしまっている。
2番目は、一見うまく展開されているようだけど、'--exclude * --include *.txt'と1つの文字列としてシングルクオートで括られている。
3番目は、OK。
4番目は、OK。
5番目は、エスケープ文字が含まれているので駄目。

13
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?