web-dev-qa-db-ja.com

コマンド出力を他のコマンドに渡す方法

例:

ls | echoは何も表示しません(実際には空白行)。私はそれがファイルのリストを印刷することを期待するでしょう。

一方、ls | grep 'foo'は期待通りに動作します(名前に 'foo'を含むファイルを表示します)。

このような状況で私がすることは、ls | while read OUT; do echo $OUT; doneのようなものですが、これはかなり面倒です。

なぜ配管は他のコマンドではなくいくつかのコマンドで動作しますか?どうすればこの問題を回避できますか?

81
Mihai Rotaru

コマンドライン引数と標準入力には違いがあります。パイプはあるプロセスの標準出力を別のプロセスの標準入力に接続します。そう

ls | echo

Lsの標準出力をechoの標準入力に接続します。いいですか?そう、echoは標準入力を無視し、そのコマンドライン引数をダンプします - この場合はなにもしません - それ自身の標準出力。出力:まったく何もありません。

この場合、いくつか解決策があります。 1つは、catのように、標準入力を読み、標準出力にダンプするコマンドを使用することです。

ls | cat

あなたの仕事の定義が何であるかに応じて、「働きます」。

しかし、一般的な場合はどうでしょうか。あなたが本当に欲しいのは、あるコマンドの標準出力を別のコマンドライン引数に変換することです。他の人が言っているように、このケースではxargsが標準的なヘルパーツールです。その標準入力からコマンドの引数を読み、実行するコマンドを構築します。

ls | xargs echo

置換コマンド$()を使ってこれを変換することもできます

echo $(ls)

また、あなたが望むことをするでしょう。

これらのツールはどちらもシェルスクリプティングの中核をなすものです。両方を学ぶ必要があります。

完全性のために、あなたが問題で示すように、標準入力をコマンドライン引数に変換するためのもう一つの基本的な方法はシェルの組み込みのreadコマンドです。 「単語」(IFS変数で定義されている単語)を一時変数に変換します。この変数は、どのコマンド実行でも使用できます。

115
Rich Homolka

echoは入力を読み取らないため、ls | echoは空白行のみを出力します。パイプラインの最後のコマンドは、実際には空行以外の何も表示しないechoです。

一般に

a | b

aの出力がbの入力になるようにします。 man bashPipelinesセクションを読むことをお勧めします。


lsechoを一緒に使いたいのなら、ここでいくつかの(かなり役に立たない)例を挙げます。

ls | xargs -L 1 echo
echo `ls`
for i in `ls` ; do echo $i ; done
18
cYrus

echoを使いたい場合はlsコマンドを試してください。

ls | xargs echo

これはechoの出力でlsを呼び出します。

10
Nathan Fellman

単に使用しないのはなぜですか。

echo `ls`

もっと安全です。

echo "`ls -lrt`"
3
Urbwzrd