diff --git a/app/src/main/java/com/termux/app/RunCommandService.java b/app/src/main/java/com/termux/app/RunCommandService.java index 737a9d8c..2091f924 100644 --- a/app/src/main/java/com/termux/app/RunCommandService.java +++ b/app/src/main/java/com/termux/app/RunCommandService.java @@ -24,6 +24,7 @@ import com.termux.shared.logger.Logger; import com.termux.shared.notification.NotificationUtils; import com.termux.app.utils.PluginUtils; import com.termux.shared.shell.command.ExecutionCommand; +import com.termux.shared.shell.command.ExecutionCommand.Runner; /** * A service that receives {@link RUN_COMMAND_SERVICE#ACTION_RUN_COMMAND} intent from third party apps and @@ -100,7 +101,17 @@ public class RunCommandService extends Service { executionCommand.stdin = IntentUtils.getStringExtraIfSet(intent, RUN_COMMAND_SERVICE.EXTRA_STDIN, null); executionCommand.workingDirectory = IntentUtils.getStringExtraIfSet(intent, RUN_COMMAND_SERVICE.EXTRA_WORKDIR, null); - executionCommand.inBackground = intent.getBooleanExtra(RUN_COMMAND_SERVICE.EXTRA_BACKGROUND, false); + + // If EXTRA_RUNNER is passed, use that, otherwise check EXTRA_BACKGROUND and default to Runner.TERMINAL_SESSION + executionCommand.runner = IntentUtils.getStringExtraIfSet(intent, RUN_COMMAND_SERVICE.EXTRA_RUNNER, + (intent.getBooleanExtra(RUN_COMMAND_SERVICE.EXTRA_BACKGROUND, false) ? Runner.APP_SHELL.getName() : Runner.TERMINAL_SESSION.getName())); + if (Runner.runnerOf(executionCommand.runner) == null) { + errmsg = this.getString(R.string.error_run_command_service_invalid_execution_command_runner, executionCommand.runner); + executionCommand.setStateFailed(Errno.ERRNO_FAILED.getCode(), errmsg); + PluginUtils.processPluginExecutionCommandError(this, LOG_TAG, executionCommand, false); + return stopService(); + } + executionCommand.backgroundCustomLogLevel = IntentUtils.getIntegerExtraIfSet(intent, RUN_COMMAND_SERVICE.EXTRA_BACKGROUND_CUSTOM_LOG_LEVEL, null); executionCommand.sessionAction = intent.getStringExtra(RUN_COMMAND_SERVICE.EXTRA_SESSION_ACTION); executionCommand.commandLabel = IntentUtils.getStringExtraIfSet(intent, RUN_COMMAND_SERVICE.EXTRA_COMMAND_LABEL, "RUN_COMMAND Execution Intent Command"); @@ -195,7 +206,7 @@ public class RunCommandService extends Service { execIntent.putExtra(TERMUX_SERVICE.EXTRA_ARGUMENTS, executionCommand.arguments); execIntent.putExtra(TERMUX_SERVICE.EXTRA_STDIN, executionCommand.stdin); if (executionCommand.workingDirectory != null && !executionCommand.workingDirectory.isEmpty()) execIntent.putExtra(TERMUX_SERVICE.EXTRA_WORKDIR, executionCommand.workingDirectory); - execIntent.putExtra(TERMUX_SERVICE.EXTRA_BACKGROUND, executionCommand.inBackground); + execIntent.putExtra(TERMUX_SERVICE.EXTRA_RUNNER, executionCommand.runner); execIntent.putExtra(TERMUX_SERVICE.EXTRA_BACKGROUND_CUSTOM_LOG_LEVEL, DataUtils.getStringFromInteger(executionCommand.backgroundCustomLogLevel, null)); execIntent.putExtra(TERMUX_SERVICE.EXTRA_SESSION_ACTION, executionCommand.sessionAction); execIntent.putExtra(TERMUX_SERVICE.EXTRA_COMMAND_LABEL, executionCommand.commandLabel); diff --git a/app/src/main/java/com/termux/app/TermuxService.java b/app/src/main/java/com/termux/app/TermuxService.java index a04d49a1..5caa3ebb 100644 --- a/app/src/main/java/com/termux/app/TermuxService.java +++ b/app/src/main/java/com/termux/app/TermuxService.java @@ -40,6 +40,7 @@ import com.termux.shared.notification.NotificationUtils; import com.termux.shared.android.PermissionUtils; import com.termux.shared.data.DataUtils; import com.termux.shared.shell.command.ExecutionCommand; +import com.termux.shared.shell.command.ExecutionCommand.Runner; import com.termux.terminal.TerminalEmulator; import com.termux.terminal.TerminalSession; import com.termux.terminal.TerminalSessionClient; @@ -353,7 +354,17 @@ public final class TermuxService extends Service implements AppShell.AppShellCli ExecutionCommand executionCommand = new ExecutionCommand(getNextExecutionId()); executionCommand.executableUri = intent.getData(); - executionCommand.inBackground = intent.getBooleanExtra(TERMUX_SERVICE.EXTRA_BACKGROUND, false); + executionCommand.isPluginExecutionCommand = true; + + // If EXTRA_RUNNER is passed, use that, otherwise check EXTRA_BACKGROUND and default to Runner.TERMINAL_SESSION + executionCommand.runner = IntentUtils.getStringExtraIfSet(intent, TERMUX_SERVICE.EXTRA_RUNNER, + (intent.getBooleanExtra(TERMUX_SERVICE.EXTRA_BACKGROUND, false) ? Runner.APP_SHELL.getName() : Runner.TERMINAL_SESSION.getName())); + if (Runner.runnerOf(executionCommand.runner) == null) { + String errmsg = this.getString(R.string.error_termux_service_invalid_execution_command_runner, executionCommand.runner); + executionCommand.setStateFailed(Errno.ERRNO_FAILED.getCode(), errmsg); + PluginUtils.processPluginExecutionCommandError(this, LOG_TAG, executionCommand, false); + return; + } if (executionCommand.executableUri != null) { Logger.logVerbose(LOG_TAG, "uri: \"" + executionCommand.executableUri + "\", path: \"" + executionCommand.executableUri.getPath() + "\", fragment: \"" + executionCommand.executableUri.getFragment() + "\""); @@ -361,7 +372,7 @@ public final class TermuxService extends Service implements AppShell.AppShellCli // Get full path including fragment (anything after last "#") executionCommand.executable = UriUtils.getUriFilePathWithFragment(executionCommand.executableUri); executionCommand.arguments = IntentUtils.getStringArrayExtraIfSet(intent, TERMUX_SERVICE.EXTRA_ARGUMENTS, null); - if (executionCommand.inBackground) + if (Runner.APP_SHELL.equalsRunner(executionCommand.runner)) executionCommand.stdin = IntentUtils.getStringExtraIfSet(intent, TERMUX_SERVICE.EXTRA_STDIN, null); executionCommand.backgroundCustomLogLevel = IntentUtils.getIntegerExtraIfSet(intent, TERMUX_SERVICE.EXTRA_BACKGROUND_CUSTOM_LOG_LEVEL, null); } @@ -373,7 +384,6 @@ public final class TermuxService extends Service implements AppShell.AppShellCli executionCommand.commandDescription = IntentUtils.getStringExtraIfSet(intent, TERMUX_SERVICE.EXTRA_COMMAND_DESCRIPTION, null); executionCommand.commandHelp = IntentUtils.getStringExtraIfSet(intent, TERMUX_SERVICE.EXTRA_COMMAND_HELP, null); executionCommand.pluginAPIHelp = IntentUtils.getStringExtraIfSet(intent, TERMUX_SERVICE.EXTRA_PLUGIN_API_HELP, null); - executionCommand.isPluginExecutionCommand = true; executionCommand.resultConfig.resultPendingIntent = intent.getParcelableExtra(TERMUX_SERVICE.EXTRA_PENDING_INTENT); executionCommand.resultConfig.resultDirectoryPath = IntentUtils.getStringExtraIfSet(intent, TERMUX_SERVICE.EXTRA_RESULT_DIRECTORY, null); if (executionCommand.resultConfig.resultDirectoryPath != null) { @@ -387,10 +397,14 @@ public final class TermuxService extends Service implements AppShell.AppShellCli // Add the execution command to pending plugin execution commands list mPendingPluginExecutionCommands.add(executionCommand); - if (executionCommand.inBackground) { - executeTermuxTaskCommand(executionCommand); - } else { - executeTermuxSessionCommand(executionCommand); + if (Runner.APP_SHELL.equalsRunner(executionCommand.runner)) + executeTermuxTaskCommand(executionCommand); + else if (Runner.TERMINAL_SESSION.equalsRunner(executionCommand.runner)) + executeTermuxSessionCommand(executionCommand); + else { + String errmsg = this.getString(R.string.error_termux_service_unsupported_execution_command_runner, executionCommand.runner); + executionCommand.setStateFailed(Errno.ERRNO_FAILED.getCode(), errmsg); + PluginUtils.processPluginExecutionCommandError(this, LOG_TAG, executionCommand, false); } } @@ -410,7 +424,7 @@ public final class TermuxService extends Service implements AppShell.AppShellCli /** Create a TermuxTask. */ @Nullable public AppShell createTermuxTask(String executablePath, String[] arguments, String stdin, String workingDirectory) { - return createTermuxTask(new ExecutionCommand(getNextExecutionId(), executablePath, arguments, stdin, workingDirectory, true, false)); + return createTermuxTask(new ExecutionCommand(getNextExecutionId(), executablePath, arguments, stdin, workingDirectory, Runner.APP_SHELL.getName(), false)); } /** Create a TermuxTask. */ @@ -420,8 +434,8 @@ public final class TermuxService extends Service implements AppShell.AppShellCli Logger.logDebug(LOG_TAG, "Creating \"" + executionCommand.getCommandIdAndLabelLogString() + "\" TermuxTask"); - if (!executionCommand.inBackground) { - Logger.logDebug(LOG_TAG, "Ignoring a foreground execution command passed to createTermuxTask()"); + if (!Runner.APP_SHELL.equalsRunner(executionCommand.runner)) { + Logger.logDebug(LOG_TAG, "Ignoring wrong runner \"" + executionCommand.runner + "\" command passed to createTermuxTask()"); return null; } @@ -502,7 +516,7 @@ public final class TermuxService extends Service implements AppShell.AppShellCli */ @Nullable public TermuxSession createTermuxSession(String executablePath, String[] arguments, String stdin, String workingDirectory, boolean isFailSafe, String sessionName) { - return createTermuxSession(new ExecutionCommand(getNextExecutionId(), executablePath, arguments, stdin, workingDirectory, false, isFailSafe), sessionName); + return createTermuxSession(new ExecutionCommand(getNextExecutionId(), executablePath, arguments, stdin, workingDirectory, Runner.TERMINAL_SESSION.getName(), isFailSafe), sessionName); } /** Create a {@link TermuxSession}. */ @@ -512,8 +526,8 @@ public final class TermuxService extends Service implements AppShell.AppShellCli Logger.logDebug(LOG_TAG, "Creating \"" + executionCommand.getCommandIdAndLabelLogString() + "\" TermuxSession"); - if (executionCommand.inBackground) { - Logger.logDebug(LOG_TAG, "Ignoring a background execution command passed to createTermuxSession()"); + if (!Runner.TERMINAL_SESSION.equalsRunner(executionCommand.runner)) { + Logger.logDebug(LOG_TAG, "Ignoring wrong runner \"" + executionCommand.runner + "\" command passed to createTermuxSession()"); return null; } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5f23f4bb..0a6c02dc 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -98,11 +98,14 @@ &TERMUX_APP_NAME; requires \"Display over other apps\" permission to start terminal sessions from background on Android >= 10. Grants it from Settings -> Apps -> &TERMUX_APP_NAME; -> Advanced + Invalid execution command runner to TermuxService: `%1$s` + Unsupported execution command runner to TermuxService: `%1$s` Invalid intent action to RunCommandService: `%1$s` + Invalid execution command runner to RunCommandService: `%1$s` Mandatory extra missing to RunCommandService: \"%1$s\" Visit %1$s for more info on RUN_COMMAND Intent usage. diff --git a/termux-shared/src/main/java/com/termux/shared/shell/command/ExecutionCommand.java b/termux-shared/src/main/java/com/termux/shared/shell/command/ExecutionCommand.java index 4751aa85..90c1fba4 100644 --- a/termux-shared/src/main/java/com/termux/shared/shell/command/ExecutionCommand.java +++ b/termux-shared/src/main/java/com/termux/shared/shell/command/ExecutionCommand.java @@ -4,6 +4,7 @@ import android.content.Intent; import android.net.Uri; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import com.termux.shared.data.IntentUtils; import com.termux.shared.shell.command.result.ResultConfig; @@ -13,6 +14,7 @@ import com.termux.shared.logger.Logger; import com.termux.shared.markdown.MarkdownUtils; import com.termux.shared.data.DataUtils; import com.termux.shared.shell.command.runner.app.AppShell; +import com.termux.terminal.TerminalSession; import java.util.Collections; import java.util.List; @@ -52,8 +54,56 @@ public class ExecutionCommand { return value; } + } + public enum Runner { + + /** Run command in {@link TerminalSession}. */ + TERMINAL_SESSION("terminal-session"), + + /** Run command in {@link AppShell}. */ + APP_SHELL("app-shell"); + + ///** Run command in {@link AdbShell}. */ + //ADB_SHELL("adb-shell"), + + ///** Run command in {@link RootShell}. */ + //ROOT_SHELL("root-shell"); + + private final String name; + + Runner(final String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public boolean equalsRunner(String runner) { + return runner != null && runner.equals(this.name); + } + + /** Get {@link Runner} for {@code name} if found, otherwise {@code null}. */ + @Nullable + public static Runner runnerOf(String name) { + for (Runner v : Runner.values()) { + if (v.name.equals(name)) { + return v; + } + } + return null; + } + + /** Get {@link Runner} for {@code name} if found, otherwise {@code def}. */ + @NonNull + public static Runner runnerOf(@Nullable String name, @NonNull Runner def) { + Runner runner = runnerOf(name); + return runner != null ? runner : def; + } + + } /** The optional unique id for the {@link ExecutionCommand}. */ public Integer id; @@ -83,8 +133,9 @@ public class ExecutionCommand { public Integer terminalTranscriptRows; - /** If the {@link ExecutionCommand} is a background or a foreground terminal session command. */ - public boolean inBackground; + /** The {@link Runner} for the {@link ExecutionCommand}. */ + public String runner; + /** If the {@link ExecutionCommand} is meant to start a failsafe terminal session. */ public boolean isFailsafe; @@ -145,13 +196,13 @@ public class ExecutionCommand { this.id = id; } - public ExecutionCommand(Integer id, String executable, String[] arguments, String stdin, String workingDirectory, boolean inBackground, boolean isFailsafe) { + public ExecutionCommand(Integer id, String executable, String[] arguments, String stdin, String workingDirectory, String runner, boolean isFailsafe) { this.id = id; this.executable = executable; this.arguments = arguments; this.stdin = stdin; this.workingDirectory = workingDirectory; - this.inBackground = inBackground; + this.runner = runner; this.isFailsafe = isFailsafe; } @@ -278,10 +329,10 @@ public class ExecutionCommand { logString.append("\n").append(executionCommand.getExecutableLogString()); logString.append("\n").append(executionCommand.getArgumentsLogString()); logString.append("\n").append(executionCommand.getWorkingDirectoryLogString()); - logString.append("\n").append(executionCommand.getInBackgroundLogString()); + logString.append("\n").append(executionCommand.getRunnerLogString()); logString.append("\n").append(executionCommand.getIsFailsafeLogString()); - if (executionCommand.inBackground) { + if (Runner.APP_SHELL.equalsRunner(executionCommand.runner)) { if (logStdin && (!ignoreNull || !DataUtils.isNullOrEmpty(executionCommand.stdin))) logString.append("\n").append(executionCommand.getStdinLogString()); @@ -372,10 +423,10 @@ public class ExecutionCommand { markdownString.append("\n").append(MarkdownUtils.getSingleLineMarkdownStringEntry("Executable", executionCommand.executable, "-")); markdownString.append("\n").append(getArgumentsMarkdownString(executionCommand.arguments)); markdownString.append("\n").append(MarkdownUtils.getSingleLineMarkdownStringEntry("Working Directory", executionCommand.workingDirectory, "-")); - markdownString.append("\n").append(MarkdownUtils.getSingleLineMarkdownStringEntry("inBackground", executionCommand.inBackground, "-")); + markdownString.append("\n").append(MarkdownUtils.getSingleLineMarkdownStringEntry("Runner", executionCommand.runner, "-")); markdownString.append("\n").append(MarkdownUtils.getSingleLineMarkdownStringEntry("isFailsafe", executionCommand.isFailsafe, "-")); - if (executionCommand.inBackground) { + if (Runner.APP_SHELL.equalsRunner(executionCommand.runner)) { if (!DataUtils.isNullOrEmpty(executionCommand.stdin)) markdownString.append("\n").append(MarkdownUtils.getMultiLineMarkdownStringEntry("Stdin", executionCommand.stdin, "-")); if (executionCommand.backgroundCustomLogLevel != null) @@ -450,8 +501,8 @@ public class ExecutionCommand { return "Working Directory: `" + workingDirectory + "`"; } - public String getInBackgroundLogString() { - return "inBackground: `" + inBackground + "`"; + public String getRunnerLogString() { + return Logger.getSingleLineLogStringEntry("Runner", runner, "-"); } public String getIsFailsafeLogString() { diff --git a/termux-shared/src/main/java/com/termux/shared/termux/TermuxConstants.java b/termux-shared/src/main/java/com/termux/shared/termux/TermuxConstants.java index f799073b..31739de3 100644 --- a/termux-shared/src/main/java/com/termux/shared/termux/TermuxConstants.java +++ b/termux-shared/src/main/java/com/termux/shared/termux/TermuxConstants.java @@ -8,7 +8,7 @@ import java.util.Formatter; import java.util.List; /* - * Version: v0.35.0 + * Version: v0.36.0 * SPDX-License-Identifier: MIT * * Changelog @@ -217,6 +217,9 @@ import java.util.List; * * - 0.35.0 (2022-01-28) * - Add `TERMUX_APP.TERMUX_ACTIVITY.EXTRA_RECREATE_ACTIVITY`. + * + * - 0.36.0 (2022-03-10) + * - Added `TERMUX_APP.TERMUX_SERVICE.EXTRA_RUNNER` and `TERMUX_APP.RUN_COMMAND_SERVICE.EXTRA_RUNNER` */ /** @@ -915,7 +918,10 @@ public final class TermuxConstants { /** Intent {@code String} extra for command current working directory for the TERMUX_SERVICE.ACTION_SERVICE_EXECUTE intent */ public static final String EXTRA_WORKDIR = TERMUX_PACKAGE_NAME + ".execute.cwd"; // Default: "com.termux.execute.cwd" /** Intent {@code boolean} extra for command background mode for the TERMUX_SERVICE.ACTION_SERVICE_EXECUTE intent */ + @Deprecated public static final String EXTRA_BACKGROUND = TERMUX_PACKAGE_NAME + ".execute.background"; // Default: "com.termux.execute.background" + /** Intent {@code boolean} extra for command the {@link com.termux.shared.shell.command.ExecutionCommand.Runner} for the TERMUX_SERVICE.ACTION_SERVICE_EXECUTE intent */ + public static final String EXTRA_RUNNER = TERMUX_PACKAGE_NAME + ".execute.runner"; // Default: "com.termux.execute.runner" /** Intent {@code String} extra for custom log level for background commands defined by {@link com.termux.shared.logger.Logger} for the TERMUX_SERVICE.ACTION_SERVICE_EXECUTE intent */ public static final String EXTRA_BACKGROUND_CUSTOM_LOG_LEVEL = TERMUX_PACKAGE_NAME + ".execute.background_custom_log_level"; // Default: "com.termux.execute.background_custom_log_level" /** Intent {@code String} extra for session action for foreground commands for the TERMUX_SERVICE.ACTION_SERVICE_EXECUTE intent */ @@ -1045,7 +1051,10 @@ public final class TermuxConstants { /** Intent {@code String} extra for current working directory of command for the RUN_COMMAND_SERVICE.ACTION_RUN_COMMAND intent */ public static final String EXTRA_WORKDIR = TERMUX_PACKAGE_NAME + ".RUN_COMMAND_WORKDIR"; // Default: "com.termux.RUN_COMMAND_WORKDIR" /** Intent {@code boolean} extra for whether to run command in background or foreground terminal session for the RUN_COMMAND_SERVICE.ACTION_RUN_COMMAND intent */ + @Deprecated public static final String EXTRA_BACKGROUND = TERMUX_PACKAGE_NAME + ".RUN_COMMAND_BACKGROUND"; // Default: "com.termux.RUN_COMMAND_BACKGROUND" + /** Intent {@code boolean} extra for command the {@link com.termux.shared.shell.command.ExecutionCommand.Runner} for the RUN_COMMAND_SERVICE.ACTION_RUN_COMMAND intent */ + public static final String EXTRA_RUNNER = TERMUX_PACKAGE_NAME + ".RUN_COMMAND_RUNNER"; // Default: "com.termux.RUN_COMMAND_RUNNER" /** Intent {@code String} extra for custom log level for background commands defined by {@link com.termux.shared.logger.Logger} for the RUN_COMMAND_SERVICE.ACTION_RUN_COMMAND intent */ public static final String EXTRA_BACKGROUND_CUSTOM_LOG_LEVEL = TERMUX_PACKAGE_NAME + ".RUN_COMMAND_BACKGROUND_CUSTOM_LOG_LEVEL"; // Default: "com.termux.RUN_COMMAND_BACKGROUND_CUSTOM_LOG_LEVEL" /** Intent {@code String} extra for session action of foreground commands for the RUN_COMMAND_SERVICE.ACTION_RUN_COMMAND intent */ diff --git a/termux-shared/src/main/java/com/termux/shared/termux/TermuxUtils.java b/termux-shared/src/main/java/com/termux/shared/termux/TermuxUtils.java index ce6ea6c9..75d212bb 100644 --- a/termux-shared/src/main/java/com/termux/shared/termux/TermuxUtils.java +++ b/termux-shared/src/main/java/com/termux/shared/termux/TermuxUtils.java @@ -520,7 +520,9 @@ public class TermuxUtils { aptInfoScript = aptInfoScript.replaceAll(Pattern.quote("@TERMUX_PREFIX@"), TermuxConstants.TERMUX_PREFIX_DIR_PATH); - ExecutionCommand executionCommand = new ExecutionCommand(1, TermuxConstants.TERMUX_BIN_PREFIX_DIR_PATH + "/bash", null, aptInfoScript, null, true, false); + ExecutionCommand executionCommand = new ExecutionCommand(1, + TermuxConstants.TERMUX_BIN_PREFIX_DIR_PATH + "/bash", null, aptInfoScript, + null, ExecutionCommand.Runner.APP_SHELL.getName(), false); executionCommand.commandLabel = "APT Info Command"; executionCommand.backgroundCustomLogLevel = Logger.LOG_LEVEL_OFF; AppShell appShell = AppShell.execute(context, executionCommand, null, new TermuxShellEnvironmentClient(), true); @@ -578,7 +580,8 @@ public class TermuxUtils { // Run script // Logging must be disabled for output of logcat command itself in StreamGobbler - ExecutionCommand executionCommand = new ExecutionCommand(1, "/system/bin/sh", null, logcatScript + "\n", "/", true, true); + ExecutionCommand executionCommand = new ExecutionCommand(1, "/system/bin/sh", + null, logcatScript + "\n", "/", ExecutionCommand.Runner.APP_SHELL.getName(), true); executionCommand.commandLabel = "Logcat dump command"; executionCommand.backgroundCustomLogLevel = Logger.LOG_LEVEL_OFF; AppShell appShell = AppShell.execute(context, executionCommand, null, new TermuxShellEnvironmentClient(), true); diff --git a/termux-shared/src/main/java/com/termux/shared/termux/file/TermuxFileUtils.java b/termux-shared/src/main/java/com/termux/shared/termux/file/TermuxFileUtils.java index a44c21a5..79770e79 100644 --- a/termux-shared/src/main/java/com/termux/shared/termux/file/TermuxFileUtils.java +++ b/termux-shared/src/main/java/com/termux/shared/termux/file/TermuxFileUtils.java @@ -342,7 +342,8 @@ public class TermuxFileUtils { .append("/system/bin/grep -E '( /data )|( /data/data )|( /data/user/[0-9]+ )' /proc/self/mountinfo 2>&1 | /system/bin/grep -v '/data_mirror' 2>&1"); // Run script - ExecutionCommand executionCommand = new ExecutionCommand(1, "/system/bin/sh", null, statScript.toString() + "\n", "/", true, true); + ExecutionCommand executionCommand = new ExecutionCommand(1, "/system/bin/sh", null, + statScript.toString() + "\n", "/", ExecutionCommand.Runner.APP_SHELL.getName(), true); executionCommand.commandLabel = TermuxConstants.TERMUX_APP_NAME + " Files Stat Command"; executionCommand.backgroundCustomLogLevel = Logger.LOG_LEVEL_OFF; AppShell appShell = AppShell.execute(context, executionCommand, null, new TermuxShellEnvironmentClient(), true);