LUSH - lua ultimate shell
Lush is a shell interpreter for minetest inspired by the POSIX shell and minecraft syntax. The benefits are:
- 79 commands
- sequential and conditional command execution
- parameters and parameter expansion
- subshells
- various datatypes which are consistently parsed
- implicit datatype conversion
- lazy loaded
- inline lua execution
- easier and more powerful API for defining commands
Project status
Lush is being actively developed and its currently in a mostely complete state its completely usable but the internal API is unstable and poorly documented
Contributions are welcome, in the form of PRs, bug reports or feature requests. if you would like to implement something but are lost in the code, dont mind opening up an issue about it
Mods
Lush is made up of mods, here are all the mods:
- lush_core: Core part of lush, adds the shell interpreter and provides all the necessary APIs
- lush_builtin: Mod that adds many general and useful commands
- lush_utilities: Mod that adds utilities for lush, these dont generally affect the game environment
- lush_messaging: Mod that rewrites the in game chat to provide many useful features, such as more convinient private messages, user blocking and optionally chat filtering using the filter++ liberary
- lush_moderation: Mod that adds commands for server moderation
- lush_gui: Mod that adds commands for displaying formspecs and HUDs
- lush_tpr: Mod that adds commands for teleport requests
Commands
Lush also adds 79 commands: (for the time being i am lazy and only list 56, see help menu for complete list)
- lush_utilities:
echo <arguments>
append <string>
lines <range>
wc <range>
prepend <string>
set <param>
split <seperator>
match <exit>
lush <code>
export <parameter name> <value> [--read-only] [--volatile]
env
- lush_builtin:
days
lag <seconds per globalstep>
set_node <position> <node name>
time <time> [--permament]
lunch <targets> <speed vector>
teleport <targets> to <position>
kill <targets>
damage <targets> <amount> [--type <damage type>]
spawnpoint <player> <position>
clear_spawnpoint <player>
heal <targets> <amount>
list
seed
lsmods
invis <players> on|off
give <players> <item name> <meta table>
--WIPpulverize <items>
fix_items <items>
lsitems <items>
nodeinfo metadata|inventory|groups|name|param1|param2 [--human]
- lush_moderation
ban <players> <time> [--script]
privs <player>
lsbans
unban <players> [--script]
kick <players> <reason>
grant <players> [privs|privileges] <priv> ... [--time <time>]
revoke <players> [privs|privileges] <priv> ... [--time <time>]
mute <players> <length>
- lush_doas
doas <player> <shell code>
su <player>
sb
- lush_tpr
tpr <player>
tpa <player>
- lush_messaging
bc <message>
msg <player> <message>
block <player>
unblock <player>
lsblocks
- lush_command_managment
blacklist_command <command> ...
whitelist <command> ...
override_command_privs <command> (add | remove | set) <priv> ...
restore_command_privs <command>
ls_command_overrides
- lush_findbiome
lsbiomes
findbiome <biome name> ... [--tp] [--start-pos <position>] [--resolution <number>] [check-amount <number>]
Lush aims to add every useful command. If you would like to see some command, feature requests are welcome
Usage
Basics
Commands need to start with a ! to invoke the shell
!echo hello world!
hello
world!
/
works too but there are some caveats, keep reading to know the difference.
For the rest of the guide i will be using !
/echo hello world!
hello
world!
Enclose in quotes to make it not split into many arguments. Single quotes are also supported
!echo "hello world!"
hello world!
!echo 'hello world'
hello world!
Escape sequences are supported in double quotes, but not in single quotes
!echo '\\'
\\
!echo "\\"
\
Calling multiple commands
Commands can be executed one after another
!echo hello; echo world
hello
world
Commands can be run only if the one before succeeds, or only if they fail
!exit 0 && echo success
success
!exit 1 || echo failure
failure
Output of one command can be piped into another command. This means that the output of the command is given as input to another command
!echo hello world | append " text"
hello text
world text
All previous thingies can be combined whenever you feel like it
!var="hello world"; echo $var | append " text" && echo "success!" || echo "failure!"
hello world
success!
When starting commands with a /
instead of !
you lose many of those features.
!
- runs a shell/
- runs a command
the shell differs from a simple command invocation, it can call multiple commands at once (as shown above) and set parameters
/echo hello
hello;
/echo hello; echo world
hello; echo world
Subshells
Subshells are their own shell instances seperate from the main shell.
Commands in paranthesis are treated as a subshell
!(echo "days:"; days)
days:
7
Output of a subshell can be piped
!(echo "days:"; days) | append " text"
days: text
7 text
Very useful if you want to run a group of commands after a command fails/succeeds
!exit 0 || echo "failure:"; echo "error message:"
error message
-- the second command ran even though the first command didnt fail.
-- do this instead
!exit 0 || (echo "failure:"; echo "error message:")
Process substitution is a special subshell thats expands to the subshell's output, similiarly to how bash does it.
!echo $(days)
7
Datatypes
Different expressions have different types in lush
Due to contentDB description limits. You will have to look at the user guide for that information
Implicit type conversion
Lush implicitly converts the datatypes of command arguments you give according to what each command expects. This means that the command syntax is more flexible and intuitive to use
For example:
!teleport joe_doe to admin
"joe_doe" is converted to objectref of player with that name "admin" is converted to position of player named "admin"
Some conversions dont work unless you have the requred privileges,
i.e you cannot get the position of every player online with selectors unless
you have the lush_get_object_pos
privilege
Misc
Inlinue lua code
You can execute inline lua code and pass it as an argument to a command (or any other place).
Only players with the lush_inline_lua
privilege can do this, for security reasons
!echo `return tostring(2 + 2)`
4
lua code can take place of a command
!`context.stdout:push("hello")` | append " world"
hello world
The lua code has access to context
variable, read the API docs to learn about it.
you can ignore that if you dont want to return any info to the shell
Learn more
you can learn more about lush here:
- API rundown
- Docs for server owners
- user guide - A LOT had to be cut out of the usage section to fit the 10k character limit. Certain huge features were completely cut off from the usage section above
Credits
People that created lush:
- rstcxk - i made the thing
people from whom i have taken code:
- sfan5 - node name normalization function from worldedit, the inconsistent command parsing of worldedit is what pushed me over the edge to make lush
- Warr1024 -
lag
command from the szutilpack modpack - SkyBuilder1717 - the
v
command from Essentials
people who made things that inspired me:
- ThePython10110 - the better_commands from whom i took the idea of datatypes and some syntax
- orwell - the @-chat mod that i reimplemented
- enchant97 - the simple_commands mod from whom i took the idea of accepting strings like "noon" or "sunset" for the
time
command - ROllerozxa - the permatime mod for the idea of
--permament
flag for thetime
command