現在のプロンプト行を含むファイルにリダイレクト

現在のプロンプト行を含むファイルにリダイレクト

リダイレクトされたコマンド自体を出力ファイルリダイレクトにどのように含めることができますか?例えば

echo "hello!">output.txt

私が望む出力ファイルの内容は次のとおりです。

echo "hello!">output.txt
hello!

答え1

これには2つのうちの1つが必要な場合があります。

  1. 使用teeecho端末とファイルに転送された結果を取得します。

    $ echo 'hello!' | tee output
    hello!
    $ cat output
    hello!
    
  2. script完全な端末セッションをキャプチャするには:

    $ script
    Script started, output file is typescript
    $ echo 'hello!' >output
    $ cat output
    hello!
    $ exit
    Script done, output file is typescript
    
    $ cat typescript
    Script started on Sat Nov 10 15:15:06 2018
    $ echo 'hello!' >output
    $ cat output
    hello!
    $ exit
    
    Script done on Sat Nov 10 15:15:37 2018
    

これがあなたが要求したものではない場合は、質問を明確にしてください。

答え2

あなたが要求する内容の一般的には不可能です。

他のツール((1)と同様)を使用してこれを達成するには、scriptプログラムがシェルを観察する必要があります。

command >foo

fooファイル名を入力して作成します。また、シェルはこれを作成しようとしたため、すでに競合が発生しています。また、プログラムが印刷されたらどうなりますか?

command >foo

ターミナルで?

シェルの内部では、シェルのリダイレクトプロセスはプログラミングの観点から見ると非常に原始的です(オリジナルのシェルを自分で作成したCレッスンを探すことは本当に驚くべきことです)。

この機能が本当に必要な場合は、独自のシェルをハッキングしてリダイレクトを傍受し、コマンドをターゲットファイルに渡す必要があります。しかし、細部には不快な問題がたくさんあるかもしれません。

答え3

シェル全体をパイプすることもできます。

$ sh -i |& tee sh.log
sh-4.4$ hello
sh: hello: command not found
sh-4.4$ echo hi
hi
sh-4.4$ exit

-istdoutは端末ではありませんが、シェルをインタラクティブに保つことは依然として必要です。 bashとzshもこのオプションをサポートしています。|&パイプstdoutとstderr; zshとbashでは機能しますが、sh(必要な場合2>&1 |)では機能しません。もちろん、ファイルにリダイレクトしたい場合は、&>またはを使用することもできます。2>&1 >とにかく、sh.logこれにはすべてが含まれています。

$ cat sh.log
sh-4.4$ hello
sh: hello: command not found
sh-4.4$ echo hi
hi
sh-4.4$ exit

答え4

出力ファイル名を削除しても大丈夫なら、次が最も簡単な方法だと思います。

command='echo "hello!"'
(echo "$command"; eval "$command") >output.txt

ただし、ファイル名を印刷する必要がある場合は、次のコマンドを使用できます。

command='echo "hello!"'
(echo "$command >output.txt"; eval "$command") >output.txt

ファイル名の変数を導入することで、両方のファイル名が同じであることを確認できます。

output="output.txt"
command='echo "hello!"'
(echo "$command >$output"; eval "$command") >$output

これにより、印刷されたファイル名が実際のファイル名と異なるリスクを回避できます。

関連情報