pmount 挂在 BASH 自动完成上

pmount 挂在 BASH 自动完成上

每当我尝试将自动完成与pmount终端结合使用时,终端就会冻结,直到我中止,CTRL+C这会导致自动完成实际执行。自动完成在任何其他方面都工作得很好,有趣的是,卸载pumount可以直接成功地自动完成通过pmount独立于我的工作目录安装的任何驱动器。

非常清晰的分步流程列表:

#start pmount
pmount /de<TAB to autocomplete>
#terminal is frozen
<press CTRL+C once to unfreeze>
pmount /dev/s
pmount /dev/sd<TAB to autocomplete>
#frozen again - note the "d"
<press CTRL+C once to unfreeze>
pmount /dev/sdb

请注意,在这种情况下,/dev/sdb是唯一存在的闪存驱动器,因此自动完成功能有点智能,不会提供例如/dev/sda,但它仍然冻结。

我已经测试了一个新的,即未配置的安装,zsh其中自动完成可以很好地工作pmount,但表现得不那么智能:pmount /dev/s<TAB>选择不会减少到/dev/sdb,但还包括“根硬盘驱动器”/dev/sdapumount <TAB>自动完成当前工作目录的条目。

所以我假设它与 BASH 所谓的智能自动完成行为有关,但我无法远程解决该问题,因为我什至不明白该行为是在哪里配置的。

有什么想法可以解决这个问题以及问题从何而来吗?

系统是Debian 8,pmount版本是0.9.23,BASH是4.3.30

答案1

自动完成参考文件存储在/etc/bash_completion.d/pmount我的系统上。

解决方案 1:(重新)移动/重命名文件

正如 Tom Hunt 所建议的,这是最简单的解决方案。挂起停止,但是自动完成是不智能的,即坚持当前目录的文件名。

解决方案 2:修复自动完成文件

参考文件的问题出现在_pmount()文件第 62 行的函数中(为了可读性添加了换行符 - 不在原始文件中):

devices="$( command ls $(grep -v '^[[:space:]]*#' /etc/pmount.allow )\
$(grep 1 /sys/block/*/removable |\
sed -e 's,/sys/block/,/dev/,;s,/removable:1,*,') 2>/dev/null |\
sort -u | sed -e 's,\(^/dev/\)\(.*\),\1\2 \2,' ; \
#this last line is of interest, as the errors occur here
grep $mdir /proc/mounts | sed -e 's,.*\($mdir/[^ ]*\).*,\1,' )"

错误在于

grep $mdir /proc/mounts

该变量$mdir之前未定义,因此脚本挂起。

所以我添加了定义mdir

mdir="$(readlink -f /media)"

取自_pumount()同一脚本的函数(参见第 75 行),例如第 36 行,似乎mdir代表edia(或数)目录ectory,即pmount.除此之外,出于安全原因,我还添加了函数mdir的局部变量_pmount()(第 25 行)。

自动完成现在停止挂起,但如果安装了可移动驱动器的分区,它的行为会很奇怪,因为它会显示安装的驱动器、其安装点以及来自的所有信息/proc/mounts,例如:

/media/sdc1
rw,nosuid,nodev,noexec,relatime,uid=1000,gid=1000,fmask=0177,dmask=0077,codepage=437,iocharset=iso8859-1,shortname=mixed,quiet,utf8,errors=remount-ro

这是由于发生错误的同一行 62 引起的,现在问题出在这部分:

grep $mdir /proc/mounts | sed -e 's,.*\($mdir/[^ ]*\).*,\1,'

其中sed命令必须失败(即不能按预期工作,不能作为命令失败),因为单引号会抑制 的求值$mdir,因此我将它们更改为双引号:

grep $mdir /proc/mounts | sed -e "s,.*\($mdir/[^ ]*\).*,\1,"

pmount自动补全现在会跳过 中的信息/proc/mounts,但仍显示已安装的分区,包括/media/sdc1安装点。

我无法判断哪个是 的标准行为pmount,但我执行了以下操作来实际抑制已安装的任何分区的列表,同样,初始行 62 现在更改为(添加换行符以提高可读性 - 应在自动完成脚本中删除) :

 devices="$( command ls $(grep -v '^[[:space:]]*#' /etc/pmount.allow )\
 $(grep 1 /sys/block/*/removable |\
 sed -e 's,/sys/block/,/dev/,;s,/removable:1,*,') 2>/dev/null |\
 sort -u | sed -e 's,\(^/dev/\)\(.*\),\1\2 \2,' \
 #previous block identical to original script
 #the following pipe replaces a semicolon from the original script
 #and so does anything that follows 
 | grep -v "$( if [[ $( grep $mdir /proc/mounts ) ]] ;
               then grep $mdir /proc/mounts |\
                    sed -e "s,.*\($mdir/[^ ]*\).*,\1," \
                        -e "s,$mdir/,," -e 's, ,\|,g' ;
               else echo $mdir ; fi \
             )"
 )"

现在,与原始脚本相反,前两个greps 的输出通过管道传输到 a grep,其中已安装的分区将被过滤,而不是/media从 中获取的任何安装/proc/mounts。该if循环需要区分空分区/media和已安装分区的情况。

通过这些更改,pmount将表现如下:

pmount <TAB to autocomplete>
/dev/sdc   /dev/sdc1  /dev/sdc2  /dev/sr0   sdc        sdc1       sdc       sr0
pmount sdc1
#successful mounting of sdc1
pmount <TAB to autocomplete>
/dev/sdc  /dev/sdc2  /dev/sr0  sdc       sdc2       sr0

即,已安装的分区被抑制,而驱动器的其他分区(以及驱动器本身)仍然显示。

mdir请注意第一步定义的重要性!

旁注pmount

请注意,此自动完成扫描/sys/block/*/removable1即仅列出设置了可移动位的设备。然而,其他驱动器可以通过输入来安装,例如pmount /dev/sdd1,它们只是不会显示在自动完成中。 AFAIK 这是预期的行为,我会保持原样。就我而言,这种情况发生在我正在运行分区的外部硬盘驱动器上ext4

相关内容