批量处理文件路径时,coproc调用gjs脚本出现文件描述符错误
问题根源
你的错误来自两个核心问题:
- coproc命令无效:你写的
coproc get_icon_from_path_stdin不是实际存在的可执行命令,必须指定你的gjs脚本路径才能启动协程。 - gjs脚本不支持stdin输入:原脚本只能处理命令行参数,无法从stdin接收批量路径,导致协程启动后直接退出,进而触发文件描述符无效的错误。
解决方案
第一步:修改gjs脚本,支持批量读取stdin路径
将原gjs脚本改为逐行读取stdin输入,处理每个路径后输出对应图标:
#!/usr/bin/env gjs const { Gio, GLib } = imports.gi; // 从stdin读取输入流 let stdinStream = Gio.File.new_for_path('/dev/stdin').read(null); let dataInputStream = new Gio.DataInputStream({ base_stream: stdinStream, close_base_stream: true }); let line; // 循环读取每一行路径 while ((line = dataInputStream.read_line(null))[0] !== null) { let path = line[0].trim(); if (!path) continue; try { let file = Gio.File.new_for_path(path); let fileInfo = file.query_info('*', Gio.FileQueryInfoFlags.NONE, null); let icons = fileInfo.get_icon().get_names(); // 优先取第二个图标,不存在则取第一个 print(icons[1] || icons[0]); } catch (e) { // 处理路径不存在等异常,可替换为你需要的默认图标名称 print('unknown'); } }
第二步:修正bash脚本的coproc用法
确保协程启动的是修改后的gjs脚本,同时正确处理协程的输入输出:
#!/usr/bin/env bash shopt -s lastpipe # 替换为你的gjs脚本实际路径 GJS_ICON_SCRIPT="$HOME/.dotfiles/your-icon-script.js" # 启动协程,运行修改后的gjs脚本 coproc GJS_ICON_PROCESS "$GJS_ICON_SCRIPT" # 检查协程是否成功启动 if [[ ! -v COPROC_PID ]]; then echo "无法启动图标处理脚本" >&2 exit 1 fi # 循环读取书签列表,与协程交互 while IFS= read -r line; do # 发送路径到协程的stdin echo "$line" >&"${COPROC[1]}" # 从协程的stdout读取图标 if read -r icon <&"${COPROC[0]}"; then echo -en "$line\0icon\x1f${icon}\n" else # 协程异常退出时,直接输出路径 echo -en "$line\n" fi done < "$HOME/.dotfiles/rofi-bookmarks-list" | rofi -dmenu -i -theme-str 'window {fullscreen:true;}' | read select # 关闭协程输入流,让gjs脚本正常退出 exec {COPROC[1]}>&- # 等待协程结束 wait "$COPROC_PID" if [[ ${PIPESTATUS[1]} -eq 0 ]]; then nemo "$select" fi
额外优化
- 给gjs脚本添加可执行权限:
chmod +x "$GJS_ICON_SCRIPT" - 如果书签列表有大量重复路径,可先通过
sort -u去重后再处理,减少不必要的IO操作 - 可根据需求调整gjs脚本的异常处理逻辑,比如指定特定的默认图标名称
内容的提问来源于stack exchange,提问作者Ahmad Ismail
相关产品推荐
相关产品推荐

