标题可能不是最好的描述问题的标题,但这是我能想到的最好的标题,继续描述我正在尝试做的事情,我使用 artix runit 作为我的操作系统,创建一个我想要启用的每个服务的符号链接,因此我创建了这个脚本以使其更容易。
#!/bin/sh
rundir="/run/runit/service"
svdir="/etc/runit/sv"
for SERVICE in $(ls $svdir); do
[[ -d "$rundir/$SERVICE" ]] && output="$output$SERVICE linked: yes\n" || output="$output$SERVICE linked: no\n"
done
service=$(printf "$output" | dmenu -l 10) || exit 1
if printf "$service" | grep -Fqe "linked: yes"; then
service=$(printf "$service" | awk '{print $1}')
sudo -A rm "$rundir/$service"
else
service=$(printf "$service" | awk '{print $1}')
sudo -A ln -s "$svdir/$service" "$rundir/"
fi
它检查所有可以启用的服务/etc/runit/sv
,并通过查看它们是否存在来检查它们是否已经启用,/run/runit/service
如果存在,它将添加到linked: yes
dmenu 列表的末尾,如果不存在,它会添加linked: no
问题是服务的名称各不相同,因此添加这些内容将导致这种不一致:
正如您所看到的,由于服务的名称会改变末尾文本的位置,所以我想说,这不太吸引人的眼睛,所以我想问是否有解决方案,如果没有,我想我会添加一linked: xxx
开始,因为这可以解决问题,但这是我最后的手段。如果有人想指出一种更有效的方法来编写代码,请这样做,这是我的第一个 bash 脚本,我还有很多东西要学。注意:我使用 dash 作为 sh,所以我不能使用任何类型的 bashisms。
答案1
您可以使用printf
将参数格式化为特定长度。我选择了20个字符的左对齐,根据需要调整。
对您的代码进行一些调整:
#!/bin/sh
rundir="/run/runit/service"
svdir="/etc/runit/sv"
cd "$svdir"
result=$(
for service in *; do
printf '%-20s linked: %s\n' "$service" $([ -d "$rundir/$service" ] && echo yes || echo no)
done | dmenu -l 10
) || exit 1
service=$(echo "$result" | awk '{print $1}')
case $result in
*yes)
sudo -A rm "$rundir/$service"
;;
*no)
sudo -A ln -s "$svdir/$service" "$rundir/"
esac
变更列表:
[ expression ]
对于测试,[[ ... ]]
破折号中不存在*
而不是ls
,但我需要一个cd
才能使其工作- 删除
$output
变量,将循环的输出通过管道传输到dmenu
- case 语句代替 if-else