如何将子字符串作为列添加到字符串

如何将子字符串作为列添加到字符串

标题可能不是最好的描述问题的标题,但这是我能想到的最好的标题,继续描述我正在尝试做的事情,我使用 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: yesdmenu 列表的末尾,如果不存在,它会添加linked: no问题是服务的名称各不相同,因此添加这些内容将导致这种不一致: 不一致

正如您所看到的,由于服务的名称会改变末尾文本的位置,所以我想说,这不太吸引人的眼睛,所以我想问是否有解决方案,如果没有,我想我会添加一linked: xxx开始,因为这可以解决问题,但这是我最后的手段。如果有人想指出一种更有效的方法来编写代码,请这样做,这是我的第一个 bash 脚本,我还有很多东西要学。注意:我使用 dash 作为 sh,所以我不能使用任何类型的 bashisms。

答案1

您可以使用printf将参数格式化为特定长度。我选择了20个字符的左对齐,根据需要调整。

d菜单截图

对您的代码进行一些调整:

#!/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

相关内容