次のコマンドを実行すると、Fedora 31とDebian 10は異なる動作をします。
/bin/ls /bin/!(znew) | /bin/grep znew
Fedoraは何も印刷しませんが、Debianは以下を印刷します。
znew
znew
Fedoraに存在します。実行すると、次のように/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つに名前が含まれている場合、その名前は一致して出力されます。/bin
znew
ls
-d
ls
znew
grep
不明なサブディレクトリの内容は、名前の前にディレクトリパスを追加せずに一覧/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
(現在のディレクトリ)へのシンボリックリンクであることがわかりました。.
これはznew
pathnameを介してアクセスできることを意味します/bin/X11/znew
。
だからまとめると、/bin/!(znew)
ワイルドカードパターンはパス名のリストに展開されますが、そのうちの1つはです/bin/X11
(しかし/bin/znew
)その後、ユーティリティはパラメータをls
含むすべてのパス名を取得します。リストを/bin/X11
取得するとls
、ディレクトリの内容がそこを指すのでリストされます/bin/X11
。その後、ユーティリティはそれを選択して出力の一部になります。/bin
/bin/X11
grep
znew
ls
主演スティーブン・チャジェラスコメントとして指摘する/bin
、名前に改行文字と文字列(おそらく他の改行文字と他の文字が続く可能性がある)を含むファイルがDebianシステムにある場合は、znew
同じ効果が得られます。
名前は正確に文字列ではないため、パターンと一致し、znew
その/bin/!(znew)
単一ls
の名前を次のように出力します。
/bin/something
znew
maybe more
その出力から抽出されますgrep
。znew