如何在用户按 Enter 时在终端上打印时间戳
How to print the timestamp on the terminal when user press Enter
首先我是 Linux 和 Rust 的新手。
我想要实现的是每当用户在终端中执行命令时将时间戳打印到终端。
我写了一个 Rust 程序,它将在终端的右端打印当前时间戳。我计划使用 bash 脚本在后台将此程序作为 systemd
服务执行。这个 bash 脚本所做的是在一个无限循环中,检查按键,如果是 Enter,然后执行 rust 程序。在执行真正的 Rust 程序之前,我只是尝试 echo
一个字符串。当我使用 运行 服务时,我注意到当我按 Enter 时,echo
在停止之前运行了很多次。我还尝试执行 Rust 程序而不是 echo
,但它并没有像我想象的那样工作。所以我的解决方案是错误的地方。
我的问题是,我的做法是否正确?不知道运行一个无限循环的后台进程好不好。这个想法是我从下面的视频中得到的。
此项目用于教育目的。我受到 Powerline 项目的启发,想了解它的工作原理并使用 Rust 小规模地做一些类似的事情。
你们能告诉我这种方法是否正确或指出正确的方向吗?谢谢
main.rs
extern crate termion;
extern crate chrono;
use std::time::SystemTime;
use std::io::stdout;
use chrono::{DateTime, Utc};
use termion::{color, terminal_size, cursor, raw::IntoRawMode, cursor::DetectCursorPos};
fn main() {
let mut stdout = stdout().into_raw_mode().unwrap();
let cursor_pos = stdout.cursor_pos().expect("Could not get the cursor position");
let time_now = SystemTime::now();
let datetime = DateTime::<Utc>::from(time_now);
let timestamp_str = datetime.format("%Y-%m-%d %H:%M:%S").to_string();
let size = terminal_size().expect("Could not get the terminal size");
let x = size.0 - (timestamp_str.len() - 1) as u16;
let y = cursor_pos.1;
print!("{}{red}{}{reset}",
cursor::Goto(x, y),
timestamp_str,
red = color::Fg(color::Red),
reset = color::Fg(color::Reset));
}
bash 脚本
#!/bin/bash
IFS=
while true
do
read -n 1 key
if [ "$key" = "" ]; then
echo "This was really Enter, not space, tab or something else"
fi
done
来自服务的日志
Apr 04 20:49:42 archlinux systemd[1]: Started cmd-timestamp.service.
Apr 04 20:49:42 archlinux cmd-timestamp.sh[410670]: thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code:>
Apr 04 20:49:42 archlinux cmd-timestamp.sh[410670]: note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Apr 04 20:49:42 archlinux systemd[1]: cmd-timestamp.service: Main process exited, code=exited, status=101/n/a
Apr 04 20:49:42 archlinux systemd[1]: cmd-timestamp.service: Failed with result 'exit-code'.
将评论带到答案部分:
完成我认为您想要的最简单方法是通过 PROMPT_COMMAND
.
将您的程序挂接到 bash
在您的~/.bashrc
(或~/.bash_login
)集合中:
export PROMPT_COMMAND=/path/to/rust/executable
首先我是 Linux 和 Rust 的新手。
我想要实现的是每当用户在终端中执行命令时将时间戳打印到终端。
我写了一个 Rust 程序,它将在终端的右端打印当前时间戳。我计划使用 bash 脚本在后台将此程序作为 systemd
服务执行。这个 bash 脚本所做的是在一个无限循环中,检查按键,如果是 Enter,然后执行 rust 程序。在执行真正的 Rust 程序之前,我只是尝试 echo
一个字符串。当我使用 运行 服务时,我注意到当我按 Enter 时,echo
在停止之前运行了很多次。我还尝试执行 Rust 程序而不是 echo
,但它并没有像我想象的那样工作。所以我的解决方案是错误的地方。
我的问题是,我的做法是否正确?不知道运行一个无限循环的后台进程好不好。这个想法是我从下面的视频中得到的。
此项目用于教育目的。我受到 Powerline 项目的启发,想了解它的工作原理并使用 Rust 小规模地做一些类似的事情。
你们能告诉我这种方法是否正确或指出正确的方向吗?谢谢
main.rs
extern crate termion;
extern crate chrono;
use std::time::SystemTime;
use std::io::stdout;
use chrono::{DateTime, Utc};
use termion::{color, terminal_size, cursor, raw::IntoRawMode, cursor::DetectCursorPos};
fn main() {
let mut stdout = stdout().into_raw_mode().unwrap();
let cursor_pos = stdout.cursor_pos().expect("Could not get the cursor position");
let time_now = SystemTime::now();
let datetime = DateTime::<Utc>::from(time_now);
let timestamp_str = datetime.format("%Y-%m-%d %H:%M:%S").to_string();
let size = terminal_size().expect("Could not get the terminal size");
let x = size.0 - (timestamp_str.len() - 1) as u16;
let y = cursor_pos.1;
print!("{}{red}{}{reset}",
cursor::Goto(x, y),
timestamp_str,
red = color::Fg(color::Red),
reset = color::Fg(color::Reset));
}
bash 脚本
#!/bin/bash
IFS=
while true
do
read -n 1 key
if [ "$key" = "" ]; then
echo "This was really Enter, not space, tab or something else"
fi
done
来自服务的日志
Apr 04 20:49:42 archlinux systemd[1]: Started cmd-timestamp.service.
Apr 04 20:49:42 archlinux cmd-timestamp.sh[410670]: thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code:>
Apr 04 20:49:42 archlinux cmd-timestamp.sh[410670]: note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Apr 04 20:49:42 archlinux systemd[1]: cmd-timestamp.service: Main process exited, code=exited, status=101/n/a
Apr 04 20:49:42 archlinux systemd[1]: cmd-timestamp.service: Failed with result 'exit-code'.
将评论带到答案部分:
完成我认为您想要的最简单方法是通过 PROMPT_COMMAND
.
在您的~/.bashrc
(或~/.bash_login
)集合中:
export PROMPT_COMMAND=/path/to/rust/executable