quote, shell-escape, shell-quote, and shlex are utilities designed to handle string manipulation for command-line interfaces and shell interactions. shell-quote and shlex focus on parsing and constructing shell commands securely, handling complex quoting rules. shell-escape provides basic escaping for arguments, while quote offers simple string quoting without shell-specific logic. These tools help prevent command injection vulnerabilities and ensure arguments are passed correctly to child processes.
When running system commands in Node.js, passing user input directly to exec or spawn can open security holes. The quote, shell-escape, shell-quote, and shlex packages help manage this risk by handling escaping and parsing correctly. Let's look at how they handle real-world tasks.
Parsing a command string back into arguments is common when you need to understand what a user typed.
shell-quote provides a dedicated parse method that handles quotes and escaped characters safely.
const quote = require('shell-quote');
const args = quote.parse('echo "hello world" && ls');
// Returns: [ 'echo', 'hello world', { op: '&&' }, 'ls' ]
shlex mimics Python's shlex module, focusing on POSIX-compliant splitting.
const shlex = require('shlex');
const args = shlex.split('echo "hello world"');
// Returns: [ 'echo', 'hello world' ]
shell-escape does not support parsing. It is designed only for escaping arguments into a string, so you cannot use it to read commands back.
// shell-escape: No parsing functionality available
// You must use native string methods or other libraries for parsing
quote is a simple utility and does not include parsing logic for shell commands.
// quote: No parsing functionality available
// Focused solely on wrapping strings in quotes
Turning an array of arguments into a safe command string is the most common use case.
shell-quote uses the quote function to handle special characters and spaces securely.
const quote = require('shell-quote');
const cmd = quote.quote(['echo', 'hello world', '$HOME']);
// Returns: "echo 'hello world' '$HOME'"
shell-escape joins and escapes arguments but can be less precise with complex shell operators.
const escape = require('shell-escape');
const cmd = escape(['echo', 'hello world', '$HOME']);
// Returns: "echo 'hello world' '$HOME'"
shlex is primarily for parsing, but some implementations include join helpers. However, it is not its main strength compared to shell-quote.
const shlex = require('shlex');
// shlex focuses on split, joining often requires manual mapping
const cmd = ['echo', 'hello'].map(s => `'${s}'`).join(' ');
// Manual implementation required for quoting
quote wraps a single string in quotes but does not handle arrays or shell escaping rules.
const quote = require('quote');
const str = quote('hello world');
// Returns: "'hello world'" (Simple wrapping only)
Using the wrong tool can lead to command injection vulnerabilities.
shell-quote is designed to prevent injection by properly escaping variables and operators.
const quote = require('shell-quote');
// Safely escapes $ to prevent variable expansion
const safe = quote.quote(['echo', '$USER']);
// Output: "echo '\$USER'"
shell-escape handles basic escaping but may miss edge cases in older versions.
const escape = require('shell-escape');
// Escapes arguments but less robust against complex injection
const safe = escape(['echo', '$USER']);
// Output: "echo '$USER'"
shlex helps avoid injection when parsing user input by respecting quote boundaries.
const shlex = require('shlex');
// Prevents splitting inside quotes
const args = shlex.split('rm -rf "/important/file"');
// Output: [ 'rm', '-rf', '/important/file' ]
quote offers no protection against shell injection as it does not escape shell metacharacters.
const quote = require('quote');
// Does not escape shell operators
const unsafe = quote('$(rm -rf /)');
// Output: "'$(rm -rf /)'" (Still dangerous if evaluated)
Choosing a library with active maintenance ensures security patches and compatibility.
shell-quote is widely used in the ecosystem and considered stable for production.
// shell-quote: Mature and reliable
const quote = require('shell-quote');
shell-escape has seen less activity in recent years and is often considered legacy.
// shell-escape: Legacy status, use with caution
const escape = require('shell-escape');
shlex is maintained for specific parsing needs but has a smaller community.
// shlex: Niche utility for parsing
const shlex = require('shlex');
quote is a minimal package with limited scope and updates.
// quote: Minimal utility
const quote = require('quote');
| Feature | shell-quote | shlex | shell-escape | quote |
|---|---|---|---|---|
| Parsing | ✅ Robust parse | ✅ POSIX split | ❌ None | ❌ None |
| Quoting | ✅ Array to String | ⚠️ Manual | ✅ Array to String | ⚠️ Single String |
| Security | 🔒 High | 🔒 High | ⚠️ Medium | ❌ Low |
| Use Case | Child Processes | CLI Input | Legacy Scripts | Simple Formatting |
For most Node.js applications running system commands, shell-quote is the best choice. It balances security, features, and maintenance better than the others. Use shlex if you are building a CLI tool that needs to parse complex user input strings. Avoid shell-escape and quote for security-critical tasks, as they lack the robust handling required for modern shell interactions.
Choose quote if you need a minimal utility to simply wrap a string in quotes without shell-specific parsing logic. It is suitable for basic formatting tasks where shell safety is not the primary concern, but avoid it for constructing actual shell commands due to limited escaping features.
Choose shell-escape for quick, legacy scripts where you need to escape an array of arguments into a single string. However, be aware it is less maintained and may not handle complex edge cases as well as modern alternatives, so use it only in low-risk internal tools.
Choose shell-quote for robust construction and parsing of shell commands in production environments. It handles complex quoting, environment variables, and security concerns better than simpler tools, making it the standard choice for safe child process execution.
Choose shlex if you need to parse command-line strings exactly like a POSIX shell would, especially when dealing with user input that mimics shell syntax. It is ideal for CLI tools that need to interpret complex argument structures reliably.
Safe quoting a given string without adding duplicate quotes
Install using node or bower
npm install quote --save
bower install quote --save
Use
// node
var quote = require('quote');
quote('foo'); // "foo"
quote('"foo"'); // "foo"
quote(quote('foo')); // "foo"
In the browser just use global function quote
Only single quote character is supported, default is double quotes ".
To change:
var quote = require('quote')({ quotes: '*' });
quote('foo'); // *foo*
quote('bar'); // *bar*
Because this is both Node and browser package, you need to build it using universal module definition CLI tool.
npm run build
npm test
Author: Gleb Bahmutov © 2014 @bahmutov glebbahmutov.com
License: MIT - do anything with the code, but don't blame me if it does not work.
Spread the word: tweet, star on github, etc.
Support: if you find any problems with this module, email / tweet / open issue on Github