Bashにこのエラーを標準エラーとして送信するように指示します。

Bashにこのエラーを標準エラーとして送信するように指示します。

LuaTeXコードのバックエンドでいくつかのLuaを書いている間、私は次のことを見つけました:背景として、ここにLuaコードがあります。このバージョンは標準のLuaです。しかし、この関数が何をしているのかを理解するためにLuaを知る必要はありません。

標準出力とエラーをLuaとTeXに返す関数が必要です。

Luaにはこれを行うライブラリ関数がないので、私は自分で書く必要がありました。

このバージョンでは、標準出力をファイルに書き込み、標準エラーを標準出力にリダイレクトします。それからそれを読んで返します。特にきれいではありませんが、より良い選択肢は明らかではありません。

local function exec_cmd(command, stdout_message, stderr_message)
   local filename=os.tmpname()
   local cmd = string.format(command .. " 2>&1 1> %s", filename)
   local pipe = io.popen(cmd)
   local stderr = pipe:read("*all")
   pipe:close()
   local f = assert(io.open(filename, "r"))
   local stdout = f:read("*all")
   f:close()
   os.remove (filename)
   if stdout ~= nil and stdout ~= '' then
      print(string.format(stdout_message, stdout))
   end
   if stderr ~= nil and stderr ~= '' then
      error(string.format(stderr_message, stderr))
   end
end

今日は、混乱した瞬間に上記commandの関数のパラメータとして次のようなコードを書きました。

"wkhtmltopdf searchpath(foo.html) foo.pdf"

上記のLua関数の観点から、次のようになります。

exec_cmd("wkhtmltopdf searchpath(foo.html) foo.pdf", "STDOUT FROM WKHTMLTOPDF is %s", "STDERR FROM WKHTMLTOPDF IS %s")

したがって、次のコマンドがシェルに渡されます。

wkhtmltopdf searchpath(foo.html) foo.pdf 2>&1 1> /tmp/lua_vyOiay

/tmp/lua_vyOiay.

シェルに直接入力するとエラーが発生します(すでに解釈目的で使用されているLuaは忘れてください)。

bash:予期しない表示"("の近くに構文エラーがあります。

しかし、興味深いことに、このエラーは標準出力に渡されないようです。少なくとも上記のコマンドは収集せず、他の方法では収集できません。

Lua機能を安全に保つために、ここに質問があります。

  1. 上記の不可解なコマンドで何が起こっているのか、なぜエラーがstderrに送信されないのですか?これは参考用です。
  2. stderr文字列を収集してTeXプログラムを中断させるにはどうすればよいですか?

さらなる議論の後、2は少なくとも2つの方法で実施することができる。

2a. Bash シェル自体でこのエラーが発生しているようで、Bash シェル自体の標準エラーをキャプチャする方法が必要です。

2b。 Luaによって生成されたシェル標準エラーのLuaメソッドを取得します。

ベストアンサー1

Luaプログラムはデフォルトで実行に帰結します。

io.popen("syntax(error) 2>&1 1>outputfile"):read("*all")

そのタスクは次のとおりです。

sh -c 'syntax(error) 2>&1 1>outputfile'

io.popen()開始するシェルの標準出力をキャプチャしますが、標準エラーはキャプチャしません。構文エラーがない場合、リダイレクトは stderr をパイプに、stdout をファイルにディスパッチします。ただし、構文エラーのため、シェルはそこまで実行できないため、リダイレクトは処理されません。 (シェルはユーザーが指示する内容を理解していません。)

実際にstdoutとstderrをキャプチャするには、通常、外部コマンドを開始する前に両方ともパイプ(または他のもの)に接続します。たとえば、Pythonにはパラメータがsubprocess.Popen()あります。しかし、Luaの標準ライブラリは少し荒れており、直接使用できないようです。この機能を提供するには、Cモジュールを作成する必要があります。stdoutstderr

説明で述べたように、コマンドをラップすると、eval結果のコマンドラインが次のようになります。

eval 'syntax(error)' 2>&1 1>outputfile

シェルはそれを実行する前に方向の再指定を処理しますeval。ただし、もちろん、コマンド内にある可能性のある単一引用符を保護するには、エスケープセットを追加する必要があります。

おすすめ記事