---
url: https://kernelsu.org/ru_RU/guide/module-script.md
---
# Одноразовые скрипты

Одноразовый скрипт — это ZIP-архив, который менеджер KernelSU **запускает один раз**, а не устанавливает. Он упаковывается так же, как модуль, но ничего не остаётся на устройстве: менеджер распаковывает ZIP в приватный каталог, запрашивает объявленные в нём параметры, показывает исходный код `action.sh` и запускает его в root-оболочке. Используйте его для таких задач, как разблокировка скрытой настройки или экспорт журнала; всё, что должно выполняться при загрузке или изменять системные разделы, следует оформлять как [модуль](module.md).

## Структура пакета

```txt
<id>-<version>.zip
├── module.prop      # the usual module.prop fields + oneshot=true
├── action.sh        # required: the script the manager runs
├── params.json      # optional: parameters asked before running
├── customize.sh     # optional: only used if the ZIP is installed as a module
└── other files      # data the script reads via $MODPATH
```

`module.prop` использует те же поля, что и [модуль](module.md#module-prop), и добавляет поле `oneshot`:

```txt
id=example_script
name=Example Script
version=v1
versionCode=1
author=Alice
description=Does a thing once
oneshot=true
```

`oneshot` читается так же, как `metamodule`: значение без учёта окружающих пробелов равно `1` или `true` (без учёта регистра). Любое другое значение или отсутствие строки `oneshot` означает обычный модуль.

Не включайте файлы, предназначенные только для модулей, такие как `post-fs-data.sh`, `service.sh`, `system.prop`, `sepolicy.rule` или каталог `system/`: при одноразовом запуске они никогда не используются. Одноразовый скрипт не может быть метамодулем.

## Запуск скрипта

Запустить одноразовый скрипт можно двумя способами:

* **Из магазина модулей**: записи реестра [KernelSU Modules](https://modules.kernelsu.org) с `kind: script` отображаются со значком «Script» и кнопкой **Run** вместо **Установка**. Загруженный файл проверяется по размеру и SHA-256 из реестра, а `module.prop` должен содержать зарегистрированный `id`.
* **Из локального ZIP**: если вы выбираете один ZIP-файл из хранилища (или открываете его из другого приложения) и его `module.prop` содержит `oneshot=true`, вместо установщика открывается страница запуска. На этой странице также доступна кнопка **Install as module anyway**.

Перед запуском менеджер проверяет, что `module.prop` объявляет `oneshot` с корректным `id` и что `action.sh` находится в корне ZIP, после чего распаковывает архив. Абсолютные пути, `..`, символические ссылки и специальные файлы отклоняются, а распакованное содержимое ограничено 64 МиБ и 4096 записями.

На странице запуска отображаются форма параметров, исходный код `action.sh` и результат последнего запуска на этом устройстве. После подтверждения менеджер запускает скрипт в новой root-оболочке в глобальном пространстве имён монтирования, так же как кнопка «Действие» (Action) модуля:

```sh
cd <dir> && <env> /data/adb/ksu/bin/busybox sh ./action.sh </dev/null
```

Вывод отображается так же, как вывод кнопки «Действие», и его можно сохранить. После этого распакованный каталог удаляется. Менеджер запоминает только последний запуск (версию и код завершения); состояния установки и проверки обновлений нет.

### Переменные окружения

| Переменная | Значение |
| --- | --- |
| `ASH_STANDALONE` | `1` |
| `KSU` | `true` |
| `KSU_VER`, `KSU_VER_CODE`, `KSU_KERNEL_VER_CODE` | версии KernelSU, как и для модулей |
| `KSU_LATE_LOAD` | `1` только в [режиме late-load](module.md#late-load-mode) |
| `KSU_MODULE` | ID скрипта |
| `KSU_ONESHOT` | `1`, чтобы отличить одноразовый запуск от кнопки «Действие» установленного модуля |
| `MODPATH` | каталог распаковки; читайте файлы данных отсюда |
| `PATH` | `$PATH:/data/adb/ksu/bin` |
| `KSU_PARAM_<KEY>` | по одной на каждый параметр, см. [`params.json`](#params-json) |

Stdin — это `/dev/null`, поэтому скрипт не может интерактивно читать ввод; вместо этого объявляйте параметры.

### Коды завершения

| Код завершения | Значение |
| --- | --- |
| `0` | Успех. |
| `2` | Неприменимо к этому устройству; отображается как уведомление, а не как ошибка. |
| любой другой | Ошибка. |

## `params.json` {#params-json}

`params.json` необязателен. Он располагается в корне ZIP, представляет собой JSON в кодировке UTF-8 и имеет размер не более 64 КиБ. Менеджер строит по нему форму и передаёт каждое значение в `action.sh` как `KSU_PARAM_<KEY>`.

```json
{
  "schemaVersion": 1,
  "params": [
    {
      "key": "ENABLE_FASTBOOT",
      "type": "bool",
      "label": "Also enable fastboot",
      "description": "Optional longer help text",
      "default": true
    },
    { "key": "MODE", "type": "enum", "label": "Mode", "default": "a",
      "options": [ { "value": "a", "label": "A" }, { "value": "b" } ] },
    { "key": "NAME", "type": "string", "label": "Name", "default": "", "maxLength": 64,
      "required": false },
    { "key": "COUNT", "type": "int", "label": "Count", "default": 1, "min": 0, "max": 10 }
  ]
}
```

| Поле | Правило |
| --- | --- |
| `schemaVersion` | Должно быть `1`. |
| `params` | До 16 параметров. |
| `key` | `^[A-Z][A-Z0-9_]{0,31}$`, уникальный. Значение передаётся в скрипт как `KSU_PARAM_<key>`. |
| `type` | `bool`, `enum`, `string` или `int`. |
| `label` | Обязательное, 1–200 символов. Метки отображаются как написаны (на одном языке). |
| `description` | Необязательное, те же правила, что и для `label`. |

По типам:

| Тип | Поля | Передаётся как |
| --- | --- | --- |
| `bool` | `default`: `true` / `false` (по умолчанию `false`). | `true` / `false` |
| `enum` | `options`: 1–32 записи `{value, label?}`; `value` соответствует `^[A-Za-z0-9._-]{1,64}$` и уникально. `default` должно быть одним из значений (по умолчанию — первый вариант). | значение варианта |
| `string` | `default` (по умолчанию `""`), `maxLength` 1–1024 (по умолчанию 256), `required` (по умолчанию `false`; пустое значение допускается, если поле не обязательное). Значения не могут содержать NUL или переводы строк. | как введено |
| `int` | Необязательные `min` / `max` и `default` (по умолчанию `min`, или `0` без `min`); 32-битные знаковые целые числа. | десятичное число |

`default` каждого параметра должно удовлетворять его собственным ограничениям. Если `params.json` некорректен, менеджер отказывается запускать скрипт.

::: warning
Для значений `string` проверка формата не выполняется. Каждое значение передаётся в одинарных кавычках, поэтому оно никогда не раскрывается оболочкой, запускающей `action.sh`, однако `action.sh` всё равно должен проверять его и заключать в кавычки при использовании.
:::

## Пример

```sh
#!/system/bin/sh
# action.sh
MODPATH=${MODPATH:-${0%/*}}

if [ "$(getprop ro.miui.ui.version.name)" = "" ]; then
  echo "Not a MIUI device"
  exit 2
fi

echo "Mode: ${KSU_PARAM_MODE:-a}"
if [ "$KSU_PARAM_ENABLE_FASTBOOT" = "true" ]; then
  sh "$MODPATH/fastboot.sh" || exit 1
fi
echo "Done"
```

## Совместимость со старыми менеджерами

Менеджеры без поддержки одноразовых скриптов устанавливают ZIP как обычный модуль, кнопка «Действие» которого запускает `action.sh`. Следите за тем, чтобы `action.sh` работал и в этом случае: там `KSU_ONESHOT`, `MODPATH` и `KSU_PARAM_*` не заданы, а рабочим каталогом является каталог модуля. Используйте значения по умолчанию, как в примере выше:

```sh
MODPATH=${MODPATH:-${0%/*}}
MODE=${KSU_PARAM_MODE:-a}
```

## Публикация

Чтобы опубликовать одноразовый скрипт в [KernelSU Modules](https://modules.kernelsu.org), укажите `kind: script` в `module.yaml`. Правила реестра см. в разделе [Script entries](https://github.com/KernelSU-Modules/tools/blob/main/docs/developers/module-yaml.md#script-entries-kind-script).
