GNU/Linux >> Linux の 問題 >  >> Linux

Nullglobがデフォルトではないのはなぜですか?

ほとんどのシェルではnullglob デフォルトではありません。つまり、たとえば、このコマンドを実行した場合

ls *

空のディレクトリでは、 *が展開されます リテラル*へのグロブ 、代わりに引数の空のリストに。 * となるように、その動作を変更する方法があります。 空のディレクトリにあると、引数の空のリストが返されます。これは、より直感的に見えるでしょう。

それで、 nullglobが理由があります デフォルトでは無効になっていますか?もしそうなら、その理由は何ですか?

承認された回答:

nullglob オプション(ところで、これは zsh 発明、数年後に bashに追加されました ( 2.0 ))多くの場合、理想的ではありません。そしてls 良い例です:

ls *.txt

または、より正確な同等物:

ls -- *.txt

nullglobを使用 onはlsを実行します ls-。として扱われる引数なし (現在のディレクトリをリストします)一致するファイルがない場合、これはおそらく lsを呼び出すよりも悪いです リテラルの*。txtを使用 引数として。

ほとんどのテキストユーティリティでも同様の問題が発生します:

grep foo *.txt

fooを探します txtがない場合はstdinに ファイル。

より賢明なデフォルトであり、csh、tcsh、zsh、またはfish 2.3以降(および初期のUnixシェル)の1つは、globが一致しない場合にコマンドを完全にキャンセルすることです。

bash (バージョン3以降)には failglobがあります そのためのオプション( ash とは対照的に、この議論に興味があります 、AT&T ksh またはzsh bash オプションのローカルスコープをサポートしていません(ただし、4.4で変更されます)。グローバルに有効にすると、そのオプションはbash-completion関数などのいくつかの機能を壊します。

cshとtcshはzshとは少し異なることに注意してください 、 fish またはbash-O failglob 次のような場合:

ls -- *.txt *.html

コマンドをキャンセルするために、すべてのグロブを一致させないようにする必要がある場合。たとえば、txtファイルが1つあり、htmlファイルがない場合、次のようになります。

ls -- file.txt

zshでその動作を得ることができます setopt cshnullglobを使用 zshでそれを行うためのより賢明な方法ですが 次のようなグロブを使用することになります:

ls -- *.(txt|html)

zshで およびksh93 nullglobを適用することもできます グロブごとに、これはグローバル設定を変更するよりもはるかに賢明なアプローチです:

files=(*.txt(N))  # zsh
files=(~(N)*.txt) # ksh93

txt がない場合は、空の配列が作成されます コマンドをエラーで失敗させる(または1つの*。txtを含む配列にする)代わりにファイル 他のシェルとのリテラル引数)。

fishのバージョン 2.3より前のバージョンはbash-O nullglobのように機能します ただし、グロブに一致するものがない場合、インタラクティブのときに警告を出します。 2.3以降、 zshのように機能します forで使用されるグロブを除く 、 set またはcount

さて、履歴ノートでは、動作は実際には壊れていました ボーンシェルによって。 Unixの以前のバージョンでは、グロブは / etc / globを介して行われました。 ヘルパーとそのヘルパーはcshのように動作しました :どのグロブもどのファイルにも一致しない場合はコマンドに失敗し、それ以外の場合は一致しないグロブを削除します。

関連:Bash +セカンダリスクリプトとメインスクリプトの両方を終了する方法は?

したがって、今日の状況は、Bourneシェルで行われた誤った決定によるものです。

Bourneシェル(およびCシェル)には、別の新しいUnix機能である環境が付属していることに注意してください。これは可変拡張を意味しました(前任者には $ 1しかありませんでした 、 $ 2 …位置パラメータ)。 Bourneシェルもコマンド置換を導入しました。

Bourneシェルのもう1つの不十分な設計上の決定は、変数の展開とコマンド置換の際にグロブ(および分割)を実行することでした(おそらく、 echo $ 1であるThompsonシェルとの下位互換性のためです。 それでも/etc / globを呼び出します $ 1の場合 ワイルドカードが含まれていました(展開された値がシェルコードとして再度解析されたため、プリプロセッサマクロの展開に似ていました)。

一致しないグロブが失敗すると、たとえば次のようになります。

pattern='a.*b'
grep $pattern file

コマンドが失敗します( a.whateverbがない場合 現在のディレクトリ内のファイル)。 csh (変数の展開時にグロビングも実行します)その場合、コマンドは失敗します( zsh <のようにグロビングをまったく行わないほど良くない場合でも、休止状態のバグを残すよりはましだと思います。 / code> 。


Linux
  1. Linux –なぜSuだけでなくSuを使用するのですか?

  2. デフォルトのプロセス作成メカニズムフォークはなぜですか?

  3. Linux –Setuidが機能しないのはなぜですか??

  1. Linux で SOCK_SEQPACKET の MSG_EOR が表示されないのはなぜですか?

  2. file_put_contentsがtxtファイルを作成していません

  3. user-data (cloud-init) スクリプトが EC2 で実行されない

  1. sftp rmdir が機能しないのはなぜですか?

  2. Fedora 25 はデフォルトでウェイランドを使用していません!

  3. bash履歴を削除するだけでは不十分なのはなぜですか?