2

pbpasteクリップボードの内容を返すMacOSXのコマンドを使用しています。pbpasteによって返される各行を個別のbashコマンドとして実行するシェルスクリプトを作成したいと思います。たとえば、クリップボードの内容が次のテキスト行で構成されているとします。

echo 1234 >~/a.txt
echo 5678 >~/b.txt

これらの各行を実行して、ホームフォルダーにa.txtとb.txtの2つのファイルを作成するシェルスクリプトが必要です。かなりの量の検索と試行錯誤の末、while次の構成を使用して、ループ内の変数にテキストの個々の行を割り当てることができるようになりました。

pbpaste | egrep -o [^$]+ | while read l; do echo $l; done

予想どおり、これは以下を標準出力に送信します。

echo 1234 >~/a.txt
echo 5678 >~/b.txt

テキストの各行を単純にエコーする代わりに、次の構成でそれらを実行しようとします。

pbpaste | egrep -o [^$]+ | while read l; do $l; done

これで各行が実行されると思いました(したがって、ホームフォルダーに2つのテキストファイルa.txtとb.txtを作成します)。代わりに、最初の用語(echo)はコマンドとして解釈され、残りの用語(nnnn >~/...)は単一のパラメーターであるかのようにまとめられているように見えます。その結果、ファイルが作成されずに次の用語が標準出力に送信されます。

1234 >~/a.txt
5678 >~/b.txt

なぜ私の構成が機能しないのか、そしてどのような変更がそれを機能させるのかを理解するのに助けていただければ幸いです。

4

1 に答える 1

2

[…]残りの用語(nnnn >~/...)は、単一のパラメーターであるかのようにまとめられているようです。[…]

ではない正確に。行は実際には空白(または$IFS指定されたもの)で分割されますが、問題は、リダイレクト演算子>をシェル変数から取得できないことです。たとえば、次のスニペット:

gt='>'
echo $gt foo.txt

> foo.txt改行を出力するのではなく、を出力しますfoo.txt

また、引用符など、他のさまざまなシェルメタ文字でも同様の問題が発生します。

必要なのはeval、文字列を受け取り、それをシェルコマンドとして解析し、実行するビルトインです。

pbpaste | egrep -o [^$]+ | while IFS= read -r LINE; do eval "$LINE"; done

IFS=および-rとの二重引用符$LINEはすべて、によって実行される処理以外の他の処理を防ぐevalためのものです。たとえば、引用符内の空白は保持されます。)

必要なものの詳細に応じて、別の可能性は、コマンドをBashの新しいインスタンスにパイプすることです。

pbpaste | egrep -o [^$]+ | bash

追加するために編集:evalさらに言えば、すべてを1つのバッチで渡すことができると思います。(コメントごとに)書くことができるのと同じようにpbpaste | bash、書くこともできますeval "$(pbpaste)"。これにより、現在のシェルで実行しながら、複数行ループなどがサポートwhileされます(シェルパラメーターを参照したり、環境変数を設定したりできるようにする場合に便利です)。

于 2013-01-31T23:09:25.147 に答える