Возникли проблемы с циклом for для перебора каталога - PullRequest
0 голосов
/ 25 сентября 2019

Я пытаюсь запустить эту часть своего кода в модуле magisk на android, чтобы он использовал оболочку android mksh.

Моя цель - пропустить папку Fontchanger в $ MODULESPATH, так как Fontchanger - это мой модуль, и если папка не является fontchanger, и в ней нет файла с именем disable, и в ней есть каталог system / fonts внутри $я только тогда должен выполнить код.Однако когда я устанавливаю zip-модуль моего модуля magisk, он запускает этот код, обнаружив Fontchanger в $ MODULESPATH, и прерывает работу.Это противоположность того, что мне нужно.Необходимо пропустить папку Fontchanger.

Это код

    imageless_magisk && MODULESPATH=/data/adb/modules || MODULESPATH=/sbin/.core/img
    for i in $MODULESPATH/*; do
      if [ $i != Fontchanger ]; then
        if [ ! -f $i/disable ]; then
          if [ -d $i/system/fonts ]; then
            NAME=$(get_var $i/module.prop)
            ui_print " [!] "
            ui_print " [!] Module editing fonts detected [!] "
            ui_print " [!] Module - $NAME [!] "
            ui_print " [!] "
            abort
          fi
        fi
      fi
    done

    imageless_magisk && MODULESPATH=/data/adb/modules_update || MODULESPATH=/sbin/.core/img
    for i in $MODULESPATH/*; do
      if [ $i != Fontchanger ]; then
        if [ ! -f $i/disable ]; then
          if [ -d $i/system/fonts ]; then 
            NAME=$(get_var $i/module.prop)
            ui_print " [!] "
            ui_print " [!] Module editing fonts detected [!] "
            ui_print " [!] Module - $NAME [!] "
            ui_print " [!] "
            abort
          fi
        fi
      fi
    done


get_var() { sed -n 's/^name=//p' ${1}; }

imageless_magisk() {
  [ $MAGISK_VER_CODE -gt 18100 ]
  return $?
}

Заранее благодарен за любую помощь

Ответы [ 2 ]

1 голос
/ 25 сентября 2019

mksh вышестоящий разработчик здесь ☻

Обычно я советую людям против set -e и особенно set -u, поскольку они приводят к сбоям в сложных управляющих структурах, которыене очевидны.Однако в настоящее время я не вижу ничего, использующего неиспользуемые переменные там.С другой стороны, существует взаимодействие между set -e и set -o pipefail, описанное в разделе CAVEATS последней версии вышеприведенной справочной страницы (еще не выпущенной), которое было отслежено только недавно:

 Using set -o pipefail makes the following construct error out:

       set -e
       for x in 1 2; do
               false && echo $x
       done | cat

 This is because, while the “&&” ensures that the inner command's failure
 is not taken, it sets the entire for..done loop's errorlevel, which is
 passed on by -o pipefail.  Invert the inner command: true || echo $x

Этот может повлиять на вложенные if с, но я не уверен здесь.

С другой стороны, эта часть кода определенно проверяетнеправильная вещь:

if [ $i != Fontchanger ]; then

Помните, строка выше была ...

for i in $MODULESPATH/*; do

… так что $i будет что-то вроде $MODULESPATH/Fontchanger.Кроме того, в случае ! imageless_magisk вы дважды запускаете /sbin/.core/img.

Пожалуйста, позвольте мне предложить, надеюсь, эквивалентный, рефакторированный код (я предпочитаю отказоустойчивый подход вместо вложенных if с,и условия || более стабильны по отношению к set -e, а условия [[ безопаснее использовать):

if imageless_magisk; then
        set -A MODULESPATHS -- /data/adb/modules /data/adb/modules_update
else
        set -A MODULESPATHS -- /sbin/.core/img
fi
for MODULESPATH in "${MODULESPATHS[@]}"; do
        for i in "$MODULESPATH"/*; do
                [[ $i = */Fontchanger ]] || continue
                [[ ! -f $i/disable ]] || continue
                [[ -d $i/system/fonts ]] || continue
                NAME=$(get_var "$i"/module.prop)
                ui_print " [!] "
                ui_print " [!] Module editing fonts detected [!] "
                ui_print " [!] Module - $NAME [!] "
                ui_print " [!] "
                abort
        done
done

Вы могли бы даже сделать что-то вроде этого: потерпеть неудачу только в конце, перечислив все каталоги, которые имеют «Шрифты редактирования модуля», вместо сбоя после первого появления:

if imageless_magisk; then
        set -A MODULESPATHS -- /data/adb/modules /data/adb/modules_update
else
        set -A MODULESPATHS -- /sbin/.core/img
fi
do_abort=0
for MODULESPATH in "${MODULESPATHS[@]}"; do
        for i in "$MODULESPATH"/*; do
                [[ $i = */Fontchanger ]] || continue
                [[ ! -f $i/disable ]] || continue
                [[ -d $i/system/fonts ]] || continue
                NAME=$(get_var "$i"/module.prop)
                if (( !do_abort )); then
                        ui_print " [!] "
                        ui_print " [!] Module editing fonts detected [!] "
                        do_abort=1
                fi
                ui_print " [!] Module - $NAME [!] "
        done
done
if (( do_abort )); then
        ui_print " [!] "
        abort
fi

Эти коды должны быть set -u и set -eo pipefail безопасными,Если это не так, мне нужен журнал (где-то добавить set -x), чтобы увидеть, где он ломается, так как у меня нет удобной среды Magisk.Версия оболочки (echo $KSH_VERSION) также пригодится;большинство Android поставляется с действительно старой mksh версией.

Надеюсь, это поможет;если нет, не стесняйтесь пинговать меня, и я переделываю свой ответ.

0 голосов
/ 28 сентября 2019
MODULESPATH=/data/adb/modules
imageless_magisk || MODULESPATH=/sbin/.core/img

for i in $MODULESPATH*/*; do
  if [[ $i != *Fontchanger ]] && [ ! -f $i/disable ] && [ -d $i/system/fonts ]; then
    NAME=$(get_var $i/module.prop)
    ui_print " [!] "
    ui_print " [!] Module editing fonts detected [!] "
    ui_print " [!] Module - $NAME [!] "
    ui_print " [!] "
    cancel
  fi
done

Этот код, который мы разработали, будет работать и настроен - euxo pipefail также совместим и работает на Android в среде magisk

...