<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/lua-sh-calling-shell-commands-as-functions-jz9tdtamj" -->

---
title: lua-sh: calling shell commands as functions | daily.dev
description: A lightweight Lua library called luash lets developers invoke shell commands as if they were native Lua functions, inspired by Python&#x27;s sh module. It uses...
canonical: https://daily.dev/posts/lua-sh-calling-shell-commands-as-functions-jz9tdtamj
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: lua-sh: calling shell commands as functions | daily.dev
og:description: A lightweight Lua library called luash lets developers invoke shell commands as if they were native Lua functions, inspired by Python&#x27;s sh module. It uses...
og:url: https://daily.dev/posts/lua-sh-calling-shell-commands-as-functions-jz9tdtamj
og:image: https://api.daily.dev/og/posts/jZ9tdtAMJ.png
og:image:alt: lua-sh: calling shell commands as functions
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# lua-sh: calling shell commands as functions

**[zserge's blog](https://daily.dev/sources/zserge)** · 6 min read · 0 upvotes · 0 comments

## Summary

A lightweight Lua library called luash lets developers invoke shell commands as if they were native Lua functions, inspired by Python's sh module. It uses Lua's metatable __index hook to intercept undefined global calls and map them to shell commands, supports piping command outputs together, passing stdin via a special table key, predefining arguments for multi-word commands like docker or git, and named options syntax. The library is under 100 lines of code, released under MIT license, and intentionally omits features like stderr redirection, glob expansion, environment variable control, and interactive I/O that Python's sh module supports.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://zserge.com/posts/luash>

## Questions this post answers

### How can I call shell commands like normal functions in Lua?

Use a metatable hook on the global table's __index so that any undefined variable is treated as a shell command lookup, returning a wrapper function that runs it via os.execute or popen. This is the approach used in the luash library, which lets you write echo('hello', 'world') instead of manually shelling out, in under 100 lines of code.

_See how developers wrap shell tools in cleaner language syntax by following Lua scripting discussions on daily.dev._

### How do you chain shell command output into another command in Lua without threads?

Buffer the output of the previous command and feed it to the next one using io.write, or write input to a temporary file and read it back with io.read('*a'), since Lua is single-threaded with blocking I/O and cannot read and write a pipe simultaneously. This avoids deadlocks that naive pipe handling would cause.

_Developers wiring shell pipelines into scripting languages can track these patterns on daily.dev._

### What features does the Lua sh module lack compared to Python's sh module?

The luash library lacks stderr redirection, subcommands as attributes like git.branch(), glob expansion (left to the shell instead), iterative output for streaming lines, stdout/stderr callbacks, interactive expect-style input handling, buffer size control, environment variable setting, and tty attachment, since Lua's standard API doesn't expose those hooks.

_Comparing lightweight scripting libraries against feature-rich ones is easier when following daily.dev._

## Similar posts on daily.dev

- [f5n : Shell scripts](https://daily.dev/posts/f5n-shell-scripts-qorivqy8y) · Lobsters · 1 upvotes · 0 comments
- [GitHub - samyeyo/clx: A cross-platform ahead-of-time Lua compiler and runtime, using C\+\+20 backend](https://daily.dev/posts/github---samyeyo-clx-a-cross-platform-ahead-of-time-lua-compiler-and-runtime-using-c-20-backend-oojs91kf1) · Hacker News · 0 upvotes · 0 comments
- [Lua can be a really cool HTML templating engine](https://daily.dev/posts/lua-can-be-a-really-cool-html-templating-engine-pwy47nz8p) · Lobsters · 0 upvotes · 0 comments
- [nlsh: talk to your terminal in natural language](https://daily.dev/posts/nlsh-talk-to-your-terminal-in-natural-language-5itrwnoa9) · Product Hunt · 2 upvotes · 0 comments

---

Tags: [#open-source](https://daily.dev/tags/open-source), [#shell](https://daily.dev/tags/shell), [#lua](https://daily.dev/tags/lua)

[View this post on daily.dev](https://daily.dev/posts/lua-sh-calling-shell-commands-as-functions-jz9tdtamj)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"lua-sh: calling shell commands as functions","url":"https://daily.dev/posts/lua-sh-calling-shell-commands-as-functions-jz9tdtamj","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/lua-sh-calling-shell-commands-as-functions-jz9tdtamj"},"datePublished":"2026-08-23T10:20:13.267Z","dateModified":"2026-08-23T10:20:49.399Z","description":"A lightweight Lua library called luash lets developers invoke shell commands as if they were native Lua functions, inspired by Python's sh module. It uses...","image":"https://media.daily.dev/image/upload/s--VDukGCjf--/f_auto/v1722860399/public/Placeholder%2002","thumbnailUrl":"https://media.daily.dev/image/upload/s--VDukGCjf--/f_auto/v1722860399/public/Placeholder%2002","isAccessibleForFree":true,"articleSection":"zserge's blog","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"zserge's blog","logo":"https://media.daily.dev/image/upload/s--KQnFBOIT--/f_auto,q_auto/v1787480407/logos/zserge","url":"https://daily.dev/sources/zserge"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/lua-sh-calling-shell-commands-as-functions-jz9tdtamj","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"open-source,shell,lua","timeRequired":"PT6M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"zserge's blog","item":"https://daily.dev/sources/zserge"},{"@type":"ListItem","position":3,"name":"lua-sh: calling shell commands as functions"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/lua-sh-calling-shell-commands-as-functions-jz9tdtamj#faq","mainEntity":[{"@type":"Question","name":"How can I call shell commands like normal functions in Lua?","acceptedAnswer":{"@type":"Answer","text":"Use a metatable hook on the global table's __index so that any undefined variable is treated as a shell command lookup, returning a wrapper function that runs it via os.execute or popen. This is the approach used in the luash library, which lets you write echo('hello', 'world') instead of manually shelling out, in under 100 lines of code. See how developers wrap shell tools in cleaner language syntax by following Lua scripting discussions on daily.dev."}},{"@type":"Question","name":"How do you chain shell command output into another command in Lua without threads?","acceptedAnswer":{"@type":"Answer","text":"Buffer the output of the previous command and feed it to the next one using io.write, or write input to a temporary file and read it back with io.read('*a'), since Lua is single-threaded with blocking I/O and cannot read and write a pipe simultaneously. This avoids deadlocks that naive pipe handling would cause. Developers wiring shell pipelines into scripting languages can track these patterns on daily.dev."}},{"@type":"Question","name":"What features does the Lua sh module lack compared to Python's sh module?","acceptedAnswer":{"@type":"Answer","text":"The luash library lacks stderr redirection, subcommands as attributes like git.branch(), glob expansion (left to the shell instead), iterative output for streaming lines, stdout/stderr callbacks, interactive expect-style input handling, buffer size control, environment variable setting, and tty attachment, since Lua's standard API doesn't expose those hooks. Comparing lightweight scripting libraries against feature-rich ones is easier when following daily.dev."}}]}
```

