### Example: Build Tools Configuration Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/configuration.md This configuration enables the execution of common build tool commands such as cargo build, cargo test, and npm install. ```json { "permissions": [ { "identifier": "shell:allow-execute", "allow": [ { "name": "build-project", "cmd": "cargo", "args": ["build", "--release"] }, { "name": "run-tests", "cmd": "cargo", "args": ["test", "--", { "validator": ".*" }] }, { "name": "npm-install", "cmd": "npm", "args": ["install"] } ] } ] } ``` -------------------------------- ### Open File Example Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/api-reference/open.md Demonstrates opening a local file with its default associated application. ```APIDOC ## Open File ### Description Open file with default application ### Code ```typescript import { open } from '@tauri-apps/plugin-shell'; await open('/path/to/document.pdf'); ``` ``` -------------------------------- ### SpawnOptions Examples Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/types.md Illustrates how to use SpawnOptions when creating a command. Shows setting cwd, env, encoding, and clearing the environment. ```typescript const cmd = Command.create('ls', '-la', { cwd: '/home/user', env: { PATH: '/usr/bin:/bin' }, encoding: 'utf-8' }); ``` ```typescript const raw = Command.create('xxd', 'file.bin', { encoding: 'raw' // Returns Uint8Array }); ``` ```typescript const noEnv = Command.create('env', { env: null // Child process has empty environment }); ``` -------------------------------- ### Example: Sidecar with Arguments Configuration Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/configuration.md Configure a sidecar to accept specific arguments using validators. This example shows a sidecar named 'my-tool' that accepts 'process', 'analyze', or 'generate' as the first argument, followed by a valid file path. ```json { "build": { "beforeDevCommand": "cargo build --release --target-dir target" }, "bundle": { "externalBin": [ "target/release/my-tool" ] }, "permissions": [ { "identifier": "shell:allow-execute", "allow": [ { "name": "my-tool", "sidecar": true, "args": [ { "validator": "process|analyze|generate" }, { "validator": "[a-zA-Z0-9._/-]+" } ] } ] } ] } ``` -------------------------------- ### Open Default Browser Example Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/api-reference/open.md Demonstrates how to open a URL using the system's default browser. ```APIDOC ## Open Default Browser ### Description Open URL with system default browser ### Code ```typescript import { open } from '@tauri-apps/plugin-shell'; await open('https://github.com/tauri-apps/tauri'); ``` ``` -------------------------------- ### Rust Examples Overview Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/README.md This section provides examples of using the ShellExt trait and related functionalities in Rust. ```rust // Using the ShellExt trait use tauri_plugin_shell::ShellExt; use std::process::Command; fn build_command() -> Command { Command::new("echo").arg("hello world") } fn main() { let mut command = build_command(); // Use ShellExt methods here, e.g., command.execute_with_output() } ``` ```rust // Building commands use std::process::Command; fn create_process() -> Command { Command::new("ls") .args(&["-l", "-a"]) .current_dir("/tmp") } fn main() { let command = create_process(); // Execute the command } ``` ```rust // Streaming with async/await use tauri_plugin_shell::Command as ShellCommand; #[tokio::main] async fn stream_output() -> Result<(), Box> { let mut command = ShellCommand::new("your-command"); let mut stream = command.spawn()?.stream_stdout().await?; while let Some(line) = stream.next_line().await? { println!("stdout: {}", line); } Ok(()) } ``` ```rust // Process lifecycle management use tauri_plugin_shell::Command as ShellCommand; #[tokio::main] async fn manage_process() -> Result<(), Box> { let mut command = ShellCommand::new("long-running-command"); let mut child = command.spawn()?; // Do some work... // Kill the process child.kill().await?; Ok(()) } ``` ```rust // Environment variable handling use tauri_plugin_shell::Command as ShellCommand; use std::env; #[tokio::main] async fn with_env_vars() -> Result<(), Box> { let mut command = ShellCommand::new("printenv"); command.env("MY_VAR", "my_value"); // You can also inherit environment variables // command.env_remove("VAR_TO_REMOVE"); let output = command.execute().await?; println!("{}", output.stdout); Ok(()) } ``` ```rust // Error matching use tauri_plugin_shell::{Command, CommandError}; #[tokio::main] async fn handle_errors() -> Result<(), ()> { match Command::new("invalid-command").execute().await { Ok(output) => { println!("Success: {}", output.stdout); Ok(()) } Err(CommandError::Io(err)) => { eprintln!("IO Error: {}", err); Err(()) } Err(CommandError::Tauri(err)) => { eprintln!("Tauri Error: {}", err); Err(()) } Err(CommandError::RemoteError(err)) => { eprintln!("Remote Error: {}", err); Err(()) } } } ``` ```rust // Advanced encoding support use tauri_plugin_shell::Command as ShellCommand; #[tokio::main] async fn advanced_encoding() -> Result<(), Box> { let mut command = ShellCommand::new("your-command"); // Specify encoding if needed, e.g., for non-UTF8 output // command.encoding("gbk"); let output = command.execute().await?; println!("{}", output.stdout); Ok(()) } ``` -------------------------------- ### Open Email Client Example Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/api-reference/open.md Demonstrates opening the default email client with a mailto link. ```APIDOC ## Open Email Client ### Description Open email client with mailto link ### Code ```typescript import { open } from '@tauri-apps/plugin-shell'; await open('mailto:user@example.com'); ``` ``` -------------------------------- ### Open Phone Dialer Example Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/api-reference/open.md Shows how to open the phone dialer with a tel link. ```APIDOC ## Open Phone Dialer ### Description Open phone dialer with tel link ### Code ```typescript import { open } from '@tauri-apps/plugin-shell'; await open('tel:+1234567890'); ``` ``` -------------------------------- ### Configure Command Execution with Any Arguments Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/configuration.md Example of configuring a command to allow any arguments. No validation is performed on the arguments provided. ```json { "name": "ls", "cmd": "ls", "args": true } ``` ```typescript // All valid: Command.create('ls'); Command.create('ls', '-la'); Command.create('ls', ['-la', '/home']); ``` -------------------------------- ### Open with Specific Browser Example Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/api-reference/open.md Shows how to open a URL with a specific browser application. ```APIDOC ## Open with Specific Browser ### Description Open with a specified browser application. ### Code ```typescript import { open } from '@tauri-apps/plugin-shell'; // Open with Firefox await open('https://example.com', 'firefox'); // Open with Chrome await open('https://example.com', 'google chrome'); // Open with Safari (macOS) await open('https://example.com', 'safari'); ``` ``` -------------------------------- ### JavaScript Examples Overview Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/README.md This section outlines the various JavaScript functionalities available for interacting with shell commands. ```javascript // Basic command execution import { Command } from 'tauri-plugin-shell'; async function runCommand() { const command = new Command('echo', ['hello world']); const output = await command.execute(); console.log(output.stdout); } ``` ```javascript // Streaming output with events import { Command } from 'tauri-plugin-shell'; async function streamCommand() { const command = new Command('your-command', ['arg1']); const unlisten = await command.stream( (output) => { console.log('stdout:', output.stdout); console.log('stderr:', output.stderr); } ); // To stop listening: // unlisten(); } ``` ```javascript // Writing to stdin import { Command } from 'tauri-plugin-shell'; async function writeToStdin() { const command = new Command('your-command'); await command.spawn(); await command.write('input to stdin\n'); await command.kill(); } ``` ```javascript // Error handling import { Command } from 'tauri-plugin-shell'; async function handleError() { try { const command = new Command('non-existent-command'); await command.execute(); } catch (error) { console.error('Command failed:', error); } } ``` ```javascript // Using with environment variables import { Command } from 'tauri-plugin-shell'; async function withEnv() { const command = new Command('printenv', ['MY_VAR'], { env: { MY_VAR: 'my_value' } }); const output = await command.execute(); console.log(output.stdout); } ``` ```javascript // Working directory configuration import { Command } from 'tauri-plugin-shell'; import path from 'path'; async function withCwd() { const command = new Command('pwd', [], { cwd: path.resolve('../some-directory') }); const output = await command.execute(); console.log(output.stdout); } ``` ```javascript // URL/file opening import { open } from 'tauri-plugin-shell'; async function openUrl() { await open('https://tauri.app'); await open('/path/to/your/file.txt'); } ``` -------------------------------- ### Custom Regex Examples for Shell Open Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/api-reference/open.md Provides examples of custom regex patterns that can be used to configure the shell open API in tauri.conf.json for specific URL formats. ```json { "open": "https?://\.github\.com(/.*)?", "open": "^file://(/home/user)?", "open": "ftp://.*" } ``` -------------------------------- ### Error Handling Example Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/api-reference/open.md Illustrates how to handle potential errors when using the open() function. ```APIDOC ## Error Handling ### Description Handle potential errors during the open operation. ### Code ```typescript import { open } from '@tauri-apps/plugin-shell'; try { await open('https://example.com'); } catch (error) { console.error(`Failed to open URL: ${error}`); } ``` ``` -------------------------------- ### Create Command with Valid Arguments Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/quick-start.md Example of creating a command with arguments that conform to the specified validation pattern. Uppercase characters are not allowed in this example. ```typescript // Valid: Command.create('cmd', ['--flag', 'abc123']); // Invalid: Command.create('cmd', ['--flag', 'ABC']); // Uppercase not allowed ``` -------------------------------- ### Configure Command with Raw Regex for Output File Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/configuration.md Example of configuring a command to accept an output file name, using a raw regex validator for the filename. ```json { "name": "curl-https", "cmd": "curl", "args": ["--output", { "validator": "[a-zA-Z0-9._-]+", "raw": true }] } ``` -------------------------------- ### JavaScript spawn() Event Sequence Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/module-overview.md Illustrates the event flow when using `Command.spawn()` in JavaScript, from process start to termination, including stdout/stderr streaming. ```text Command.spawn() ↓ [Child process starts] ↓ emit Stdout/Stderr events (streaming) ↓ emit close event with TerminatedPayload ↓ [Process terminated] ``` -------------------------------- ### Example: Restricted Open URLs Configuration Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/configuration.md This configuration restricts the 'open' command to only allow URLs starting with 'http://', 'https://', 'mailto:', or 'tel:', and further filters by domain or phone number format. ```json { "plugins": { "shell": { "open": "^(https?://|mailto:|tel:)(github\\.com|.*example\\.com|[+\\d-]+).*" } }, "permissions": [ { "identifier": "shell:allow-open" } ] } ``` -------------------------------- ### Configure Command Execution with No Arguments Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/configuration.md Example of configuring a command to only allow execution without any arguments. This is useful for simple commands like 'whoami'. ```json { "name": "whoami", "cmd": "whoami", "args": false } ``` ```typescript // Valid: Command.create('whoami'); // Invalid: Command.create('whoami', ['--version']); ``` -------------------------------- ### Install JavaScript Guest Bindings Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/README.md Instructions for installing the JavaScript guest bindings for the Tauri Plugin Shell using common package managers like pnpm, npm, or yarn. ```sh pnpm add @tauri-apps/plugin-shell # or npm add @tauri-apps/plugin-shell # or yarn add @tauri-apps/plugin-shell ``` -------------------------------- ### Configure Command with Fixed and Variable Arguments Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/configuration.md Example of configuring a command to accept specific fixed arguments and a variable argument validated by a regex pattern. ```json { "name": "git-commit", "cmd": "git", "args": ["commit", "-m", { "validator": "\S+" }] } ``` ```typescript // Valid: Command.create('git-commit', ['commit', '-m', 'my message']); // Invalid: Command.create('git-commit', ['commit', 'my message']); // Missing -m Command.create('git-commit', ['add', '.']); // Wrong command ``` -------------------------------- ### Install Tauri Shell Plugin Package (npm/yarn/pnpm) Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/configuration.md Install the @tauri-apps/plugin-shell package using your preferred package manager. This makes the shell plugin's JavaScript API available in your frontend code. ```bash npm install @tauri-apps/plugin-shell # or yarn add @tauri-apps/plugin-shell # or pnpm add @tauri-apps/plugin-shell ``` -------------------------------- ### Accessing Shell Plugin Instance Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/api-reference/rust-shell-ext.md Demonstrates how to get a reference to the Shell plugin instance using the `shell()` method from an AppHandle. ```rust use tauri::{AppHandle, Runtime}; use tauri_plugin_shell::ShellExt; fn my_function(app: &AppHandle) { let shell = app.shell(); // Use shell to create commands } ``` -------------------------------- ### Handle Command Output Data Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/types.md Examples demonstrating how to listen for 'data' events on Command's stdout, both for string output and raw byte arrays. The 'encoding' option in Command.create determines the payload type. ```typescript const cmd = Command.create('cat', 'file.txt'); cmd.stdout.on('data', (line: string) => { console.log(`Line: ${line}`); }); const rawCmd = Command.create('xxd', 'binary.bin', { encoding: 'raw' }); rawCmd.stdout.on('data', (bytes: Uint8Array) => { console.log(`Bytes:`, bytes); }); ``` -------------------------------- ### Example: Git Operations Configuration Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/configuration.md This configuration allows executing various Git commands, including status, commit with a message validator, and push with a branch name validator. ```json { "permissions": [ { "identifier": "shell:allow-execute", "allow": [ { "name": "git-status", "cmd": "git", "args": ["status"] }, { "name": "git-commit", "cmd": "git", "args": ["commit", "-m", { "validator": "^.{1,100}$" }] }, { "name": "git-push", "cmd": "git", "args": ["push", "origin", { "validator": "[a-z0-9\\-_]+" }] } ] }, { "identifier": "shell:allow-open" } ] } ``` -------------------------------- ### Configure Command with Python Script Argument Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/configuration.md Example of configuring a command to accept a Python script file name as an argument, validated by a regex. ```json { "name": "python-script", "cmd": "python3", "args": [{ "validator": ".+\\.py$" }] } ``` -------------------------------- ### JavaScript Scope Check Example Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/scopes-and-security.md Demonstrates how to execute a command in JavaScript and catch scope validation errors. This is useful for verifying if a command is allowed at runtime. ```typescript try { const output = await Command.create('unauthorized').execute(); } catch (error) { console.error('Scope validation failed:', error); // Error message will indicate which permission is missing } ``` -------------------------------- ### Configure Command with Regex Argument Validator Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/configuration.md Example of configuring a command to accept a specific argument that must match a given regular expression pattern. ```json { "name": "run-npm", "cmd": "npm", "args": ["run", { "validator": "[a-z]+" }] } ``` -------------------------------- ### Spawn Command and Handle Events Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/api-reference/rust-command.md Use spawn to start a command as a child process. It returns a receiver for command events like stdout, stderr, and termination, along with a handle to the child process for interaction. ```rust pub fn spawn(self) -> crate::Result<(Receiver, CommandChild)> ``` ```rust use tauri_plugin_shell::process::CommandEvent; #[tauri::command] async fn run_command(app: AppHandle) -> Result<(), String> { let (mut rx, mut child) = app .shell() .command("cat") .spawn() .map_err(|e| e.to_string())?; // Write to stdin child.write(b"hello\n").map_err(|e| e.to_string())?; // Receive events while let Some(event) = rx.recv().await { match event { CommandEvent::Stdout(line) => { let text = String::from_utf8_lossy(&line); println!("Output: {}", text); } CommandEvent::Stderr(line) => { let text = String::from_utf8_lossy(&line); eprintln!("Error: {}", text); } CommandEvent::Terminated(payload) => { println!("Exit code: {:?}", payload.code); break; } CommandEvent::Error(err) => { eprintln!("Process error: {}", err); } } } Ok(()) } ``` -------------------------------- ### CommandChild Methods Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/api-reference/rust-command.md Provides methods to interact with a running child process, such as writing to stdin, killing the process, and getting its PID. ```rust pub struct CommandChild { // Fields are private } impl CommandChild { pub fn write(&mut self, buf: &[u8]) -> crate::Result<()> { ... } pub fn kill(self) -> crate::Result<()> { ... } pub fn pid(&self) -> u32 { ... } } ``` -------------------------------- ### Rust Scope Check Example Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/scopes-and-security.md Shows how to handle scope validation errors in Rust when attempting to execute a command. It specifically catches the `ProgramNotAllowed` error. ```rust match app.shell().command("unauthorized").output().await { Err(Error::ProgramNotAllowed(path)) => { eprintln!("Program not allowed: {:?}", path); } // Handle other cases } ``` -------------------------------- ### Rust Command Handler for Listing Files Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/quick-start.md Implement a Rust command handler in `lib.rs` or `main.rs` to execute shell commands. This example defines a `list_files` command that uses the shell plugin to run 'ls -la' and returns the output. ```rust use tauri::AppHandle; use tauri_plugin_shell::ShellExt; #[tauri::command] async fn list_files(app: AppHandle) -> Result { let output = app .shell() .command("list-files") .output() .await .map_err(|e| e.to_string())?; String::from_utf8(output.stdout).map_err(|e| e.to_string()) } ``` -------------------------------- ### React Component for Shell Interaction Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/quick-start.md Create a React component to interact with the shell plugin. This example provides buttons to trigger the 'list_files' command and open an external URL using the `open` function from the plugin. ```typescript import { Command, open } from '@tauri-apps/plugin-shell'; import { invoke } from '@tauri-apps/api/core'; export function Shell() { const [output, setOutput] = useState(''); const listFiles = async () => { try { const result = await invoke('list_files'); setOutput(result); } catch (error) { setOutput(`Error: ${error}`); } }; const openGithub = async () => { try { await open('https://github.com'); } catch (error) { console.error(error); } }; return (
{output}
); } ``` -------------------------------- ### Execute a Program and Get Output (TypeScript) Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/INDEX.md Executes an external program ('ls') and waits for its completion, then logs the standard output. This is a simple way to run a command and capture its entire output. ```typescript const output = await Command.create('ls').execute(); console.log(output.stdout); ``` -------------------------------- ### Tauri Configuration for Shell Plugin Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/quick-start.md Configure the shell plugin in `tauri.conf.json` to allow specific commands and open patterns. This example enables executing 'ls' and 'echo' commands and opening URLs matching the specified pattern. ```json { "plugins": { "shell": { "open": "^https?://(github\\.com|example\\.com).*" } }, "permissions": [ { "identifier": "shell:allow-execute", "allow": [ { "name": "list-files", "cmd": "ls", "args": ["-la"] }, { "name": "echo", "cmd": "echo", "args": true } ] }, { "identifier": "shell:allow-open" } ] } ``` -------------------------------- ### Handle Unknown Program Name Errors in TypeScript Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/errors.md This TypeScript example shows how to use the `open` API with a custom browser. It highlights the error that occurs if an unrecognized browser name is provided. Only use predefined or valid browser names. ```typescript await open('https://example.com', 'invalid-browser'); // Error: unknown program name: invalid-browser ``` -------------------------------- ### Remove Specific Listener Example Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/api-reference/event-emitter.md Provides an example of how to register a listener and then remove it using the `off` method. ```typescript const handler = (msg: string) => console.log(msg); emitter.on('message', handler); emitter.off('message', handler); // Listener is removed ``` -------------------------------- ### Create and Execute a Command Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/api-reference/command.md Demonstrates how to create a simple command using `Command.create` and execute it. It also shows how to use the 'raw' encoding option for binary output. ```typescript import { Command } from '@tauri-apps/plugin-shell'; const command = Command.create('echo', 'hello world'); const output = await command.execute(); console.log(output.stdout); // 'hello world' const withRaw = Command.create('node', 'script.js', { encoding: 'raw' }); // Returns Uint8Array instead of string ``` -------------------------------- ### Creating a System Command Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/api-reference/rust-shell-ext.md Shows how to create a command for a system program using the `command()` method. ```rust let cmd = app.shell().command("ls").arg("-la"); ``` -------------------------------- ### Install Tauri Plugin Shell (Rust) Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/README.md This snippet shows how to add the Tauri Plugin Shell to your Rust project's Cargo.toml file. It supports installation from crates.io or directly from a Git repository. ```toml [dependencies] tauri-plugin-shell = "2.0.0" # alternatively with Git: tauri-plugin-shell = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2" } ``` -------------------------------- ### Executing a Command and Handling Output Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/types.md Demonstrates how to execute a command using Command.create().execute() and access its stdout, stderr, and exit code. Handles both successful execution and error cases. ```typescript import { Command } from '@tauri-apps/plugin-shell'; const result = await Command.create('echo', 'hello').execute(); if (result.code === 0) { console.log(result.stdout); // 'hello' } const errResult = await Command.create('sh', '-c', 'exit 42').execute(); console.log(errResult.code); // 42 console.log(errResult.stderr); // '' const sigResult = await Command.create('sleep', '100').execute(); // On Unix: code might be null, signal might be 15 (SIGTERM) ``` -------------------------------- ### Configure Sidecar Build and Bundle Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/scopes-and-security.md Add sidecar program configuration to your `Cargo.toml` or build process. The `externalBin` array lists the sidecar binaries to be bundled. ```json { "build": { "beforeDevCommand": "./build-sidecar.sh", "beforeBuildCommand": "./build-sidecar.sh" }, "bundle": { "externalBin": [ "path/to/sidecar-binary" ] } } ``` -------------------------------- ### Least Privilege: Basic Command Execution Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/scopes-and-security.md Demonstrates the difference between granting broad command execution and specific command execution. Use specific commands for better security. ```json { "name": "anything", "cmd": "sh", "args": true } ``` ```json { "name": "list-files", "cmd": "ls", "args": ["-la"] } ``` -------------------------------- ### Migrate to Tauri Plugin Opener Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/api-reference/open.md Demonstrates the recommended way to open URLs in newer Tauri projects (2.1.0+) using the dedicated '@tauri-apps/plugin-opener' package. ```typescript import { open } from '@tauri-apps/plugin-opener'; await open('https://example.com'); ``` -------------------------------- ### Using `open` with Valid Paths Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/errors.md Demonstrates how to use the `open` command with paths that conform to the default validation regex, including URLs, mailto, and tel links. ```typescript await open('https://example.com'); await open('mailto:user@example.com'); await open('tel:+1234567890'); ``` -------------------------------- ### Rust Main Crate Entry Point Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/module-overview.md Shows the entry point function for the Rust crate, used for initializing the plugin. ```rust pub fn init() -> TauriPlugin> ``` -------------------------------- ### Execute Command and Get Status Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/api-reference/rust-command.md Use status to run a command and wait for its completion, returning only the exit status. Stdout and stderr are discarded. ```rust pub async fn status(self) -> crate::Result ``` ```rust #[tauri::command] async fn check_command(app: AppHandle) -> Result { let status = app .shell() .command("test") .arg("-f") .arg("/etc/passwd") .status() .await .map_err(|e| e.to_string())?; Ok(status.success()) } ``` -------------------------------- ### Execute Command in JavaScript Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/configuration.md Demonstrates how to execute a command with arguments in JavaScript using the Command API. Includes error handling for disallowed commands. ```typescript try { const result = await Command.create('my-cmd', ['arg1']).execute(); } catch (error) { console.error('Not allowed:', error); } ``` -------------------------------- ### Get Child Process ID Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/api-reference/child.md Retrieve the unique process identifier of a spawned child process. This is useful for logging or referencing the specific process. ```typescript const child = await command.spawn(); console.log(`Child process ID: ${child.pid}`); ``` -------------------------------- ### Command.create Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/api-reference/command.md Creates a command to execute a given program with optional arguments and spawn options. The encoding option determines if the output is a string or Uint8Array. ```APIDOC ## Command.create ### Description Creates a command to execute the given program with optional arguments and spawn options. The encoding option determines if the output is a string or Uint8Array. ### Method Signature ```typescript static create(program: string): Command static create(program: string, args?: string | string[], options?: SpawnOptions & { encoding: 'raw' }): Command static create(program: string, args?: string | string[], options?: SpawnOptions): Command ``` ### Parameters #### Path Parameters * **program** (string) - Required - The program to execute. Must be configured in your project's capabilities. * **args** (string | string[]) - Optional - Optional arguments to pass to the program. Can be a single string or array of strings. Defaults to `[]`. * **options** (SpawnOptions & { encoding?: 'raw' }) - Optional - Spawn options including cwd, env, and encoding. When encoding is 'raw', returns Uint8Array; otherwise string. ### Returns `Command` or `Command` depending on encoding option. ### Example ```typescript import { Command } from '@tauri-apps/plugin-shell'; const command = Command.create('echo', 'hello world'); const output = await command.execute(); console.log(output.stdout); // 'hello world' const withRaw = Command.create('node', 'script.js', { encoding: 'raw' }); // Returns Uint8Array instead of string ``` ``` -------------------------------- ### SpawnOptions Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/types.md Options for spawning a child process, including current working directory, environment variables, and character encoding for output. ```APIDOC ## SpawnOptions ### Description Options for spawning a child process. ### Interface Definition ```typescript interface SpawnOptions { /** Current working directory for the child process. */ cwd?: string /** Environment variables. Set to `null` to clear the process env. */ env?: Record | null /** Character encoding for stdout/stderr. Defaults to UTF-8. */ encoding?: string } ``` ### Fields | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | cwd | `string` | no | — | Current working directory. Defaults to parent process cwd. | | env | `Record \| null` | no | — | Environment variables to inherit. When `null`, clears all env vars (child process starts with empty env). When undefined (omitted), inherits from parent. | | encoding | `string` | no | — | Character encoding for stdout/stderr. Common values: `'utf-8'` (default), `'utf-16'`, `'iso-8859-1'`, `'raw'` (returns Uint8Array). Use encoding_rs label format. | ### Used By `Command.create()`, `Command.sidecar()` ### Example ```typescript const cmd = Command.create('ls', '-la', { cwd: '/home/user', env: { PATH: '/usr/bin:/bin' }, encoding: 'utf-8' }); const raw = Command.create('xxd', 'file.bin', { encoding: 'raw' // Returns Uint8Array }); const noEnv = Command.create('env', { env: null // Child process has empty environment }); ``` ``` -------------------------------- ### spawn() Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/api-reference/command.md Executes the command as a child process, returning a handle to it. The process runs in the background and emits events for stdout, stderr, and termination. ```APIDOC ## spawn() ### Description Executes the command as a child process, returning a handle to it. The process runs in the background and emits events for stdout, stderr, and termination. ### Method `spawn()` ### Returns A promise resolving to a `Child` process handle with a `pid` property and methods to write to stdin and kill the process. ### Throws - Command rejected if program not configured in capabilities. - `Error` if the process fails to spawn. ### Example ```typescript import { Command } from '@tauri-apps/plugin-shell'; const command = Command.create('tail', '-f', { cwd: '/var/log' }); command.on('close', data => { console.log(`Process exited with code ${data.code} and signal ${data.signal}`); }); command.on('error', error => { console.error(`Command failed: ${error}`); }); command.stdout.on('data', line => { console.log(`stdout: ${line}`); }); command.stderr.on('data', line => { console.log(`stderr: ${line}`); }); const child = await command.spawn(); console.log(`Process PID: ${child.pid}`); // Later: write to stdin await child.write('some input\n'); // Or kill the process await child.kill(); ``` ``` -------------------------------- ### Execute a Program and Get Output (Rust) Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/INDEX.md Executes an external program ('ls') and retrieves its output. The output is then converted from bytes to a UTF-8 string for printing. ```rust let output = app.shell().command("ls").output().await?; println!("{}", String::from_utf8(output.stdout)?); ``` -------------------------------- ### Configure and Execute Node.js Scripts Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/quick-start.md Define a configuration for running Node.js scripts, such as 'npm run build'. The 'args' can specify script names or other npm arguments. ```json { "name": "build", "cmd": "npm", "args": ["run", { "validator": "[a-z-]+" }] } ``` -------------------------------- ### Spawn a Command with Event Handling Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/quick-start.md Spawn a command and listen for stdout, stderr, and close events. Logs the process PID. ```typescript import { Command } from '@tauri-apps/plugin-shell'; const command = Command.create('list-files'); command.stdout.on('data', (line) => { console.log('Output:', line); }); command.stderr.on('data', (line) => { console.error('Error:', line); }); command.on('close', (data) => { console.log(`Exit code: ${data.code}`); }); const child = await command.spawn(); console.log(`Process PID: ${child.pid}`); ``` -------------------------------- ### Accessing Command via ShellExt Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/api-reference/rust-command.md Demonstrates how to obtain a `Command` instance using the `ShellExt` trait within a Tauri application context. This is the recommended way to create commands. ```rust use tauri_plugin_shell::ShellExt; let cmd = app.shell().command("ls"); ``` -------------------------------- ### Handle Command Termination Event Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/types.md Example of how to attach a listener to the 'close' event of a Command to log the exit code or termination signal. This demonstrates the practical usage of the TerminatedPayload. ```typescript const command = Command.create('my-program'); command.on('close', (data: TerminatedPayload) => { if (data.signal !== null) { console.log(`Terminated by signal ${data.signal}`); } else { console.log(`Exit code: ${data.code}`); } }); await command.spawn(); ``` -------------------------------- ### Creating a Sidecar Command Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/api-reference/rust-shell-ext.md Demonstrates creating a command for a sidecar program using the `sidecar()` method. Ensure the sidecar is configured in `tauri.conf.json`. ```rust let cmd = app.shell().sidecar("my-sidecar")?; ``` -------------------------------- ### JavaScript API - Command Class Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/INDEX.md Provides functionality to spawn and execute system commands. It allows for capturing output and managing child processes. ```APIDOC ## Command ### Description Spawn and execute system commands, with options to capture output and manage the child process. ### Documentation Link [Read](api-reference/command.md) ``` -------------------------------- ### Monitor Process with Timeout in Rust Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/api-reference/rust-shell-ext.md Spawn a long-running process and monitor its events, with a built-in timeout. This example uses `tokio::select!` to concurrently wait for process events or a timeout. ```rust use tauri::{AppHandle, Runtime}; use tauri_plugin_shell::ShellExt; use tokio::time::{sleep, Duration}; #[tauri::command] async fn long_running_task(app: AppHandle) -> Result<(), String> { let (mut rx, _child) = app .shell() .command("long-running-program") .spawn() .map_err(|e| e.to_string())?; let timeout = sleep(Duration::from_secs(30)); tokio::pin!(timeout); loop { tokio::select! { Some(event) = rx.recv() => { match event { tauri_plugin_shell::process::CommandEvent::Terminated(payload) => { if payload.code == Some(0) { return Ok(()) } else { return Err(format!("Process failed with code {:?}", payload.code)); } } tauri_plugin_shell::process::CommandEvent::Error(err) => { return Err(err); } _ => {} } } _ = &mut timeout => { return Err("Process timeout".to_string()); } } } } ``` -------------------------------- ### Create and Execute a Sidecar Command Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/api-reference/command.md Shows how to create and execute a command for a sidecar binary. This is useful for running embedded external binaries configured in `tauri.conf.json`. ```typescript import { Command } from '@tauri-apps/plugin-shell'; const sidecar = Command.sidecar('my-sidecar-binary'); const output = await sidecar.execute(); console.log(`Exit code: ${output.code}`); ``` -------------------------------- ### Configuring Argument Validation for Commands Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/errors.md Define specific arguments and validation rules for commands in `tauri.conf.json`. This example allows the `git commit` command with a message that matches a non-whitespace pattern. ```json { "permissions": [ { "identifier": "shell:allow-execute", "allow": [ { "name": "run-git-commit", "cmd": "git", "args": ["commit", "-m", { "validator": "\\S+" }] } ] } ] } ``` -------------------------------- ### Configure Shell Open Scope in tauri.conf.json Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/api-reference/open.md Shows how to enable the shell open API in your Tauri application's configuration file. This example enables the API without a custom regex. ```json { "plugins": { "shell": { "open": true } } } ``` -------------------------------- ### Configure Command Argument Validation Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/quick-start.md Define argument validation patterns in `tauri.conf.json` to ensure commands receive arguments in the expected format. This example uses a regex to allow only lowercase alphanumeric characters. ```json { "name": "cmd", "cmd": "program", "args": ["--flag", { "validator": "[a-z0-9]+" }] } ``` -------------------------------- ### Handle Unknown Encoding Errors in TypeScript Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/errors.md This TypeScript example demonstrates creating a command with an invalid encoding specified. It shows the resulting error and suggests using `'raw'` for the encoding to receive a `Uint8Array`. ```typescript const cmd = Command.create('ls', { encoding: 'invalid-encoding' }); // Error: unknown encoding invalid-encoding ``` -------------------------------- ### Allow Local Files with Custom Regex Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/scopes-and-security.md Configure the `open` scope to allow local file paths. This regex pattern permits URLs starting with `file://` followed by a path structure. ```json { "open": "^file://(/[a-zA-Z0-9._/-]+)?$" } ``` -------------------------------- ### Configure and Execute Git Commands Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/quick-start.md Define and execute Git commands like 'status' and 'commit' using the Shell plugin. The 'args' can include string literals or validators for dynamic input. ```json { "name": "git-status", "cmd": "git", "args": ["status"] } ``` ```json { "name": "git-commit", "cmd": "git", "args": ["commit", "-m", { "validator": ".+" }] } ``` -------------------------------- ### Execute a Command and Collect Output in Rust Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/api-reference/rust-shell-ext.md This snippet demonstrates how to execute a command and wait for its completion, collecting all standard output. It checks the exit status to determine success or failure. ```rust use tauri::{AppHandle, Runtime}; use tauri_plugin_shell::ShellExt; #[tauri::command] async fn get_current_user(app: AppHandle) -> Result { let output = app .shell() .command("whoami") .output() .await .map_err(|e| e.to_string())?; if output.status.success() { Ok(String::from_utf8_lossy(&output.stdout).trim().to_string()) } else { Err("Failed to get current user".to_string()) } } ``` -------------------------------- ### Use Command API (JavaScript) Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/README.md An example of using the Command API from the Tauri Plugin Shell in JavaScript. This allows you to create and execute shell commands from your frontend code. ```javascript import { Command } from '@tauri-apps/plugin-shell' Command.create('git', ['commit', '-m', 'the commit message']) ``` -------------------------------- ### API Reference - open() Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/README.md Documentation for the open() function, used to open URLs or files with their default application. ```APIDOC ## open(target: string): Promise ### Description Opens the specified URL or file path using the system's default application. ### Parameters - **`target`** (string) - Required - The URL or file path to open. ### Usage ```javascript import { open } from 'tauri-plugin-shell'; // Open a URL await open('https://tauri.app'); // Open a file await open('/path/to/your/document.pdf'); ``` ``` -------------------------------- ### Command Builder Methods Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/module-overview.md Defines methods for constructing and executing shell commands, including setting arguments, environment variables, and working directory. ```rust pub struct Command { // Methods: pub fn new>(program: S) -> Self pub fn arg>(self, arg: S) -> Self pub fn args(self, args: I) -> Self pub fn env_clear(self) -> Self pub fn env(self, key: K, value: V) -> Self pub fn envs(self, envs: I) -> Self pub fn current_dir>(self, current_dir: P) -> Self pub fn set_raw_out(self, raw_out: bool) -> Self pub async fn spawn(self) -> Result<(Receiver, CommandChild)> pub async fn status(self) -> Result pub async fn output(self) -> Result } ``` -------------------------------- ### Use Fixed Arguments for Security Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/configuration.md Whenever possible, use fixed arguments instead of dynamic ones. This is the most secure approach for command execution. ```json "args": ["--output-format", "json"] // Fixed, secure ``` -------------------------------- ### Execute Git Commands in JavaScript Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/quick-start.md This JavaScript snippet shows how to execute pre-configured Git commands using `Command.create`. Use it for integrating Git operations into your Tauri application. ```typescript const status = await Command.create('git-status').execute(); const commit = await Command.create('git-commit', ['commit', '-m', 'message']).execute(); ``` -------------------------------- ### Clear environment variables for a command Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/api-reference/rust-command.md Call `env_clear()` to remove all inherited environment variables. The child process will start with an empty environment, requiring explicit setting of variables via `env()` or `envs()` if needed. Returns `Self` for chaining. ```rust pub fn env_clear(self) -> Self ``` ```rust let cmd = app .shell() .command("env") .env_clear() .env("PATH", "/bin:/usr/bin") .env("LANG", "en_US.UTF-8"); ``` -------------------------------- ### Migrate from Tauri Plugin Shell open() to Tauri Plugin Opener Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/module-overview.md Illustrates the code changes required to migrate from the deprecated `open::open()` function in Tauri Plugin Shell to the recommended `open_with()` function in Tauri Plugin Opener. ```rust use tauri_plugin_shell::open::Program; app.shell().open(url, Some(Program::Firefox))?; ``` ```rust use tauri_plugin_opener::ShellExt as OpenerExt; app.opener().open_with(url, "firefox")?; ``` -------------------------------- ### Configuring Sidecar Programs Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/errors.md Specify external binary paths in `tauri.conf.json` to make them available as sidecars. This ensures that the `my-tool` can be spawned by the application. ```json { "bundle": { "externalBin": [ "path/to/my-tool" ] } } ``` -------------------------------- ### spawn() Source: https://github.com/tauri-apps/tauri-plugin-shell/blob/v2/_autodocs/api-reference/rust-command.md Spawns the command as a child process and returns a receiver for events. This method allows for asynchronous handling of command output and termination. ```APIDOC ## spawn() ### Description Spawns the command as a child process and returns a receiver for events. This method allows for asynchronous handling of command output and termination. ### Method `spawn()` ### Returns `Result<(Receiver, CommandChild), Error>` where: - `Receiver`: Async channel receiving process events. - `CommandChild`: Handle to the child process (for writing to stdin or killing). ### Throws - `Error::Io`: if process spawn fails. ### Example ```rust use tauri_plugin_shell::process::CommandEvent; #[tauri::command] async fn run_command(app: AppHandle) -> Result<(), String> { let (mut rx, mut child) = app .shell() .command("cat") .spawn() .map_err(|e| e.to_string())?; // Write to stdin child.write(b"hello\n").map_err(|e| e.to_string())?; // Receive events while let Some(event) = rx.recv().await { match event { CommandEvent::Stdout(line) => { let text = String::from_utf8_lossy(&line); println!("Output: {}", text); } CommandEvent::Stderr(line) => { let text = String::from_utf8_lossy(&line); eprintln!("Error: {}", text); } CommandEvent::Terminated(payload) => { println!("Exit code: {:?}", payload.code); break; } CommandEvent::Error(err) => { eprintln!("Process error: {}", err); } } } Ok(()) } ``` ```