Как создать таймер обратного отсчета

Значение некоторых из этих полей можно вывести из исходного кода сс и ядро Линукс.Информация, которую вы видите, распечатывается tcp_show_info()функция в iproute2/misc/ss.c.

адвмсс:

Вss.c:

s.advmss     = info->tcpi_advmss;
(...)
    if (s->advmss)
        out(" advmss:%d", s->advmss);

Вlinux/include/linux/tcp.h:

u16 advmss;     /* Advertised MSS           */

приложение _ограниченное:

Вss.c:

s.app_limited = info->tcpi_delivery_rate_app_limited;
(..)
if (s->app_limited)
   out(" app_limited");

Этот не задокументирован в linux/include/uapi/linux/tcp.hв Линукс:

struct tcp_info {
(...)
    __u8    tcpi_delivery_rate_app_limited:1;

но, что удивительно, мы можем найти некоторую информацию в коммите, который представил его:

commit eb8329e0a04db0061f714f033b4454326ba147f4
Author: Yuchung Cheng 
Date:   Mon Sep 19 23:39:16 2016 -0400

    tcp: export data delivery rate

    This commit export two new fields in struct tcp_info:

      tcpi_delivery_rate: The most recent goodput, as measured by
        tcp_rate_gen(). If the socket is limited by the sending
        application (e.g., no data to send), it reports the highest
        measurement instead of the most recent. The unit is bytes per
        second (like other rate fields in tcp_info).

      tcpi_delivery_rate_app_limited: A boolean indicating if the goodput
        was measured when the socket's throughput was limited by the
        sending application.

    This delivery rate information can be useful for applications that
    want to know the current throughput the TCP connection is seeing,
    e.g. adaptive bitrate video streaming. It can also be very useful for
    debugging or troubleshooting.

Быстрый git blameв ss.cподтверждает, что app_limitedбыл добавлен после того, как tcpi_delivery_rate_app_limitedбыл добавлен в ядро.

занято:

Вss.c:

s.busy_time = info->tcpi_busy_time;
(..)
    if (s->busy_time) {
        out(" busy:%llums", s->busy_time / 1000);

А в include/uapi/linux/tcp.hв Linux написано:

struct tcp_info {
(...)
    __u64   tcpi_busy_time;      /* Time (usec) busy sending data */

ретрансляция:

Вss.c:

s.retrans    = info->tcpi_retrans;
s.retrans_total  = info->tcpi_total_retrans;
(...)
    if (s->retrans || s->retrans_total)
        out(" retrans:%u/%u", s->retrans, s->retrans_total);

tcpi_total_retransне описан вlinux/include/uapi/linux/tcp.h:

struct tcp_info {
(...)
    __u32   tcpi_total_retrans;

но используется вtcp_get_info():

void tcp_get_info(struct sock *sk, struct tcp_info *info)
{
    const struct tcp_sock *tp = tcp_sk(sk); /* iff sk_type == SOCK_STREAM */
(...)
    info->tcpi_total_retrans = tp->total_retrans;

А в linux/include/linux/tcp.hсказано:

struct tcp_sock {
(...)
    u32 total_retrans;  /* Total retransmits for entire connection */

tcpi_retransтоже не описывается, а читается tcp_get_info()снова мы видим:

info->tcpi_retrans = tp->retrans_out;

И вlinux/include/linux/tcp.h:

struct tcp_sock {
(...)
    u32 retrans_out;    /* Retransmitted packets out        */

dsack _дубликаты:

Вss.c:

s.dsack_dups = info->tcpi_dsack_dups;
(...)
    if (s->dsack_dups)
        out(" dsack_dups:%u", s->dsack_dups);

В include/uapi/linux/tcp.hв Linux:

struct tcp_info {
(...)
__u32   tcpi_dsack_dups;     /* RFC4898 tcpEStatsStackDSACKDups */

И вhttps://www.ietf.org/rfc/rfc4898.txt:

The number of duplicate segments reported to the local host by D-SACK blocks.

2
18.11.2020, 16:00
2 ответа

Пока кто-нибудь не предложит лучшее решение:

#!/bin/bash

tmout=20

(
        while [[ $tmout -gt 0 ]]; do
                printf '\rPlease respond within %02d seconds: ' "$tmout" >&2
                sleep 1
                tmout=$(( tmout - 1 ))
        done
) & prompt_pid=$!

read -s -t "$tmout"
read_ok=$?
echo ''

if [[ $read_ok -eq 0 ]]; then
        kill "$prompt_pid"
        printf 'You responded with "%s"\n' "$REPLY"
else
        echo 'You did not respond in time'
fi

Это запускает фоновое задание, которое обновляет приглашение раз в секунду в течение $tmoutсекунд или до тех пор, пока оно не будет уничтожено. Тексту подсказки предшествует \r, возврат каретки. Вывод \rс помощью printfперемещает курсор обратно в начало строки, а это означает, что остальная часть строки перезапишет ранее выведенный текст, создавая впечатление тикающего счетчика. Я намеренно использую нулевое -заполненное двухзначное -целое число для счетчика, так что текстовая строка, выводимая printf, всегда имеет одинаковую длину (, по крайней мере, для значений $tmoutменьше 100. ).

Затем приоритетное задание ожидает $tmoutсекунд ввода данных пользователем с помощью readс тайм-аутом.Я использую -sс readздесь, так как мы читаем пароль (, это также означает, что то, что набирается, не будет отображаться и не будет испорчено выводимой подсказкой ).

Когда readвозвращается, мы завершаем цикл подсказок, если он все еще выполняется, а затем печатаем сообщение в зависимости от того, как readзавершается.

3
18.03.2021, 22:49

Вот фрагмент ; При достижении 00 секунд он будет ждать еще 5 секунд, вы можете отредактировать его с условием, потому что я не знаю, нужно ли это поведение:

#!/bin/bash
c1=5
c2=4
count=20
status=''
while [[ "$count" != 0 ]]   
    do
        count="$(expr $c1 \* $c2)"
        c2="$(expr $c2 \- 1)"
        read -t 5 -p  "You have $count sec to enter your password : "$'\n'
        status=$?
        if [ "$status" -ne 142 ] ; then
          break
        fi

done
if [ "$status" -eq 142 ]
then
    echo "Your time is over"
    
else 
   echo "Success"
fi 

###РЕДАКТИРОВАТЬ###

ВЫХОД 1:

[root@host~]#./lol.sh
You have 20 sec to enter your password :
You have 15 sec to enter your password :
You have 10 sec to enter your password :
You have 5 sec to enter your password :
You have 0 sec to enter your password :
Your time is over

ВЫХОД 2:

[root@host~]#./lol.sh
You have 20 sec to enter your password :
LOL
Success
[root@host~]#

##РЕДАКТИРОВАТЬ 2 БОЛЬШЕ ГЛОБАЛЬНОГО РЕШЕНИЯ, как предложено в комментариях##:

С этим счетчиком ровно 20 секунд; вы можете изменить константы tmt и wait _sec по своему усмотрению.

#!/bin/bash
##CALCULATTION :
##TIMEOUT=WAIT_SECONDS * NB_ITERATIONS 
##TIMEOUT modulo WAIT_SECONDS should  equal to 0 to get a fixed iterations number
# 20  =   5 * 4 
wait_sec=5
tmt=20
modulo_ok=1
fpr=1
count="$tmt"
# Modulo Test
if [[ "$(($tmt % $wait_sec))" -eq 0 ]]; then
    nb_iters="$(expr $tmt \/ $wait_sec)"
    modulo_ok=0
fi
if [[ "modulo_ok" -eq 0 ]]; then
    (while [[ "$count" != 0 ]] && [[ "$fpr" -gt 0 ]]
        do
            count="$(expr $wait_sec \* $nb_iters)"
            nb_iters="$(expr $nb_iters \- 1)"
            echo "You have $count sec to enter your password :" 
            ps -p "$pid" &> /dev/null 
            sleep $wait_sec
    done
    ) &  fpr=$?  
    bpr=$!
    read -t "$tmt" -s pass
    kill $bpr > /dev/null 2>&1 
    if [[ -z  "$pass" ]]
    then
        echo "Your time is over"
    else 
       echo "Success"
       echo "Your password is : $pass"
    fi 
else 
    echo 'Timeout modulo Wait seconds should be equal to 0'
fi

ВЫХОД 3:СЛУЧАЙ -> Пароль, установленный в течение интервала tmt

[root@host~]#./lol2.sh
You have 20 sec to enter your password :
You have 15 sec to enter your password :
Success
Your password is : Reda

ВЫХОД 4:СЛУЧАЙ -> Тайм-аут

[root@host~]#./lol2.sh
You have 20 sec to enter your password :
You have 15 sec to enter your password :
You have 10 sec to enter your password :
You have 5 sec to enter your password :
Your time is over

ВЫХОД 5:СЛУЧАЙ -> tmt % ожидания _сек отличается от 0

[root@host~]#./lol2.sh
Timeout modulo Wait seconds should be equal to 0
0
18.03.2021, 22:49

Теги

Похожие вопросы