【发布时间】:2021-04-04 17:31:12
【问题描述】:
首先我是 Linux 和 Rust 的新手。
我想要实现的是每当用户在终端中执行命令时将时间戳打印到终端。
我编写了一个 Rust 程序,它将在终端的右端打印当前时间戳。我计划使用 bash 脚本在后台将这个程序作为systemd 服务执行。这个 bash 脚本所做的是在一个无限循环中,检查按键,如果是 Enter,然后执行 rust 程序。在我执行真正的 Rust 程序之前,我只是尝试echo 一个字符串。当我运行该服务时,我注意到当我按下 Enter 时,echo 在停止之前运行了很多次。我还尝试执行 Rust 程序而不是 echo,但它并没有像我想象的那样工作。所以我的解决方案是错误的。
我的问题是,我的方法正确吗?我不知道用无限循环运行后台进程是否好。这个想法是我从下面的视频中得到的。
Creating systemd Service Files
此项目用于教育目的。我受到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'.
【问题讨论】:
-
我认为 Powerline 根本不使用 systemd 功能。
-
我来自网络开发背景。因此我没有任何与这种系统编程相关的经验。我试图找到任何指向正确方向的指南,但我找不到。这就是为什么在这里发布。所以你知道我可以通过其他方式实现这一目标吗?
-
我不确定我是否完全理解您想要实现的目标。如果您正在谈论每次使用交互使用 bash 时打印时间戳,例如执行
ls或其他非交互运行的程序/脚本,最简单的方法是将您的程序用作bash 的PROMPT_COMMAND。通过将 ENTER 作为一项深深地连接到系统的服务来响应每一次按下 ENTER 似乎是一种彻底搞砸终端的方法...... -
@tink 这太好了。谢谢。我想我可以用它来执行我的 rust 应用程序 :)
标签: linux bash rust terminal systemd