for循环遍历目录时遇到麻烦

时间:2019-09-24 22:18:25

标签: android shell sh mksh

我正在尝试在android上的magisk模块中运行我的代码的这一部分,因此它使用android mksh shell。

我的目标是跳过$ MODULESPATH中的Fontchanger文件夹,因为Fontchanger是我的模块,并且如果该文件夹不是fontchanger并且它没有名为disable的文件,并且在$ i中只有一个system / fonts目录,然后代码应该运行。但是,当我去安装magisk模块zip时,它将运行此代码以检测$ MODULESPATH中的Fontchanger并中止。这与我所需要的相反。它需要跳过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 个答案:

答案 0 :(得分:1)

mksh上游开发人员在这里

我通常建议人们不要使用set -e set -u,因为它们会在不明显的复杂控制结构中引入故障。但是,我目前看不到任何使用未使用的变量的地方。另一方面,在最新版本的上游手册页(尚未发布)的“ CAVEATS”部分中描述了set -eset -o pipefail之间的交互,该交互最近才被跟踪:

 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 -uset -eo pipefail安全的。如果不是,我将需要一个日志(在某处添加set -x)来查看它的中断位置,因为我没有Magisk环境。 shell版本(echo $KSH_VERSION)也将派上用场;大多数Android都提供了非常老的mksh版本。

希望这会有所帮助;如果没有,请随时对我执行ping操作,然后我将重做我的答案。

答案 1 :(得分:0)

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兼容,并且可以在magisk环境下的Android上运行