2022-01-14 06:20:53 +00:00
|
|
|
use std::time::Duration;
|
|
|
|
|
2021-10-01 21:53:13 +00:00
|
|
|
use nu_protocol::{
|
|
|
|
ast::Call,
|
2021-10-25 16:58:58 +00:00
|
|
|
engine::{Command, EngineState, Stack},
|
2022-12-21 19:20:46 +00:00
|
|
|
Category, Example, IntoInterruptiblePipelineData, PipelineData, ShellError, Signature, Type,
|
|
|
|
Value,
|
2021-10-01 21:53:13 +00:00
|
|
|
};
|
|
|
|
|
2021-10-25 04:01:02 +00:00
|
|
|
#[derive(Clone)]
|
2021-10-01 21:53:13 +00:00
|
|
|
pub struct Ps;
|
|
|
|
|
|
|
|
impl Command for Ps {
|
|
|
|
fn name(&self) -> &str {
|
|
|
|
"ps"
|
|
|
|
}
|
|
|
|
|
|
|
|
fn signature(&self) -> Signature {
|
|
|
|
Signature::build("ps")
|
2022-12-21 19:20:46 +00:00
|
|
|
.input_output_types(vec![(Type::Nothing, Type::Table(vec![]))])
|
2021-10-01 21:53:13 +00:00
|
|
|
.switch(
|
|
|
|
"long",
|
|
|
|
"list all available columns for each entry",
|
|
|
|
Some('l'),
|
|
|
|
)
|
|
|
|
.filter()
|
2021-11-17 04:22:37 +00:00
|
|
|
.category(Category::System)
|
2021-10-01 21:53:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn usage(&self) -> &str {
|
|
|
|
"View information about system processes."
|
|
|
|
}
|
|
|
|
|
2022-07-21 11:29:41 +00:00
|
|
|
fn search_terms(&self) -> Vec<&str> {
|
|
|
|
vec!["procedures", "operations", "tasks", "ops"]
|
|
|
|
}
|
|
|
|
|
2021-10-01 21:53:13 +00:00
|
|
|
fn run(
|
|
|
|
&self,
|
2021-10-28 04:13:10 +00:00
|
|
|
engine_state: &EngineState,
|
2021-10-25 06:31:39 +00:00
|
|
|
_stack: &mut Stack,
|
2021-10-01 21:53:13 +00:00
|
|
|
call: &Call,
|
2021-10-25 04:01:02 +00:00
|
|
|
_input: PipelineData,
|
2023-02-05 21:17:46 +00:00
|
|
|
) -> Result<PipelineData, ShellError> {
|
2021-10-28 04:13:10 +00:00
|
|
|
run_ps(engine_state, call)
|
2021-10-01 21:53:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn examples(&self) -> Vec<Example> {
|
2022-03-04 12:10:09 +00:00
|
|
|
vec![
|
|
|
|
Example {
|
|
|
|
description: "List the system processes",
|
|
|
|
example: "ps",
|
|
|
|
result: None,
|
|
|
|
},
|
|
|
|
Example {
|
|
|
|
description: "List the top 5 system processes with the highest memory usage",
|
|
|
|
example: "ps | sort-by mem | last 5",
|
|
|
|
result: None,
|
|
|
|
},
|
|
|
|
Example {
|
|
|
|
description: "List the top 3 system processes with the highest CPU usage",
|
|
|
|
example: "ps | sort-by cpu | last 3",
|
|
|
|
result: None,
|
|
|
|
},
|
|
|
|
Example {
|
|
|
|
description: "List the system processes with 'nu' in their names",
|
|
|
|
example: "ps | where name =~ 'nu'",
|
|
|
|
result: None,
|
|
|
|
},
|
2023-04-06 12:32:12 +00:00
|
|
|
Example {
|
|
|
|
description: "Get the parent process id of the current nu process",
|
|
|
|
example: "ps | where pid == $nu.pid | get ppid",
|
|
|
|
result: None,
|
|
|
|
},
|
2022-03-04 12:10:09 +00:00
|
|
|
]
|
2021-10-01 21:53:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-28 04:13:10 +00:00
|
|
|
fn run_ps(engine_state: &EngineState, call: &Call) -> Result<PipelineData, ShellError> {
|
2022-01-14 06:20:53 +00:00
|
|
|
let mut output = vec![];
|
2021-10-01 21:53:13 +00:00
|
|
|
let span = call.head;
|
|
|
|
let long = call.has_flag("long");
|
|
|
|
|
2022-01-14 06:20:53 +00:00
|
|
|
for proc in nu_system::collect_proc(Duration::from_millis(100), false) {
|
|
|
|
let mut cols = vec![];
|
|
|
|
let mut vals = vec![];
|
|
|
|
|
|
|
|
cols.push("pid".to_string());
|
|
|
|
vals.push(Value::Int {
|
|
|
|
val: proc.pid() as i64,
|
|
|
|
span,
|
|
|
|
});
|
|
|
|
|
2023-04-05 18:12:01 +00:00
|
|
|
cols.push("ppid".to_string());
|
|
|
|
vals.push(Value::Int {
|
|
|
|
val: proc.ppid() as i64,
|
|
|
|
span,
|
|
|
|
});
|
|
|
|
|
2022-01-14 06:20:53 +00:00
|
|
|
cols.push("name".to_string());
|
|
|
|
vals.push(Value::String {
|
|
|
|
val: proc.name(),
|
|
|
|
span,
|
|
|
|
});
|
|
|
|
|
2022-01-15 19:44:24 +00:00
|
|
|
#[cfg(not(windows))]
|
|
|
|
{
|
|
|
|
// Hide status on Windows until we can find a good way to support it
|
|
|
|
cols.push("status".to_string());
|
|
|
|
vals.push(Value::String {
|
|
|
|
val: proc.status(),
|
|
|
|
span,
|
|
|
|
});
|
|
|
|
}
|
2022-01-14 06:20:53 +00:00
|
|
|
|
|
|
|
cols.push("cpu".to_string());
|
|
|
|
vals.push(Value::Float {
|
|
|
|
val: proc.cpu_usage(),
|
|
|
|
span,
|
|
|
|
});
|
|
|
|
|
|
|
|
cols.push("mem".to_string());
|
|
|
|
vals.push(Value::Filesize {
|
|
|
|
val: proc.mem_size() as i64,
|
|
|
|
span,
|
|
|
|
});
|
|
|
|
|
|
|
|
cols.push("virtual".to_string());
|
|
|
|
vals.push(Value::Filesize {
|
|
|
|
val: proc.virtual_size() as i64,
|
|
|
|
span,
|
|
|
|
});
|
|
|
|
|
|
|
|
if long {
|
|
|
|
cols.push("command".to_string());
|
2021-10-01 21:53:13 +00:00
|
|
|
vals.push(Value::String {
|
2022-01-14 06:20:53 +00:00
|
|
|
val: proc.command(),
|
2021-10-01 21:53:13 +00:00
|
|
|
span,
|
|
|
|
});
|
2022-02-01 21:05:26 +00:00
|
|
|
#[cfg(windows)]
|
|
|
|
{
|
|
|
|
cols.push("cwd".to_string());
|
|
|
|
vals.push(Value::String {
|
|
|
|
val: proc.cwd(),
|
|
|
|
span,
|
|
|
|
});
|
|
|
|
cols.push("environment".to_string());
|
|
|
|
vals.push(Value::List {
|
|
|
|
vals: proc
|
|
|
|
.environ()
|
|
|
|
.iter()
|
|
|
|
.map(|x| Value::string(x.to_string(), span))
|
|
|
|
.collect(),
|
|
|
|
span,
|
|
|
|
});
|
|
|
|
}
|
2021-10-01 21:53:13 +00:00
|
|
|
}
|
2022-01-14 06:20:53 +00:00
|
|
|
|
|
|
|
output.push(Value::Record { cols, vals, span });
|
2021-10-01 21:53:13 +00:00
|
|
|
}
|
|
|
|
|
2021-10-28 04:13:10 +00:00
|
|
|
Ok(output
|
|
|
|
.into_iter()
|
|
|
|
.into_pipeline_data(engine_state.ctrlc.clone()))
|
2021-10-01 21:53:13 +00:00
|
|
|
}
|