我的用例是一个 yad 程序,它使用另一个挂载文件系统的脚本。我目前正在做的并且有些不满意的是,通过复杂的 kill 和 wait 来“模拟”yad 的返回值可用。
(挂载脚本位于代码片段上方且无关紧要。请注意,它在退出或重新挂载时向“FD”(而不是 SEL_FD)发送写入,下面的代码使用循环或不循环取决于 GAME_SEL 和 REMOUNTED)
#stdout to FD (to get the selection on exit and still be a background proc)
GAME_SEL=$(mktemp -u -p "${XDG_RUNTIME_DIR}" "${0##*/}.XXXXXXXXXX")
mkfifo "$GAME_SEL"
exec {SEL_FD}<> "$GAME_SEL"
yad \
--width=600 \
--height=660 \
--center \
--window-icon "applications-games" \
--title "Dosbox Launcher with games overlay" \
--text=" Click to play" \
--list \
--noheaders \
--search-column=2 \
--regex-search \
--column="Path:HD" \
--column="Game Config:TEXT" \
--button=gtk-close:1 \
--button=gtk-ok:0 \
"${CONF_LIST[@]}" \
2>/dev/null 1>& "$SEL_FD" &
yad_pid=$!
#wait for copy-on-write-drive notification (quit or mount doesn't matter)
#and kill the dialog using yad signal for graceful failure termination
( read -u "$FD"; kill -USR2 $yad_pid ) &
pidof_killer=$!
#wait for yad termination and read its stdout on a timeout. If triggers timeout, it's empty
wait $yad_pid 2>/dev/null
read -t 0.1 -u "$SEL_FD" GAME
exec {SEL_FD}>&- #close FD
#kill the killer if still active
kill $pidof_killer 2>/dev/null
wait $pidof_killer 2>/dev/null #supresses 'Terminated' output too
#if the killer was already dead (it caught a notification), this is 0, otherwise != 0
REMOUNTED=$?
据我所知,我需要这种复杂性,因为我需要将 yad 进程置于后台,以便能够响应挂载脚本 FD 通知而终止它,这反过来会导致 yad 的返回值(而不是标准输出)由 SEL_FD 捕获)不能被主脚本进程捕获。有没有更好的方法来执行这个逻辑?感觉这件事太复杂了。