コマンドラインでパイプの概念を学ぶのを手伝っている場合、どのような例を使用しますか?実際に思いついた例は次のとおりです。
cat whatever.txt | less
それは最良の例ではない、つまり1つのステップしかないためです。 |
の優れた、しかし根本的な用途は何ですか?
理想的には、これから紹介する例では、独立して実行でき、パイプで一緒に表示できる出力自体を備えたプログラムを使用します。
実際のシナリオに基づいて、少し複雑な例を紹介します。
問題
コマンドconky
がデスクトップで応答を停止し、手動で終了したいとします。 Unixを少し知っているので、kill <PID>
コマンドを実行する必要があることはわかっています。 PIDを取得するために、ps
またはtop
、またはUnixディストリビューションから提供されたツールを使用できます。しかし、これを1つのコマンドでどのように実行できますか?
回答
$ ps aux | grep conky | grep -v grep | awk '{print $2}' | xargs kill
免責事項:このコマンドは特定の場合にのみ機能します。端末にコピー/貼り付けして使用を開始しないでください。疑いもなくプロセスが強制終了される可能性があります。むしろ学ぶそれを構築する方法。
仕組み
1- ps aux
このコマンドは、実行中のプロセスのリストとそれらに関するいくつかの情報を出力します。興味深い情報は、2列目に各プロセスのPIDを出力することです。これは私のボックスのコマンドの出力からの抜粋です:
$ ps aux
rahmu 1925 0.0 0.1 129328 6112 ? S 11:55 0:06 tint2
rahmu 1931 0.0 0.3 154992 12108 ? S 11:55 0:00 volumeicon
rahmu 1933 0.1 0.2 134716 9460 ? S 11:55 0:24 parcellite
rahmu 1940 0.0 0.0 30416 3008 ? S 11:55 0:10 xcompmgr -cC -t-5 -l-5 -r4.2 -o.55 -D6
rahmu 1941 0.0 0.2 160336 8928 ? Ss 11:55 0:00 xfce4-power-manager
rahmu 1943 0.0 0.0 32792 1964 ? S 11:55 0:00 /usr/lib/xfconf/xfconfd
rahmu 1945 0.0 0.0 17584 1292 ? S 11:55 0:00 /usr/lib/gamin/gam_server
rahmu 1946 0.0 0.5 203016 19552 ? S 11:55 0:00 python /usr/bin/system-config-printer-applet
rahmu 1947 0.0 0.3 171840 12872 ? S 11:55 0:00 nm-applet --sm-disable
rahmu 1948 0.2 0.0 276000 3564 ? Sl 11:55 0:38 conky -q
2- grep conky
興味があるのは1つのプロセスだけなので、grep
を使用して、自分のプログラムconky
に対応するエントリを見つけます。
$ ps aux | grep conky
rahmu 1948 0.2 0.0 276000 3564 ? Sl 11:55 0:39 conky -q
rahmu 3233 0.0 0.0 7592 840 pts/1 S+ 16:55 0:00 grep conky
3- grep -v grep
手順2で確認できるように、コマンドps
は、リストにgrep conky
プロセスを出力します(結局、これは実行中のプロセスです)。それをフィルタリングするために、grep -v grep
を実行できます。オプション-v
は、すべての行に一致するようにgrep
に指示します除くパターンを含む行に一致します。
$ ps aux | grep conky | grep -v grep
rahmu 1948 0.2 0.0 276000 3564 ? Sl 11:55 0:39 conky -q
注:単一のgrep
呼び出しでステップ2と3を実行する方法を知りたいです
4- awk '{print $2}'
ターゲットプロセスを分離したので、 PIDを取得したい。つまり、出力の2番目のワードを取得したいと思います。幸運なことに、ほとんど(すべて?)の最新のuniceは、テーブルデータで不思議に思うスクリプト言語であるawk
のいくつかのバージョンを提供します。私たちの仕事はprint $2
と同じくらい簡単になります。
$ ps aux | grep conky | grep -v grep | awk '{print $2}'
1948
5- xargs kill
PIDを持っています。 kill
に渡すだけです。これを行うには、xargs
を使用します。
xargs kill
は、入力(この場合はパイプから)から読み取り、commandから構成されますkill <items>
(<items>
は入力から読み取ったものです) 、作成したコマンドを実行します。私たちのケースではkill 1948
を実行します。任務完了。
最後の言葉
使用しているUNIXのバージョンによっては、特定のプログラムの動作が少し異なる場合があります(たとえば、ps
は$ 3列にPIDを出力する場合があります)。何かが間違っている、または違っているように見える場合は、ベンダーのドキュメントを読んでください(または、man
ページ)。また、配管が長いと危険な場合がありますのでご注意ください。特にkill
やrm
などのコマンドを使用する場合は、何も想定しないでください。たとえば、「conky」(または「Aconkyous」)という名前の別のユーザーがいる場合、私のコマンドは実行中のプロセスもすべて強制終了する可能性があります。
特に長いパイプの場合は注意が必要です。ここで行ったように、対話的に構築する方が、仮定をして後で後悔するよりも常に優れています。
私のお気に入りはこれです:
youtube-dl $1 -q -o - | ffmpeg -i - $2
$1
から渡された特定のYouTube URLから動画をダウンロードし、$2
から渡されたファイルとして出力します。ファイルが静かに-q
でSTDOUT -o -
に出力され、ffmpegにパイプされて-i -
によって入力として使用されることに注意してください。
特にLinuxの初心者にとって、これはコマンドラインが便利でGUIツールを使用するよりも簡単にできる理由の実用的な例となるでしょう。 YouTubeからビデオをダウンロードし、そのサウンドをMP3に変換するのにどれくらい時間がかかるかわかりません。上記の行は数秒でそれを行うことができます。
一般的な用途(読み取り:ほとんどの場合の使用方法)は、何らかの理由で、さまざまな処理タスクを実行するためにいくつかのツールでデータを実行する必要がある場合です。
だから私はtheパイプの使用はいくつかのビルディングブロック(異なるUNIXツール)を一緒にアセンブルするための接着剤と同じだと思います。 Ulrichが言ったように、sort
およびuniq
は一般的なスタンザです。
聴衆によっては、このパイプの使用法を強調したい場合、たとえば、次のように開始できます。「ねえ、このシラバスには、論文と講義ノートを含むいくつかの興味深いPDFへのリンクがありますが、一部は繰り返されています。どういうわけかこれを自動化しますか?」
次に、lynx --dump --listonly
がリンクのリストを取得する方法、grep
が.pdf
で終わるリンクをフィルタリングする方法、colrm
またはsed
がどのようにできるかを示すことができますlynx
が各URLに残した書き込み数を取り除く、sort
とuniq
が重複を取り除く方法、最後にwget -i -
を使用して取得する方法ファイル(もちろん--wait
を使用して、サーバーにやさしくなります)。
これは複雑な例だと思います。一方、パイプを使用してシェルに一度に実行させると、パイプの力を示すのに役立ちます。
ようやく、1年半ほど前に作ったこのワンライナーの混乱を共有できるようになりました...
while read in; do Host "$in"; done < sites.txt | grep -iv "GOOGLE" | grep -E '1\.2\.3\.4|5\.6\.7\.8' | sed -e 's/has\ address\ 216.70.91.72//' | sed -e 's/has\ address\ 94.23.33.92//' | while read sites; do curl -sL -w "%{http_code} %{url_effective}\\n" "$sites" -o /dev/null; done | grep -ivE '4.*|5.*' | sed -e 's/200//' | sed -e 's/HTTP/http/'
それ...
これは、1つのPython=スクリプトで十分にうまくいくはずです。
私は良いことについて正確には知りませんが、grep
を介したパイプ処理は最も一般的な用途の1つである必要があり、おそらくwc -l
がそれに続きます。 (はい、grep
にはほとんど知られていない-c
スイッチがあります。)
別の一般的なスタンザは| sort | uniq
です。これは、uniq
が入力のソートを必要とするためです。
これが最初に頭に浮かんだことです...
mysqldump
は、データ、スキーマ、およびオプションでプロシージャと関数をstdoutに送信するコンソールアプリケーションです。通常、バックアップ用のファイルにリダイレクトされます。
mysqldump <options> > mydb.dump
これにより、非圧縮のSQLスクリプトが得られます。スペースを節約するために、bzip2で圧縮できます。
bzip2 mydb.dump
または、両方を1つのステップで実行することもできます。
mysqldump <options> | bzip2 > mydb.dump.bz2
上記の例では、mysqldump
からのstdoutがbzip2にパイプされ、その出力がファイルにリダイレクトされます。
この例では必要ありませんが、次のとおりです。
$ ps aux | grep -v grep | grep conky
... grepsの順序を逆にすると、色付けは保持されますが、効率はかなり低下します。おそらく大きなリストでは、色は関係ありません。
また、このWebページは次のことを提案しています。
https://stackoverflow.com/questions/9375711/more-elegant-ps-aux-grep-v-grep
> Johnsywebが2012年2月21日10:31に回答 >通常のトリックはこれです: > ps aux | grep '[t] erminal' >これは端末を含む行に一致しますが、grep '[t] erminal'はそうではありません! >多くの種類のUnixでも機能します。
...しかし、1つの文字(プロセス 'X'など)を探している場合は機能しません。
これは、1つのコマンドで複数のパイプを使用する場合の例です。これは、gawkを使用してMySQLの一般クエリログ($ OFILE)を検索し、拒否されたログインを見つけます。次に、そのリストを名前でソートし、そのリストをuniqにパイプして、出現回数をカウントします。次に、パイプして、最後にもう一度ソートして、カウントされたリストを数値でソートします...
gawk '{ for (x=1;x<=NF;x++) if ( $x~"Access" && $(x+4)~".*@.*") print $(x+4)}' $OFILE | sort | uniq -c | sort -n
パイプはフィルターとトランスレーターで最適に機能します
find /usr/bin/ | #produce
sed 's:.*/::' | #translate: strip directory part
grep -i '^z' | #filter : select items starting with z
xargs -d '\n' aFinalConsumer #consume
このようにして、データは1つのプログラムから次のプログラムにバッファリングで流れることができ、すべてのデータが一度にメモリにある必要はありません。
以下は、xauthがオプションではないときにDISPLAY変数を設定するために使用した例です...
export DISPLAY=\`who am i |awk '{print $NF}' | sed 's/[()]//g'`":0.0"
最初のコマンドは、必要なデータ、つまりホスト名またはIPを取得します。 2番目のコマンドは、そのデータ(最後のフィールド)のみを取得します。最後に、最後のコマンドは括弧をデータから削除します。
cat filename | less
は単にless filename
これは私が毎日使用するピップの例です(ただし、悪い例かもしれません):ls -la | more -c
Scott hoffmanとnjsgの回答がより良い例です。
フォルダーサイズをソートして分析したい任意のディレクトリでこれを実行します(次にENDキーで下にスクロールします)。
du -m| sort -n| less
Sortiert nachOrdnergrösse
コマンドパイピングは、最初のコマンドの出力を次の入力として入力できると感じる場所ならどこでも使用できます。
例。
猫の例txt | grep {some_line} | awk {some_command}
これは、実行したコマンドの出力を別のコマンドの入力にすることができる場合は、それらをパイプ処理できるという単純な概念です。
方法: パターンを検索して、最後に発生したパターンを表示しますか?
段階的に構築できるパイプコンテキストでtail
、sed
、grep
を使用する方法を示します。