Математика Bash :выкл. -на -единицу или вычисление ошибки, если число делится на другое число

Текущая версия

Последние версии bash будут терять привилегии, если только они не были запущены с -p. Из раздела bash (1 ), описывающего привилегированный режим:

If the shell is started with the effective user (group) id not equal to the real user (group) id, and the -p option is not supplied, [...] the effective user id is set to the real user id. If the -p option is supplied at startup, the effective user id is not reset. Turning this option off causes the effective user and group ids to be set to the real user and group ids.

Исторические версии

Вы спросили: "От какой версии...?". Та часть system(), которую вы цитируете, не изменилась с самой ранней версии, доступной в активном репозитории git(версии 1.70). Это было проверено в 2004 году, и в комментариях указано, что последний раз оно было изменено в 2001 году.

Bash версии 3 был выпущен в 2004 году . Это означает, что bash 2 была бы текущей/последней версией в то время. Таким образом, он говорит «... bash версии 2 или выше/новее», т.е. так было начиная с версии 2.

Чтобы убедиться в этом, вы можете попробовать собрать несколько промежуточных версий и протестировать их или обратиться к репозиторию bash git . Ответственные строки:

  if (running_setuid && privileged_mode == 0)
    disable_priv_mode ();

Они были там с версии 2.0 . Оглядываясь назад на версии 1.14.7 , bash сбрасывал привилегии только тогда, когда привилегированный режим был явно отключен с помощью+p:

    case 'p':
      if (on_or_off == '+')
      {
        setuid (current_user.uid);
        setgid (current_user.gid);
        current_user.euid = current_user.uid;
        current_user.egid = current_user.gid;
      }
0
05.08.2020, 21:28
1 ответ

Первое, что нужно сделать при отладке любого bash-скрипта, — это добавить set -xв самом верху. Это позволит вам увидеть, что делает сценарий, как выглядит каждый тест на каждой итерации цикла и т. д.

Я бы сказал,:

#!/usr/bin/env bash

# NOTE: Remove or comment the below line when you're done debugging!
set -x

minutes=6
sec=00
...

Рассыпание echo "myvar = $myvar"по всему коду во время отладки также может помочь вам отслеживать значение переменной в ключевых точках вашего сценария, чтобы вы могли сравнить его с тем, что, по вашему мнению, должно быть.

Недостаток вашей логики заключается в том, что как только вы получаете условие, которое позволяет вам выйти из цикла «счетчика минут»,вы немедленно уменьшаете min на 1 , поэтому, когда вы пересчитываете остаток, вы всегда отключается на единицу. Вы уменьшаете свой «счетчик»до того, каквы используете его для нужных вам вычислений!

Логически, вы хотите проверить секунды = 0, , затем вычислить остаток, , затем настроить для следующего цикла:

#!/usr/bin/env bash

#set -x

minutes=6
sec=00
min="$minutes"

do_thing() {
  echo 'done thing'
}

while [ "$min" -ge 0 ]; do
  while [ $sec -ge 0 ]; do
    echo "$min $sec"
    ((sec=sec-1))
    sleep 1
  done
  remainder=$(( min % 5 ))
  # Added echo for debugging
  echo "remainder = $remainder"
  [ "$remainder" -eq 0 ] && [ "$min" -ne "$minutes" ] && do_thing
  sec=59
  ((min=min-1))
done

Еще одна вещь выделяется здесь -Будьте очень осторожными с &&и||-они хороши для быстрых и грязных,но для сложной логики они могут вас обмануть!

Эти логические операторы не заменяют надлежащий тест, даже если они ведут себя таким образом иногда-одно отличие от использования, например, теста if []; then...заключается в том, что они потребляют ваш код выхода молча. Прочтите о них и не используйте более одного из них подряд, не используя также ()для обеспечения желаемого порядка операций.

Если вы хотите последовать моему совету и избегать &&здесь, вот один из способов (вложенный `если другой, но я предпочитаю не использовать их, если мне не нужно):

 ...
  remainder=$(( min % 5 ))
  # Added echo for debugging
  echo "remainder = $remainder"
  if ([ "$remainder" -eq 0 ] && [ "$min" -ne "$minutes" ]); then
    do_thing
  fi
  sec=59
  ((min=min-1))
 ...
2
18.03.2021, 23:14

Теги

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