所以我遇到了一点障碍,我的脚本中有一个选项,它调用一个函数,允许我指定一个文件/目录,然后我想将该输出解析为菜单工具(在本例中使用 dmenu)以选择哪个文件是我特别想要的,并继续在同一脚本中将该选择作为变量使用。如果只有一个文件或目录,这种方法可以正常工作,但我希望能够多次使用该选项,然后一次性将所有输出解析为 dmenu。这是一个片段
fileSelection () {
if [ -d "${OPTARG}" ]; then find "${OPTARG}" -type f; fi;
if [ -f "${OPTARG}" ]; then printf '%s\n' "${OPTARG}"; fi;
}
while getopts "f:" option; do
case "${option}" in
f) file="$(fileSelection|dmenu)";;
esac
done
就像我说的,如果我这样做,这会有效:
myscript -f file
或者
myscript -f directory
但我希望也能做到这一点:
myscript -f file1 -f file2
问题是,由于该函数是连续调用的,我无法像那样将输出解析到 dmenu,因为它不使用选项 file1 和 file2 调用 dmenu,而是先使用 file1,然后使用 file2,我希望这有意义。
我可能遗漏了一些非常简单的解决方案,我曾考虑过将输出简单地写入文件,然后解析可能有效的文件,但如果可能的话,我想避免通过管道传输到文件。我也试图使其符合 POSIX 标准,并希望得到后续的答案。
您可以收集从您的派生的值
-f
并将它们全部传递给dmenu
。这是一个适用于大多数目录和文件的示例 - 但不适用于包含嵌入换行符的目录和文件:由于您需要 POSIX 解决方案,并且您已经假设文件名不能包含换行符,因此您可以构建一个以换行符结尾的值的字符串并使用它。实际上,在这种情况下,我可能会构建一组起点,然后
find | dmenu
在它们之间使用,而不是像我在第一种方法中那样构建一组结果。您
fileSelection|dmenu
假设的文件路径无论如何都不包含换行符,因此您可以创建$file
一个换行符分隔/定界的列表:另一种方法是生成
set -- ...
shell 代码,将位置参数列表设置为文件列表从 POSIX 角度来看,这仍然很危险,因为
sed
不需要正确处理长度超过 LINE_MAX 字节的行,并且find
不能保证输出的行尽可能短(甚至不短于 PATH_MAX 本身,也不保证比 LINE_MAX 更短)。使选项解析
while
-loop 输出找到的名称,并将其输出传递给dmenu
。即,将管道dmenu
从输出移至 -loopfileSelection
的输出while
。-f
为了正确执行此操作,我们首先需要确定命令行上至少有一个选项。这意味着必须解析选项两次:一次处理任何其他选项并检测-f
,另一次对选项采取行动-f
并获取文件列表并让用户选择文件名放入我们的file
变量中。在进一步研究了 POSIX 数组处理方式后,我可能找到了解决方案
这是脚本的一个非常简化的版本,但只需从 sed 解析到 dmenu 就可以得到我想要的结果。我回家后会再检查一下。感谢 Chris Davies 为我指明了正确的方向。