extglobはFedoraとDebian bashで異なる動作をします。

extglobはFedoraとDebian bashで異なる動作をします。

次のコマンドを実行すると、Fedora 31とDebian 10は異なる動作をします。

/bin/ls /bin/!(znew) | /bin/grep znew

Fedoraは何も印刷しませんが、Debianは以下を印刷します。

znew

znewFedoraに存在します。実行すると、次のように/bin/ls /bin/znew | /bin/grep znewなります。

/bin/znew

(Debianでも同じことが起こります)

両方のディストリビューションでbash設定を確認しましたが、私が見つけた唯一の違いは、Fedoraで次のようなことです。

cdable_vars     on
cdspell         on
dirspell        on
login_shell     on

Debian では、これらのオプションは無効になっています。extglob両方のディストリビューションで有効

注:コマンドはgrepリストを短くするためにここでのみ使用されます。

バージョン:

  • Fedora: 5.0.11

  • Debian: 5.0-4

なぜそのような違いがありますか?

アップデート1

/ binは、DebianとFedoraの/ usr / binへのシンボリックリンクです。

以下は、ファイル名から znew 文字列を検索した結果です。

updatedb && locate  znew
/usr/bin/znew
/usr/share/man/man1/znew.1.gz
/var/lib/flatpak/runtime/org.freedesktop.Platform/x86_64/19.08/5a35247ad1c941455f2f9c4139d9136c6c0662e1b04e5b3c56121e7f67ba0100/files/bin/znew
/var/lib/lxc/centos/rootfs/usr/bin/znew
/var/lib/lxc/centos/rootfs/usr/share/man/man1/znew.1.gz
/var/lib/lxc/opensuse/rootfs/usr/bin/xznew
/var/lib/lxc/opensuse/rootfs/usr/bin/znew
/var/lib/lxc/opensuse/rootfs/usr/share/man/man1/xznew.1.gz
/var/lib/lxc/opensuse/rootfs/usr/share/man/man1/znew.1.gz

アップデート2

私が見つけた興味深いのは、Debianに/bin/X11へのシンボリックリンクがあり、.削除するとFedoraと同じように動作することです。

答え1

シェルオプションがextglob対話型セッションで設定されていると仮定すると、次のコマンドはbash

ls /bin/!(znew) | grep znew

Firstは引数ではなくlsすべての名前を使用して実行されます。この名前リストにサブディレクトリの名前が含まれている場合、そのサブディレクトリの内容が出力されます(一緒に使用されないため)。これらのサブディレクトリの1つに名前が含まれている場合、その名前は一致して出力されます。/binznewls-dlsznewgrep

不明なサブディレクトリの内容は、名前の前にディレクトリパスを追加せずに一覧/bin表示されます。lsしたがって、サブディレクトリに名前が含まれている場合は、asではなくasとしてznew出力されます。znew/bin/some-dir/znew

lsたとえば、いつ使用しますか?

ls /bin/znew | grep znew

/bin/znew代わりに文字列を出力しますznew(パス名が存在する場合)。これは、引数として指定されたディレクトリの内容ではなく、コマンドライン引数として指定されたファイルの特定のパス名を出力するためです。

/usr/bin呼び出されたアイテムがすでにシンボリックリンクで/binある間に誰かがシンボリックリンクを作成しようとした場合、またはそのアイテムがまだディレクトリである場合、同様の状況が発生する可能性があります。/bin/usr/bin/bin

質問の更新では、これが/bin/X11(現在のディレクトリ)へのシンボリックリンクであることがわかりました。.これはznewpathnameを介してアクセスできることを意味します/bin/X11/znew

だからまとめると/bin/!(znew)ワイルドカードパターンはパス名のリストに展開されますが、そのうちの1つはです/bin/X11(しかし/bin/znew)その後、ユーティリティはパラメータをls含むすべてのパス名を取得します。リストを/bin/X11取得するとls、ディレクトリの内容がそこを指すのでリストされます/bin/X11。その後、ユーティリティはそれを選択して出力の一部になります。/bin/bin/X11grepznewls


主演スティーブン・チャジェラスコメントとして指摘する/bin、名前に改行文字と文字列(おそらく他の改行文字と他の文字が続く可能性がある)を含むファイルがDebianシステムにある場合は、znew同じ効果が得られます。

名前は正確に文字列ではないため、パターンと一致し、znewその/bin/!(znew)単一lsの名前を次のように出力します。

/bin/something
znew
maybe more

その出力から抽出されますgrepznew

関連情報