我正在努力寻找一种优雅的方式来执行以下操作:
我想要一个 makefile 规则:
trace-XXXXX
,其中 XXXXX
是 QEMU 运行时的 PID。./qemu ... & echo $!
并将其放入某个变量中(变量的范围在规则内)目前我有以下内容:
trace:
./qemu/build/qemu-riscv64 -d plugin,nochain --trace "exec_tb" -plugin ./test_plugin.so ./test_qemu & export TRACE_PID=$$!; \
echo Trace PID is $$TRACE_PID; \
wait $$TRACE_PID; \
python3 ./qemu/scripts/simpletrace.py ./qemu/build/trace/trace-events-all trace-$$TRACE_PID
但是好像没啥作用。我看到“Trace PID is”,但随后得到一个在
line 1
上找不到的命令,我认为这可能是由于 qemu 的标准输出破坏了东西。
有没有一种干净优雅的方法来做到这一点?
调用qemu时捕获此PID,即
./qemu ... & echo $!
&
会导致您的 qemu
在后台运行,但这会适得其反,因为您想等待它完成。
捕获 PID 的唯一真正原因似乎是计算跟踪文件的名称。如果 qemu 支持它,最好的方法是自己选择跟踪文件的名称,并告诉
qemu
在那里写入。然后你可以在前台运行qemu
(没有wait
),然后分析文件。如果您需要的话,mktemp
命令将用于创建一个具有不同名称的新文件。
如果您无法预先控制跟踪文件名,那么您仍然可以通过将所有内容保留在前台来做得更好(IMO),如下所示:
trace:
TRACE_PID=$$(/bin/sh -c 'echo $$$$; exec ./qemu/build/qemu-riscv64 -d plugin,nochain --trace "exec_tb" -plugin ./test_plugin.so ./test_qemu >qemu.out 2>&1'); \
echo Trace PID is $$TRACE_PID; \
python3 ./qemu/scripts/simpletrace.py ./qemu/build/trace/trace-events-all trace-$$TRACE_PID
备注:
shell 将在
subshell中执行命令替换
$(...)
的内容,但这不一定在不同的进程中运行。我们确实需要一个不同的进程,因此我们从子 shell 启动一个单独的 shell 进程。
在该单独进程中运行的 shell 通过
echo
命令报告其 PID,顶级 shell 将捕获该命令。它使用 exec
在同一进程中运行 qemu
,因此已报告的 PID 对于 qemu
来说将是正确的。
qemu
命令的标准输出也被重定向到文件以防止它被捕获。它的标准错误被重定向到同一个文件以保持整洁,并避免潜在的混乱。
wait
执行任何操作,因为尚未启动任何后台作业。
echo Trace PID ...
命令只有在
qemu
完成后才会启动。
export TRACE_PID
,因为它似乎只在当前 shell 进程中使用,而不在任何子进程中使用。
qemu
失败。这个版本可以更容易地适应这一点,并且可能应该如此适应。
python3
可执行文件的完整路径。您甚至可能想为其创建一个
make
变量。