import { exec, execSync } from 'child_process'; import { promisify } from 'util'; const execPromise = promisify(exec); export interface CommandResult { stdout: string; stderr: string; exitCode: number; } /** * Executes an arbitrary shell command * @param command - The command to execute (e.g., "cat abc.txt | grep 'abc@gmail.com'") * @param options - Optional execution options * @returns Promise with stdout, stderr, and exit code */ export async function executeCommand( command: string, options?: { cwd?: string; timeout?: number; // timeout in milliseconds maxBuffer?: number; // max buffer size in bytes } ): Promise { try { const { stdout, stderr } = await execPromise(command, { cwd: options?.cwd, timeout: options?.timeout, maxBuffer: options?.maxBuffer || 1024 * 1024, // default 1MB shell: '/bin/sh', // use sh for cross-platform compatibility }); return { stdout: stdout.trim(), stderr: stderr.trim(), exitCode: 0, }; } catch (error: any) { // exec throws an error if the command fails or times out return { stdout: error.stdout?.trim() || '', stderr: error.stderr?.trim() || error.message, exitCode: error.code || 1, }; } } /** * Executes a command synchronously (blocking) * Use with caution - prefer executeCommand for async execution */ export function executeCommandSync( command: string, options?: { cwd?: string; timeout?: number; } ): CommandResult { try { const stdout = execSync(command, { cwd: options?.cwd, timeout: options?.timeout, encoding: 'utf-8', shell: '/bin/sh', }); return { stdout: stdout.trim(), stderr: '', exitCode: 0, }; } catch (error: any) { return { stdout: error.stdout?.toString().trim() || '', stderr: error.stderr?.toString().trim() || error.message, exitCode: error.status || 1, }; } }