如何让mpv以分离进程运行fzf选中的文件并脱离终端?
解决方案:让mpv在Bash函数中后台无输出运行并脱离终端
你编写的Bash函数可通过fzf选择MP3文件并用mpv播放,但存在两个问题:播放时终端会输出mpv日志,且无法关闭终端(否则mpv会终止)。你尝试的写法未生效,以下是可行的调整方案:
原函数代码
play-music() { local selected=$(find "${PWD}" -mindepth 1 -maxdepth 1 -type f -iname "*.mp3" | LC_COLLATE=C sort | fzf) local processed="" while IFS= read -r line; do processed+="$line\n" done <<< "$selected" echo -e "${processed}" | xargs -d '\n' mpv # How to execute this line as a detached process without showing any message from mpv in the terminal }
无效尝试的代码
echo -e "${processed}" | xargs -d '\n' mpv </dev/null &>/dev/null & disown
优化后的实现
方法1:子shell+disown(推荐)
简化多余变量,通过子shell包裹播放逻辑,确保进程完全脱离终端:
play-music() { local selected=$(find "${PWD}" -mindepth 1 -maxdepth 1 -type f -iname "*.mp3" | LC_COLLATE=C sort | fzf) # 无选中文件时直接退出 [ -z "$selected" ] && return # 子shell后台运行,disown脱离终端控制 ( printf "%s\n" "$selected" | xargs -d '\n' mpv </dev/null &>/dev/null ) & disown }
方法2:使用setsid创建独立会话
借助setsid为mpv创建新会话,直接脱离当前终端:
play-music() { local selected=$(find "${PWD}" -mindepth 1 -maxdepth 1 -type f -iname "*.mp3" | LC_COLLATE=C sort | fzf) [ -z "$selected" ] && return # setsid让mpv脱离当前终端,关闭终端不影响播放 printf "%s\n" "$selected" | xargs -d '\n' setsid mpv </dev/null &>/dev/null & }
关键说明
- 移除冗余的
processed变量:selected本身就是fzf输出的换行分隔文件名,用printf "%s\n"直接输出可避免echo -e对特殊字符的错误转义。 - 彻底屏蔽输出:
</dev/null禁止mpv读取终端输入,&>/dev/null将所有标准输出和错误丢弃,消除终端日志。 - 脱离终端的核心逻辑:
- 方法1的子shell+
disown会让整个播放进程组脱离当前终端的控制,关闭终端后mpv仍能继续运行。 - 方法2的
setsid直接为mpv创建独立会话,从根源上切断与当前终端的关联,效果更直接。
- 方法1的子shell+
内容的提问来源于stack exchange,提问作者Rittwik Chatterjee
相关产品推荐
相关产品推荐

