スクリプト出力の自己リダイレクトに相当するダッシュ


9

Bashでは、現在実行中のスクリプトの将来のすべて stdout出力をリダイレクトできます。たとえば、このスクリプトでは、

exec > >(logger -t my-awesome-script)
echo 1
echo 2
echo 3

これはsyslogで終わります:

Oct 26 01:03:16 mybox my-awesome-script[72754]: 1
Oct 26 01:03:16 mybox my-awesome-script[72754]: 2
Oct 26 01:03:16 mybox my-awesome-script[72754]: 3

しかし、これはBash固有であり、リダイレクトを備えたネイキッドexecはDashでは機能しないようです。

Syntax error: redirection unexpected

Dashで、またはおそらく両方のシェルで機能させるにはどうすればよいですか?


正確に何が必要か明確にしていただけませんか?>ダッシュでリダイレクトできます。あなたは何か他のものを求めているように見えますが、それが何であるか私にはよくわかりません。
terdon

@terdon説明を拡大しました。
Alex B

回答:


6

あなたはただ行うことができます:

{ commands
....
} | logger -t my_awesome_script

あなたはどんなシェルでもそれをすることができます。

見た目が気に入らない場合は、スクリプトを関数にラップすることができます。

#!/bin/sh
run() if     [ "$run" != "$$" ] || return
      then   sh -c 'run=$$ exec "$0" "$@"' "$0" "$@" |
             logger -t my-awesome-script
      fi
#script-body
run "$@" || do stuff

最後の行はrun ${1+"$@"} || do stuff、引数が保持されるようにする必要があります。
Adam Katz 2016

@AdamKatz-良い点、execpt ${1+"$@"}は何もしません"$@" 。とにかく他の問題がありました。
mikeserv 2016

"$@"合格する""一方、引数がないとき${1+"$@"}は引数がない場合、空の文字列を渡します。""(引用符で囲まれていない)空の文字列は引数として解釈されない一方で、空の引数として解析されるため、これは多くのプログラムにとって非常に重要です。
Adam Katz

@AdamKatz-非常に古いBourneシェルはそうかもしれません(そして、私dashはそのようなシステムで見つけることを期待しません)が、それ以外"$@"は、引数なしのケースがPOSIXシェルのnull引数に代わらないという点でユニークです。
mikeserv 2016

1
@AdamKatz-それは実際には古いbshでもバグであり、そのように動作するはずがありませんでした。最終的には修正されましたが、たとえばSolaris 10でまだ必要かどうかはわかりません。あなたは$ *について正しいです-それはexpabsionの同じきちんとした特性を示しません-それのユニークさonkyは常にそれが何かであるけれども、その展開の可変の内容に関係します "${@+is especially cool $@}" 。しかし${1+”$@"}、結局のところ、以前の回避策とほとんど変わりません。ksh93を使用している場合:"${1+quoted" not quoted "quoted again}"
mikeserv

5

プロセスの置換は、名前付きパイプを使用して簡単にシミュレーションできます。

mkfifo logger_input
logger -t my_awesome_script < logger_input &
exec > logger_input
echo 1
echo 2
echo 3

実際、名前付きパイプは、/dev/fdプロセス置換をで実装できるメカニズム(もう1つ)の1つですbash


私の意見では最も用途が広い:teeを使用して複数のストリームにシームレスにリダイレクトできます。ただ1つ、スクリプトの最後に作成されたlogger_inputを削除することを忘れないでください。
lauhub

2

これはで可能ではないと思いますdash。そのmanページからわかる限り、プロセスの置換はサポートされていません。

回避策として、mikservの提案を試すか、すべてをファイルにリダイレクトし、スクリプトが終了した後(おそらくこれはスクリプト内にある)、そのファイルの内容をロガーに追加します。

$ exec > ~/foo/foo.txt
$ ls
$ echo something
$ cat foo/foo.txt | sudo logger -t my-awesome-script

実際、プロセス置換、または他のシェルがプロセス置換と呼んでいるものはdash、他のシェルよりも簡単です。プロセス置換は/dev/fd/[num]、匿名パイプへのリンクを指す引数に相当します。dash他のほとんどのシェルのように一時ファイルを生成するのではなく、匿名パイプを使用してヒアドキュメントを作成します。したがってcat /dev/fd/3 3<<HEREDOC\n$(get output)\nHEREDOC\n、機能的に同等であるだけでなく、fdに自分で名前を付けることもできます。それでも、あなたの主張は逆の方向に進んでいる-あなたは新しいfdを開き、execそれを読み取るプロセスをバックグラウンドで開く必要がある。
mikeserv 2014年

2
@mikeserv:どのような意味でcat /dev/fd/3 3<<HEREDOC\n$(get output)\nHEREDOC\n"簡単" cat <(get output)ですか?
ruakh 2014年

@mikeserv:覚えておくべきルールがたくさんあります。たぶん、あなたは単に彼らに慣れすぎて、あなたが気付かないほど成長したのでしょう。
ruakh 2014年

@ruakh-まあ、確かに。< >シェルリダイレクト。基本的にそれらの2つだけを実行する場合は、次の行にも重ねることができます。しかし、ええ、あなたにはポイントがあります-私はここのドキュメントが好きです。それでも、覚えておかなければならないことがたくさんあるので、普遍的に機能するほうが簡単だと思います。繰り返しになりますが、多くの人は他のシェルをあまり使用していないので、他のシェルに違いはありません。私は彼らの中だけではありません。
mikeserv 2014年

1
@mikeserv:ヒアドキュメントだけでなく、/dev/fd/3(その正確な形式で)また、空白に何が起きるかの詳細。。。さらに言えば、このアプローチ全体がDashでまったく機能し、すべてのコンポーネントを持つ他のシェルでは機能しないという事実は、全体的なアプローチが覚えておくべき特別なルールであることを意味します。(これは、ボキャブラリーの少ない簡略化された英語を作成しようとする試みを思い出させます。それらは、persistなどの単語を切り取りましたkeep onのような難しい問題を無視しています。)
ruakh
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.