Termux add-on app for integration with Tasker.
A Termux add-on app allowing
Termuxcommands to be executed from Tasker and other plugin apps.
Termux:Tasker application can be obtained from
You do not need to download the
F-Droidapp (via the
Download F-Droidlink) to install Termux:Tasker. You can download the Termux:Tasker APK directly from the site by clicking the
Download APKlink at the bottom of each version section.
Termux:Tasker application can be obtained on
>= v0.6or from
Github Buildaction workflows.
The APKs for
Github Releaseswill be listed under
Assetsdrop-down of a release. These are automatically attached when a new version is released.
The APKs for
Github Buildaction workflows will be listed under
Artifactssection of a workflow run. These are created for each commit/push done to the repository and can be used by users who don't want to wait for releases and want to try out the latest features immediately or want to test their pull requests.
Termux:Taskerplugin requires Termux app to run the actual commands. You need to install it and start it at least once and have it install the required files for the plugin to start working. The Termux prefix directory
/data/data/com.termux/files/usr/and Termux home directory
/data/data/com.termux/files/home/must also exist and must have read, write and execute permissions
(0700)for the plugin to work. The
$PREFIX/is shortcut for the Termux prefix directory. The
~/is a shortcut for the Termux home directory. Permissions and ownerships can be checked with the
>= 0.5, the plugin host app will need to be granted the
com.termux.permission.RUN_COMMANDpermission to run ANY plugin commands. This is a security measure to prevent any other apps from running commands in
Termuxcontext which do not have the required permission granted to them. This is also required for the RUN_COMMAND Intent intent.
The Tasker app has requested the permission since
v5.9.3, so you will need to update the app if you are using an older version. You can grant the permission using the
Permissionsactivity in the
App Infoactivity of your plugin host app. For
Taskeryou can grant it with:
Run commands in Termux environment.
If you do not grant the permission, you will likely get errors like
receiver com.termux.tasker.FireReceiver requires permission com.termux.permission.RUN_COMMAND which we don't havewhen running the
Termux:Taskerplugin action in
Tasker. Note that, the
%errmsgfor missing permissions will not be set if you are using
Continue Task After Erroris enabled, only
%errwill be set to
1. You can open the plugin configuration screen to detect missing permissions of the plugin host.
~/.termux/tasker/directory stores the scripts that can be run with the plugin without setting
trueif you do not want to use absolute paths. Open a non-root termux session and run the below command to create it and give it read, write and executable permissions
taskerdirectory must have read permission, otherwise the plugin will not be able to read the script files and give errors like
No regular file found at pathfor any script name entered in the
Executablefield of plugin configuration. The
taskerdirectory of the script must also have executable permissions for the script to be allowed to execute.
mkdir -p /data/data/com.termux/files/home/.termux/tasker chmod 700 -R /data/data/com.termux/files/home/.termux
>= 0.5also allows commands to be run outside the
~/.termux/tasker/directory by setting absolute paths in the
Executablefield of the plugin configuration ONLY if
allow-external-appsproperty is set to
~/.termux/termux.propertiesfile. This is an added security measure. DO NOT set it to true if you have given a relatively untrusted app
com.termux.permission.RUN_COMMANDpermission, since it will be able to run arbitrary commands in termux or even root context (assuming termux has been granted root permissions) in the background without user intervention. The
~/.termuxdirectory must have read permission, otherwise the plugin will not be able to read the property values. This is also required for the RUN_COMMAND Intent intent.
Automatic You can use the one-liner commands below to set the desired value. The commands will append the desired value using
echocommand to the file if the file doesn't exist or the property doesn't exist in the file, otherwise it will
sedreplace any existing values of the key with the desired value.
value="true"; key="allow-external-apps"; file="/data/data/com.termux/files/home/.termux/termux.properties"; mkdir -p "$(dirname "$file")"; chmod 700 "$(dirname "$file")"; if ! grep -E '^'"$key"'=.*' $file &>/dev/null; then [[ -s "$file" && ! -z "$(tail -c 1 "$file")" ]] && newline=$'\n' || newline=""; echo "$newline$key=$value" >> "$file"; else sed -i'' -E 's/^'"$key"'=.*/'"$key=$value"'/' $file; fi
To set `allow-external-apps` property to `false`.
value="false"; key="allow-external-apps"; file="/data/data/com.termux/files/home/.termux/termux.properties"; mkdir -p "$(dirname "$file")"; chmod 700 "$(dirname "$file")"; if ! grep -E '^'"$key"'=.*' $file &>/dev/null; then [[ -s "$file" && ! -z "$(tail -c 1 "$file")" ]] && newline=$'\n' || newline=""; echo "$newline$key=$value" >> "$file"; else sed -i'' -E 's/^'"$key"'=.*/'"$key=$value"'/' $file; fi
nanotext editor in the terminal. Then add/update a line
allow-external-apps=trueto set the property to
true, and press
Enterto save and
file="/data/data/com.termux/files/home/.termux/termux.properties"; mkdir -p "$(dirname "$file")"; nano "$file"
Draw Over Appspermission (Optional)
>= 10there are new restrictions that prevent activities from starting from the background. This prevents the background
TermuxServicefrom starting a terminal session in the foreground and running the commands until the user manually clicks
Termuxnotification in the status bar dropdown notifications list. This only affects plugin commands that are to be executed in a terminal session and not the background ones.
>= 0.100requests the
Draw Over Appspermission so that users can bypass this restriction so that commands can automatically start running without user intervention. You can grant
Draw Over Appspermission from its
Draw over other apps.
Select Action Categorydialog, select
Action Plugindialog, select
The plugin configuration activity can be started by plugin host apps to configure the plugin to define what commands should be run and in which mode.
The text fields support plugin host app local variables (all lowercase) like
%stdin, etc and you may use multiple variables in a single field.
Executabletext field defines the executable that needs to be run. It can either be set to a file in
~/.termux/tasker/directory or to an absolute path if
allow-external-appsproperty is set to
true(check Setup Instructions). Absolute paths can be like
~/prefixes are also supported, like
Execute permissions will automatically be set for the executable file if it exists inside the
~/.termux/tasker/directory when the plugin action is run. It is the user's responsibility to set read and execute permissions for the executable file if it exists outside the
~/.termux/tasker/directory. That can be done by running the command
chmod 700 "/path/to/executable"from a terminal session before running the plugin action.
Argumentstext field defines the argument that will be passed to the executable. For
>= 0.5, arguments will be processed just like there are if commands are run in a shell like bourne shell. It uses ArgumentTokenizer to parse the arguments string.
Arguemnts are split on whitespaces unless quoted with single or double quotes. Double quotes and backslashes can be escaped with backslashes in arguments surrounded with double quotes.
Any argument surrounded with single quotes is considered a literal string. However, if an argument itself contains single quotes, then they will need to be escaped properly. You can escape them by replacing all single quotes
'in an argument value with
'\''before passing the argument surrounded with single quotes. So an argument surrounded with single quotes that would have been passed like
'some arg with single quote ' in it'will be passed as
'some arg with single quote '\'' in it'. This is basically 3 parts
'some arg with single quote ',
' in it'but when processed, it will be considered as one single argument with the value
some arg with single quote ' in itthat is passed to the executable.
Tasker, you can use the
Variable Search Replaceaction on an
%argumentvariable to escape the single quotes. Set the
Searchfield to one single quote
', and enable
Replace Matchestoggle, and set
Replace Withfield to one single quote, followed by two backslashes, followed by two single quotes
'\\''. The double backslash is to escape the backslash character itself.
Working directory path
Working directory pathtext field for
>= 0.5defines the working directory that should be used while running the command. The directory must be readable by the termux app. It is the user's responsibility to create the directory if its outside the
~/directory for version
/data/data/com.termux/filesdirectory for version
>= 0.6. That can be done by running the command
mkdir -p "/path/to/workdir"from a terminal session before running the plugin action. The
~/prefixes are also supported, like
Stdintext field for
>= 0.6can be used to pass scripts via standard input (
stdin), like a
bashscript to the
$PREFIX/bin/bashshell and a
pythonscript to the
$PREFIX/bin/pythonshell or any other commands. This allows scripts to be defined in the plugin host app instead of defining physical script files in
~/.termux/tasker/directory. Check Defining Scripts In Plugin Host App for details.
Note that if passing script via
stdin, do not pass arguments, since it will fail depending on shell, at least will for
The max supported length of a script is
45Kcharacters taking into consideration the Tasker plugin bundle limits of
100KBwhen its stored in a
Parcel. On Android
Stringcharacters are stored in Parcel as
2bytes. So we use
10KBfor rest of the plugin configuration data and half of the remaining (
90KB) for storing the script.
Terminal Session Action
Terminal Session Actiontext field for
>= 0.6defines what should happen when a foreground session command is received for the
Termux. The user can define whether the new session should be automatically switched to or if existing session should remain as the current session. The user can also define if foreground session commands should open the
TermuxActivityor if they should run in the "background" in the Termux notification. The user can click the notification to open the sessions. The valid values are defined by
TermuxConstants.TERMUX_APP.TERMUX_SERVICE.VALUE_EXTRA_SESSION_ACTION_*, currently, between
Custom Log Level
Custom Log Leveltext field for
>= 0.6defines the log level for background commands that should be used by
By default Termux only logs command
logcatif user has set log level to
VERBOSEin Termux app settings (not
Termux:Tasker). However, if command outputted too much data to
logcatclients like in Android Studio would crash.
So one can pass a custom log level that is
>=to the log level set it Termux app settings where (
VERBOSE=3) for custom behaviour. If you pass
0, it will completely disable logging. If you pass
1, logging will only be enabled if log level in termux settings is
NORMALor higher. If custom log level is not passed, then default behaviour will remain and log level in Termux app settings must be
VERBOSEor higher for logging to be enabled. Note that the log entries will still be logged with priority
Log.VERBOSEregardless of log level, i.e
logcatcomponent will be
TermuxCommand. For output at
stdout, the entry format is
[-stdout] ...and for the output at
stderr, the entry format is
[-stderr] .... The will be the process id (
pid) as an integer that was started by Termux for the executable. For example:
V/TermuxCommand: [66666-stdout] ....
Custom Log Levelto send commands to Tasker
Instead of using
am command to send messages back to Tasker, you can use Tasker
Logcat Entry profile event to listen to messages from Termux at both
stderr. This might be faster than
am command intent systems or at least possibly more convenient in some use cases.
So setup a profile with the
Component value set to
Filter value set to
-E 'TermuxCommand: \[[0-9]+-((stdout)|(stderr))\] message_tag: .*' and enable the
Grep Filter toggle so that entry matching is done in native code. Check Tasker Logcat Info documentation for details. Also enable
Enforce Task Order in profile settings and set collision handling to
Run Both Together so that if two or more entries are sent quickly, entry task is run for all. Tasker currently (
v5.13.16) is not maintaining order of entry tasks despite the setting.
Then start a
Termux:Tasker plugin action with custom log level
1 (assuming current log level is
NORMAL) and you should be able to receive the entries for whatever you send to
stderr in your script that starts with
%lc_text in entry task of tasker
Logcat Entry profile. You can remove the prefix from the
%lc_text variable with
Variable Search Replace action. Set the
Search field to
TermuxCommand: \[[0-9]+-((stdout)|(stderr))\] message_tag: , and enable
Replace Matches toggle, and leave
Replace With empty.
Execute in a terminal session
Execute in a terminal sessiontoggle defines whether the commands will be run in the background or in a foreground terminal session.
If the toggle is enabled, a new terminal session will open up automatically in the foreground and commands will be run inside it. Result of commands is not returned to the plugin host app for version
< 0.6. For version
>= 0.6, result will be returned in
%stdoutvariable will only contain the session transcript and will contain both
stderrcombined, basically anything sent to the the pseudo terminal
PS1prefixes for interactive sessions. For foreground commands that exited with failure will require Termux app version
>= 0.118for sessions to automatically close without waiting for user to press enter.
If the toggle is not enabled, then commands are run in the background and result of commands is returned to the plugin host app in
Check Setup Instructions for android
>= 10restrictions that will prevent the commands from automatically starting unless notification is clicked.
Wait for result for commands
Wait for result for commandstoggle for
>= 0.6defines whether the plugin action should wait for result of commands. It will apply to both foreground session and background commands. Check Plugin Variables for details.
Check Templates section for templates that can be used for various configurations.
Depending on plugin configuration, the following variables may be returned.
%stdout_original_lengthcontaining original length of
%stderr_original_lengthcontaining original length of
exit codeof commands. The
0often means success and anything else is usually a failure of some sort.
exit codeof plugin action. This will be set only if running the action itself failed like missing permissions or invalid configuration. This may be set by the plugin host app or the plugin. This will not be set if plugin action succeeded.
%errmsgcontaining the error message of why the plugin action failed if
If the timeout value of the plugin action is set to
None(slider to extreme left in Tasker), then no variables will be returned, regardless of whether commands need to be run in a foreground terminal session or in background. Even
%errmsgwill not be set to notify of any errors while running the plugin action since plugin host app will not wait for the plugin to return any variables. This is important for cases like if
allow-external-appsis not set to
truebut an absolute path outside
~/.termux/tasker/directory is set as the
Executable, in which case the plugin action will appear to have succeeded but no commands will execute.
If the timeout value of the plugin action is set to
Wait for result for commandstoggle is enabled, then the result of commands will be returned in
%stderr(only background) and
%errmsgvariables may also be set if the action failed. Note that if the timeout has passed by the time commands finish, the result of command variables will not be set in the plugin host app task and the action will exit with a timeout error, the
%errvariable will be set to
timeout, at least in
If the timeout value of the plugin action is set to
Wait for result for commandstoggle is not enabled, then
%resultvariables will not be returned. Only the
%errmsgvariables may be set if the action failed.
The (new) default timeout is set to
10sfor all configurations. If you are running background commands that will likely take longer to run, then increase the timeout or set it to
Never(slider to extreme right in Tasker). The plugin host app may still get killed by android if it keeps running for long time regardless of timeout value, check here for more info. Even if the commands are to be run in a foreground terminal session, do not set timeout to
10sinstead, since with timeout
0, plugin host app will not wait for any errors to be returned by the plugin in
%errmsgvariables and continue the task and the user wouldn't know if any error occurred. Users who already have preexisting actions with the timeout set to
0, like for foreground terminal session commands (considering previous default was
0) should update their tasks and use the new default
10sinstead, just opening the configuration screen and returning should automatically do it.
>= 0.5, the
%resultvariables will also be automatically cleared whenever the action is run if timeout is greater than
0to solve the issue of if multiple actions are run in the same task, then variables from previous action may still be set and get mixed in with current ones. For older versions, you can use a
Variable Clearaction in Tasker with
Pattern Matchingenabled and the
Namefield set to
%errmsg/%stdout/%stderr/%resultto clear all of them before each plugin action if multiple actions are run in a task or
Local Variable Passthroughis enabled in Tasker.
%errmsgvariables will mainly only be set for
>= 0.5. These will be set if there are errors like if an executable file is not found, or if
allow-external-appsproperty is not set to
truebut an absolute path is specified as the executable.
Taskeritself may set it too like if
Taskerhas not been granted the
com.termux.permission.RUN_COMMANDpermission when running the plugin action or if a timeout occurs, etc.
%errmsgvariables must be stored in another variable with the
Variable Setaction right after the plugin action if they have to be checked and used later. The plugin host app like Tasker sets and clears
%errfor each action and it is only available in the next action. To check if and what they are set to, add a
Variable Clearaction for
%command_failedvariable before the plugin action, then add a
Variable Setaction after the plugin action for the
%command_failedvariable with the value
If %err Set OR If %errmsg Set. Then you can just check
If %command_failed Setafterward and flash it to notify the user or exit the task if necessary. Error checking should ideally also be done based on
%resultand optionally the
%stderrvariables before continuing the task.
%stderr_original_lengthcan be used to check if
%stderrwere truncated by Termux app before sending them back to plugin host app in case they were too large and would have triggered
stderrsent back will be truncated from the start to max
errmsgwill also be truncated from end to max
25KB. Check here and here for details.
Check Templates section for templates on how error and result variables should be handled for various configurations.
The templates were written for version
< 0.6and currently have not been updated for version
XMLDownload the Termux Tasker Plugin Basic Templates Task XML file to the android download directory. To download, right-click or hold the
Rawbutton at the top after opening a file link and select
Download/Save linkor use
curlfrom a termux shell. Then import the downloaded task file into Tasker by long pressing the
Tasktab button in Tasker home and selecting
curl -L 'https://github.com/termux/termux-tasker/raw/master/templates/plugin_hosts/tasker/Termux_Tasker_Plugin_Basic_Templates.tsk.xml' -o "/storage/emulated/0/Download/Termux_Tasker_Plugin_Basic_Templates.tsk.xml"
Termux Tasker Plugin Basic Templates Taskfrom
Check Termux Tasker Plugin Basic Templates Task Info file for more info on the task.
ScriptsTo use the above task, you will also need to place the termuxtaskerbasicbashtest and termuxtaskerbasicpythontest scripts in
~/.termux/tasker/directory after following its Setup Instructions. They basically just print the first
2args are received, otherwise exit with error.
1. Download the script files.
- Download to `~/.termux/tasker/` directly from github using `curl` using a non-root termux shell. `curl -L 'https://github.com/termux/termux-tasker/raw/master/templates/scripts/termux_tasker_basic_bash_test' -o "/data/data/com.termux/files/home/.termux/tasker/termux_tasker_basic_bash_test"` `curl -L 'https://github.com/termux/termux-tasker/raw/master/templates/scripts/termux_tasker_basic_python_test' -o "/data/data/com.termux/files/home/.termux/tasker/termux_tasker_basic_python_test"` - Download them manually to android download directory and then use `cat` to copy them to `~/.termux/tasker/` or manually do it with a [SAF file browser](#Creating-And-Modifying-Scripts). `cat "/storage/emulated/0/Download/termux_tasker_basic_bash_test" > "/data/data/com.termux/files/home/.termux/tasker/termux_tasker_basic_bash_test"` `cat "/storage/emulated/0/Download/termux_tasker_basic_python_test" > "/data/data/com.termux/files/home/.termux/tasker/termux_tasker_basic_python_test"`
Set executable permissions.
chmod 700 "/data/data/com.termux/files/home/.termux/tasker/termux_tasker_basic_bash_test"
chmod 700 "/data/data/com.termux/files/home/.termux/tasker/termux_tasker_basic_python_test"
To modify the scripts you can use
Termux needs to be granted
Storagepermission to allow it to access
/storage/emulated/0/Downloaddirectory, otherwise you will get permission denied errors while running commands.
You can create scripts in
~/.termux/tasker/directory after following its Setup Instructions. Scripts can also be created elsewhere in Termux files directory but will require
allow-external-appsto be set to
truefor the plugin to access them.
You can use
shellbased text editors like
emacsto create and modify scripts.
You can also use
GUIbased text editor android apps that support
SAF. Termux provides a Storage Access Framework (SAF) file provider to allow other apps to access its
~/home directory. However, the
$PREFIX/directory is not accessible to other apps. The QuickEdit or QuickEdit Pro app does support
SAFand can handle large files without crashing, however, it is closed source and its pro version without ads is paid. You can also use Acode editor or Turbo Editor if you want an open source app.
Note that the android default
Documentfile picker may not support hidden file or directories like
~/.termuxwhich start with a dot
., so if you try to use it to open files for a text editor app, then that directory will not show. You can instead create a symlink for
~/termux_symso that it is shown. Use
ln -s "/data/data/com.termux/files/home/.termux" "/data/data/com.termux/files/home/termux_sym"to create it.
You can help debug problems like how arguments are being parsed by the plugin or if the plugin is even firing etc by setting appropriate
Log Levelin options menu (3 dots) in the plugin configuration screen or in Termux app settings ->
Log Level. Note that whatever log level is set will affect the entire plugin app and all plugin actions and not just for the action whose configuration you used to set it. The setting only exists inside the configuration activity of actions because creating a separate launcher activity that would be shown in the list of apps in the launcher just for this setting doesn't seem worth it.
Log Leveldefaults to
Normaland log level
Debugcurrently logs additional information. Its best to revert log level to
Normalafter you have finished debugging since private data may otherwise be passed to
logcatduring normal operation and moreover, additional logging increases execution time.
For information on how to view the
logcatlogs, check official android guide here.
Off- Log nothing
Normal- Start logging error, warn and info messages and stacktraces
Debug- Start logging debug messages
Verbose- Start logging verbose messages ##
There are limits on the arguments size you can pass to commands or the full command string length that can be run, which is likely equal to
128KBfor an android device defined by
ARG_MAXbut after subtracting shell environment size, etc, it will roughly be around
120-125KBbut limits may vary for different android versions and kernels. You can check the limits for a given termux session by running
true | xargs --show-limits. If you exceed the limit, you will get exceptions like
Argument list too long. You can manually cross the limit by running something like
$PREFIX/bin/echo "$(head -c 131072 < /dev/zero | tr '\0' 'a')" | tr -d 'a', use full path of
echo, otherwise the
echoshell built-in will be called to which the limit does not apply since
execis not done.
Moreover, exchanging data between
Termux:Taskeris done using Intents, like sending the command and receiving result of commands in
%stderr. However, android has limits on the size of actual data that can be sent through intents, it is roughly
7but may be different for different android versions. The
Termuxapp based on testing still sets a safe limit at
100KBand will truncate any data higher than that. Check
%stderr_original_lengthin Plugin Variables section for details.
Basically, make sure any data/arguments you send to
Termux:Taskeris less than
120KB(or whatever you found) and any expected result sent back is less than
100KB, but best keep it as low as possible for greater portability. If you want to exchange an even larger data between tasker and termux, use physical files instead.
The argument data limits also apply for the RUN_COMMAND Intent intent.
Termux does not load the environment fully for external plugins or RUN_COMMAND Intent commands, like setting
LD_PRELOAD, so any external scripts which do not have shebangs to full path to termux bin directory will not work if called from inside your plugin scripts, since
libtermux-exec.sois not called since
LD_PRELOADisn't set and you will get
bad interpreter: No such file or directoryerrors. Simply setting
LD_PRELOADwill not work either without starting a new shell. So make sure to set the shebangs correctly for any external scripts you want to run from inside your plugin script. The correct shebangs for termux scripts are like
#!/data/data/com.termux/files/usr/bin/bashfor bash scripts instead of
#!/usr/bin/bashused in common linux distros. You can also use termux-fix-shebang command on the external scripts before running them with the plugin to fix the shebangs automatically or use
Any script files that need to be run need to be created in
~/.termux/tasker/directory. It may get inconvenient to create physical script files for each type of command you want to run. These script files are also neither part of backups of plugin host apps like Tasker and require separate backup methods and nor are part of project configs shared with other people or even between your own devices, and so the scripts need to be added manually to the
~/.termux/tasker/directory on each device.
To solve such issues and to dynamically define scripts of different interpreted languages inside your plugin host app like
Taskerand to pass them to
Termuxas arguments instead of creating script files, you can either use
Stdinplugin configuration field or use
scriptcommand type. These scripts will also load the termux environment properly like setting
LD_PRELOADetc before running the commands. There are much more customizable then using
Stdinand support things that aren't possible to be provided via the plugin.
Released under the GPLv3 license.