file $(ls /usr/bin/* | grep zip) コマンドを実行するとエラーが発生します。何が問題なの?

file $(ls /usr/bin/* | grep zip) コマンドを実行するとエラーが発生します。何が問題なの?

私はLinux / Unixに関する本を読むことにしました。私はコマンドの出力を拡張としてシェルにパイプする方法を説明する章を読んだ。

次のコマンド

file $(ls /usr/bin/* | grep zip)

代わりに、「ファイル名(ファイルやディレクトリなし)を開くことができません」というエラーが表示されます。

file $(ls | grep zip)

フォルダに関係なく、すべてが正常に表示されます。なぜ?これは一種の議論の制限ですか?

もし私がするなら

file $(ls Pictures/ | grep jpg)

次のメッセージが表示されます。

1234.jpg: ERROR: cannot open 1234.jpg (No such file or directory)

リストしたいディレクトリに直接移動するとき

nassosdim@ubuntu:~$ cd Pictures/

nassosdim@ubuntu:~/Pictures$ file $(ls | grep jpg)

ファイルの結果を印刷

1234.jpg: JPEG image data, JFIF standard 1.01

誰かが私に何が起こっているのかを説明できますか? :(

答え1

このエラーは、bashが*globパターンマッチングを使用して引数をlsに拡張しようとするために発生します。 globがパターンと一致しない場合、常にこのようなエラーが発生します。その後、実際のアスタリスクに*渡されます。lsこれはファイルとも一致しないため、lsエラーが発生します!

現在実行中の作業について重複するいくつかの点があります。あなたが構造を学びようとしていることを知っていますが、あなたが達成したものとそれを達成した方法を分析しましょう。

  1. ls /usr/binbinディレクトリにあるファイルをリストするだけで十分です。アスタリスクはまったく必要ありません。
  2. 君は絶対にならない出力の解析lsそれにもかかわらず、これはあいまいで潜在的に危険です。
  3. 次のようにしてgrepなしで同じ効果を得ることができますが、ls /usr/bin/*zip*これはlsまだ重複しているため、glob拡張をファイルに渡すことができます。file /usr/bin/*zip*

最後に、findファイルを見つけるためのより良いツールがあることがよくあります。次のようにしたいことができます。

$ find /usr/bin -iname '*zip*' -exec file {} +

答え2

*シェルはコマンドを拡張してに変換しますfile $(ls /usr/bin/a /usr/bin/b /usr/bin/whatever | grep zip)。シェルがアスタリスクをとして渡すことを望まない限り、UNIXではアスタリスクを指定する必要はありませんls

つまり、シェルは*を一致する各ファイルに置き換えます。今後コマンドを実行しますが、これが慣れている場合はWindowsで動作する方法ではありません。

ここでセクション3.4.9を読んでください。

file $(ls /usr/bin/ | grep zip) 

*は必要ありませんが、他の質問やオプションについては、Calebの答えを参照するという意味で正しいアプローチです。しかし、実際に実行されるのは

file /usr/bin/a /usr/bin/b /usr/bin/whatever

いいえ

file /usr/bin/a
file /usr/bin/b
file /usr/bin/whatever

繰り返しますが、Windowsとは異なり、これを行います。

答え3

ls /usr/bin/* | grep zipあなたが提供する引数をチェックしてくださいfile。結果が少し混乱ですね。私のUbuntuシステムでは、結果は次のとおりです。

/usr/bin/funzip
/usr/bin/gpg-zip
/usr/bin/mzip
/usr/bin/preunzip
/usr/bin/prezip
/usr/bin/prezip-bin
/usr/bin/unzip
/usr/bin/unzipsfx
/usr/bin/zip
/usr/bin/zipcloak
/usr/bin/zipgrep
/usr/bin/zipinfo
/usr/bin/zipnote
/usr/bin/zipsplit
funzip
gpg-zip
mzip
preunzip
prezip
prezip-bin
unzip
unzipsfx
zip
zipcloak
zipgrep
zipinfo
zipnote
zipsplit

これを使用すると、ls /usr/bin/* | lessこの結果が出てくる理由がわかります。 /usr/bin のすべてのファイルの後に、ls/usr/bin/X11 ディレクトリの内容もリストされ、ディレクトリ名の前に追加せずにリストされます。

ディレクトリ名なしでこれらのファイル名を指定すると、ファイルが見つからず、filefile該当するファイルまたはディレクトリがありません」というエラーメッセージが表示されます。 (注:エラーメッセージが表示されたら、「エラーが発生しました」とだけ言わないでください。「しかしエラーメッセージを投稿します)。

Calebがすでに投稿したようにfile /usr/bin/*zip*

答え4

ls出力形式が異なるため、結果を解析するのは危険な作業になる可能性があります。次のようにする方が良いでしょう。

file /path/to/*.zip

プロセスの交換がどのように機能するかを示すために、より簡単なコマンドを試してください。

ls $(echo /usr/bin) 

関連情報