You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让记录观影清单的Shell脚本在dmenu中正常运行?

问题排查:dmenu运行Shell脚本无法识别当前目录的问题

问题描述

  • 需求:通过dmenu运行脚本,将当前电影目录名追加到watched.txt以记录已看电影
  • 异常现象:终端运行脚本完全正常,但通过dmenu运行时,始终触发else分支,提示"not inside movies directory"
  • 环境说明:~/bin已加入$PATH,其他存放在该目录的脚本均可通过dmenu正常运行

用户提供的脚本代码:

#!/bin/sh

parent_dir=$(basename "$(dirname "$PWD")")
if [ "$parent_dir" = "movies" ];then
        choice=$(echo -e "yes\nno" | dmenu -p Watched?)

        if [ "$choice" = "yes" ];then
                echo "$(basename "$PWD")" >> /home/sinjini/movies/watched.txt && nl -s: -p ~/movies/watched.txt | dmenu -p "watched movies" -l 5
        else
                 nl -s: -p ~/movies/watched.txt | dmenu -p "watched movies" -l 5
        fi
else
        echo not inside movies directory | dmenu -p watched
fi

问题根源

你的猜测完全正确:dmenu(以及绝大多数桌面环境启动的程序)的当前工作目录并非你打开dmenu时所在的终端目录,而是桌面环境的默认工作目录(通常是用户主目录~/)。因此脚本中$PWD在dmenu环境下指向的是~/,计算出的parent_dir自然不是"movies",直接触发了else分支。

解决方案

有两种可行的修正方向:

方向1:获取当前终端的工作目录

如果你的dmenu是从终端启动,或者需要关联当前终端的目录,可以借助xdotool读取终端进程的工作目录:

#!/bin/sh
# 获取当前活跃终端的PID
term_pid=$(xdotool getwindowfocus getwindowpid)
# 读取该PID对应的工作目录
term_pwd=$(readlink /proc/$term_pid/cwd)
# 计算父目录
parent_dir=$(basename "$(dirname "$term_pwd")")

if [ "$parent_dir" = "movies" ];then
        choice=$(echo -e "yes\nno" | dmenu -p Watched?)

        if [ "$choice" = "yes" ];then
                echo "$(basename "$term_pwd")" >> /home/sinjini/movies/watched.txt && nl -s: -p ~/movies/watched.txt | dmenu -p "watched movies" -l 5
        else
                 nl -s: -p ~/movies/watched.txt | dmenu -p "watched movies" -l 5
        fi
else
        echo not inside movies directory | dmenu -p watched
fi

注意:需要先安装xdotool(例如sudo apt install xdotool)。

方向2:让脚本接收目录参数

修改脚本,允许传入目标电影目录作为参数,脱离对当前工作目录的依赖:

#!/bin/sh
# 检查是否传入目录参数
if [ -z "$1" ]; then
        echo "Usage: $0 <movie-directory>" | dmenu -p Error
        exit 1
fi

# 验证目录合法性
if [ ! -d "$1" ]; then
        echo "Invalid directory" | dmenu -p Error
        exit 1
fi

# 计算父目录
parent_dir=$(basename "$(dirname "$1")")
if [ "$parent_dir" = "movies" ];then
        choice=$(echo -e "yes\nno" | dmenu -p Watched?)

        if [ "$choice" = "yes" ];then
                echo "$(basename "$1")" >> /home/sinjini/movies/watched.txt && nl -s: -p ~/movies/watched.txt | dmenu -p "watched movies" -l 5
        else
                 nl -s: -p ~/movies/watched.txt | dmenu -p "watched movies" -l 5
        fi
else
        echo not inside movies directory | dmenu -p watched
fi

使用时,在终端执行watched "$PWD",或者将该命令绑定到快捷键,即可直接传递当前目录给脚本。

排查验证步骤

  • 在脚本开头添加调试代码,查看dmenu环境下的$PWD值:
    echo "PWD is: $PWD" | dmenu -p Debug
    
    运行后可确认dmenu的默认工作目录是否为用户主目录。
  • 打印parent_dir的值,验证计算逻辑:
    echo "parent_dir is: $parent_dir" | dmenu -p Debug
    

内容的提问来源于stack exchange,提问作者Sinjini

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 18:40:18