mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-04-26 08:56:22 +02:00
81 lines
1.9 KiB
TypeScript
81 lines
1.9 KiB
TypeScript
|
|
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<CommandResult> {
|
||
|
|
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,
|
||
|
|
};
|
||
|
|
}
|
||
|
|
}
|