use crate::command_registry::CommandRegistry; use crate::commands::WholeStreamCommand; use crate::prelude::*; use nu_errors::ShellError; use nu_protocol::{Signature, SyntaxShape}; use nu_source::Tagged; use std::path::PathBuf; pub struct Exec; #[derive(Deserialize)] pub struct ExecArgs { pub command: Tagged, pub rest: Vec>, } #[async_trait] impl WholeStreamCommand for Exec { fn name(&self) -> &str { "exec" } fn signature(&self) -> Signature { Signature::build("exec") .required("command", SyntaxShape::Path, "the command to execute") .rest(SyntaxShape::Pattern, "any additional arguments for command") } fn usage(&self) -> &str { "Execute command" } async fn run( &self, args: CommandArgs, registry: &CommandRegistry, ) -> Result { exec(args, registry).await } fn examples(&self) -> Vec { vec![ Example { description: "Execute 'ps aux'", example: "exec ps aux", result: None, }, Example { description: "Execute 'nautilus'", example: "exec nautilus", result: None, }, ] } } #[cfg(unix)] async fn exec(args: CommandArgs, registry: &CommandRegistry) -> Result { use std::os::unix::process::CommandExt; use std::process::Command; let registry = registry.clone(); let name = args.call_info.name_tag.clone(); let (args, _): (ExecArgs, _) = args.process(®istry).await?; let mut command = Command::new(args.command.item); for tagged_arg in args.rest { command.arg(tagged_arg.item); } let err = command.exec(); // this replaces our process, should not return Err(ShellError::labeled_error( "Error on exec", format!("{}", err), &name, )) } #[cfg(not(unix))] async fn exec(args: CommandArgs, _registry: &CommandRegistry) -> Result { Err(ShellError::labeled_error( "Error on exec", "exec is not supported on your platform", &args.call_info.name_tag, )) }