Symfony6で突然zipコマンドが動かなくなった問題
Symfony3.4では動いてたんや
Symfony\Processを用いて、複数ファイルをワイルドカード(*)を使用して
1つのZIPファイルにまとめるコマンドを実行していました。
Processクラスに渡したコマンドは以下の通りです
new Process(['zip', '-jrq', '-P', 'password', 'path/to/test.zip', 'path/to/test*.csv']);
# コマンド実行前
path
└── to
├── test_1.csv
├── test_2.csv
└── test_3.csv
# コマンド実行後
path
└── to
├── test_1.csv
├── test_2.csv
├── test_3.csv
└── test.zip # test_1.csv, test_2.csv, test_3.csvが全て入っている
このコマンドをSymfony3.4で実行すると、問題なく動作します。
なぜかSymfony6では動かない...
しかし、Symfony6でそのコマンドを走らせると下記のようなエラーが出るようになりました。
もちろんZIPファイルも作成されていません。
zip error: Notiong to do ! (try: zip -jrq -P password /path/to/test.zip . -i /path/to/test*.csv)
zip -jrq -P password /path/to/test.zip . -i /path/to/test*.csv
を
代わりに試してくれよなと言われてしまいました。
原因
Symfonyのgithub discussionにて、このエラーの原因について教えていただきました。
エラーの原因は、Processクラスのコンストラクタに渡されたコマンドの取り扱い方法が
Symfony3.4と6で変わっていたことでした。
その変更に伴い、圧縮対象のファイル名に含まれているワイルドカード(*)の解釈の仕方も変わりました。
-
Symfony3.4
- コンストラクタに渡されたコマンドは一度シェルでプリプロセッシングされてから実行される
- ワイルドカード(*)は、globとして扱われる
-
test_1.csv
test_2.csv
test_3.csv
が圧縮対象のファイルになる
-
Symfony6
- コンストラクタに渡されたコマンドはシェルでラップされることなく直接実行される
- ワイルドカード(*)は、そのまま文字列として扱われる
-
test*.csv
というファイル名は存在しないのでエラーが出る
解決策
解決策は、エラーメッセージが既に教えてくれていました。
(try: zip -jrq -P password /path/to/test.zip . -i /path/to/test*.csv)
これをそのままProcessクラスのコンストラクタに渡せば無事実行することができました。
-i
オプションを用いることで、ワイルドカード(*)をglobとして認識させることができるようです。
new Process(['zip', '-jrq', '-P', 'password', 'path/to/test.zip', '.', '-i' ,'path/to/test*.csv']);
後書き
普段はLaravelばかり触っており、Symfonyやシェルについてはまだまだ勉強中です。
もし、間違っているところなどありましたらコメント欄にて教えていただけると幸いです。
シェルのプリプロセッシングって厳密には何しているんでしょうか・・・?
詳しい方教えてください。
最後まで読んでいただきありがとうございました。
Author And Source
この問題について(Symfony6で突然zipコマンドが動かなくなった問題), 我々は、より多くの情報をここで見つけました https://qiita.com/wadakatu/items/c90dec005d0d670d2302著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .