在之前的控制台输出中附加代码/文本以显示状态

在之前的控制台输出中附加代码/文本以显示状态

我一直无法弄清楚下面的“代码”是如何创建的。

# sudo /etc/init.d/samba restart
[ ok ] Restarting nmbd (via systemctl): nmbd.service.
[ ok ] Restarting smbd (via systemctl): smbd.service.

具体来说,调用命令后,首先显示的是:

[ .. ] Restarting nmbd (via systemctl): nmbd.service.

随后确认服务重新启动,它变为

[ ok ] Restarting nmbd (via systemctl): nmbd.service.

随着..改变ok

我想将这些合并到我自己的脚本中,但无法找到这些或任何类似的代码。

非常感谢您的帮助!

请注意,我仅使用 Samba 作为示例,因为它展示了我所指的输出。

据我所知,唯一的可能性是它运行了一些 python 脚本,但是查看任何具有类似输出的任意服务的服务文件都没有提到 python 脚本,也没有回显的内容ok

猫/etc/init.d/samba

#!/bin/sh

### BEGIN INIT INFO
# Provides:          samba
# Required-Start:
# Required-Stop:
# Default-Start:
# Default-Stop:
# Short-Description: ensure Samba daemons are started (nmbd, smbd and samba)
# Description: Starts Samba, a Windows AD and SMB/CIFS fileserver for UNIX
### END INIT INFO

set -e

# start nmbd, smbd and samba-ad-dc unconditionally
# the init scripts themselves check if they are needed or not
case $1 in
    start)
        /etc/init.d/nmbd start
        /etc/init.d/smbd start
        /etc/init.d/samba-ad-dc start
        ;;
    stop)
        /etc/init.d/samba-ad-dc stop
        /etc/init.d/smbd stop
        /etc/init.d/nmbd stop
        ;;
    reload)
        /etc/init.d/smbd reload
        ;;
    restart|force-reload)
        /etc/init.d/nmbd "$1"
        /etc/init.d/smbd "$1"
        /etc/init.d/samba-ad-dc "$1"
        ;;
    status)
        status=0
        NMBD_DISABLED=`testparm -s --parameter-name='disable netbios' 2>/dev/null || true`
        SERVER_ROLE=`samba-tool testparm --parameter-name="server role"  2>/dev/null | tail -1 || true`
        if [ "$SERVER_ROLE" != "active directory domain controller" ]; then
            if [ "$NMBD_DISABLED" != "Yes" ]; then
                /etc/init.d/nmbd status || status=$?
            fi
            /etc/init.d/smbd status || status=$?
        else
            /etc/init.d/samba-ad-dc status || status=$?
        fi
        exit $status
        ;;
    *)
        echo "Usage: /etc/init.d/samba {start|stop|reload|restart|force-reload|status}"
        exit 1
        ;;
esac

答案1

printf 并用回车符覆盖

这种“魔法”可以通过printf回车符“\r”来实现,以覆盖现有输出。但是,您必须注意连续的行。请观察以下示例:

#!/bin/bash

string="[  ] pinging google.com "

printf "%s" "$string"

if ping -c 4 -q google.com > /dev/null 
then
    printf "\r[OK"
    printf "\n\n"
fi

请注意,我们首先打印“status”字符串,然后使用回车跳回到开头,并用“[OK]”字符串覆盖前 3 个字符。以下两个换行符只是您想要执行的操作的示例,以便将脚本向前移动并打印更多行。至于if command ; then . . . fi,这是一个简单的结构,它根据command输出有条件地执行 if 语句的主体。

这种方法的缺点是,如果您打印的字符长度不匹配,那么它可能会显示出来。

$ printf "Hello\rcat\n" 
catlo

稍微好一点的方法:用转义代码清除行

我们可以利用ANSI 转义码用于清除行(在本例中为八进制\033[2K),以删除我们之前在行上的内容。这样做的好处是,当您将光标重置回开头时,不会出现打印内容的长度匹配/不匹配的问题。

以下是一个示例,添加了 UTF-8 字符以进行检查和交叉标记

#!/bin/bash

string="[ ] pinging google.com "
printf "%s" "$string"

if ping -c 4 -q google.com > /dev/null 
then
    # clear previous line, add UTF checkmar to string
    printf "\r%b" "\033[2K"
    string="[\U2713] pinging google.com "
else
    # clear previous line, add UTF checkmar to string
    printf "\r%b" "\033[2K"
    string="[\U274C] pinging google.com "
fi
printf "%b" "$string"

相关内容