zip の -x exclude オプションが実際にパスを除外しないのはなぜでしょうか?

zip の -x exclude オプションが実際にパスを除外しないのはなぜでしょうか?

Raspberry Pi で Raspbian を使用して、/etc ファイルをバックアップしたいのですが、すべてではありません。/etc/alternatives を除外したいので、次のコマンドを使用しました。

sudo zip -r /home/pi/backup/$timestamp/etcfilesall.zip /etc/* –x /etc/alternatives/*

なぜこれが機能しないのでしょうか? /etc 内の他のすべてのフォルダーと同様に、/etc/alternatives の内容が含められます。

これらのバリエーションを試してみましたが、どちらもうまくいきませんでした

sudo zip -r –x /etc/alternatives/* @ /home/pi/backup/$timestamp/etcfilesall.zip /etc/*
sudo zip -r /home/pi/backup/$timestamp/etcfilesall.zip /etc/* –x /etc/alternatives
sudo zip -r /home/pi/backup/$timestamp/etcfilesall.zip /etc/* –x '/etc/alternatives'
sudo zip -r /home/pi/backup/$timestamp/etcfilesall.zip /etc/* –x '/etc/alternatives/*'

再帰の -r オプションの下で、zip -h2 ヘルプには「パスを含めるか除外するかを指定するには、-i と -x を使用します」と記載されているため、私がやろうとしていることはサポートされているようです。

答え1

問題は、OP の質問では、「x」の前の「-」(オプション「-x」)が実際には ASCII マイナス記号ではないことです。代わりに、これは Unicode u+2013 です(見た目は同じですが、動作は同じではありません)。

コマンドが期待どおりに入力されると、OP の最後の例 (ここで修正) では期待どおりに動作します。

sudo zip -r /home/pi/backup/$timestamp/etcfilesall.zip /etc/* -x '/etc/alternatives/*'

これはおそらく、何らかの Web サイトからの切り取り/貼り付けによって生じた問題です。

参考文献:

答え2

ページからman zip:

zip -r foo foo -x \*.o

これにより、foo のコンテンツが foo.zip に含まれますが、.o で終わるすべてのファイルは除外されます。バックスラッシュによりシェルのファイル名の置換が回避されるため、zip によってすべてのディレクトリ レベルで名前のマッチングが実行されます。

*globがシェルではなくユーティリティ自体によって展開されていることを確認する必要がありますzip。そうしないと、/etc/alternatives ディレクトリ内のファイルに直接影響し、サブディレクトリは対象になりません。これは、前にバックスラッシュを追加する*か、引用符で囲むことで実行できます。

sudo zip -r /home/pi/backup/$timestamp/etcfilesall.zip /etc/* –x /etc/alternatives/\*

ただし、すでに同様の方法を試したようですが、なぜうまくいかなかったのかはわかりません。ただし、zipユーティリティを呼び出す前に、追加のツールを使用して不要なファイルを除外するなど、同様の効果を得る方法は他にもあります。

sudo zip -r /home/pi/backup/$timestamp/etcfilesall.zip $(sudo find /etc | grep -v ^/etc/alternatives)

関連情報