用DeepSeek写程序之一:编写在linux终端窗口右上角动态显示时间的c++程序
一. 简单需求
早前有个需求当SSH进入linux时,希望在终端窗口动太显示当前的时间,原来是用脚本解决的
while sleep 1;do tput sc;tput cup 0 $(($(tput cols)-29));date;tput rc;done &
如果想加上颜色,改为:
while sleep 1;do tput sc;tput cup 0 $(($(tput cols)-8)); tput setb 1;tput setf 7;date "+%T";tput rc;done &
如果希望每次打开终端都能显示时间,而不必每次在控制台执行脚本,可以将其放在.bashrc中,即:
echo "while sleep 1;do tput sc;tput cup 0 \$((\$(tput cols)-29));date;tput rc;done &" >> $HOME/.bashrc
实际使用时发现这种输出方式会影响窗口滚动,就是脚本输出时间时将窗口滚回最下方,影响相当大。
最近DeepSeek爆火后,看看DeepSeek能不能写个C++程序,同时解决窗口滚动问题。
二. 用DeepSeek写程序
向DeepSeek发出灵魂拷贝:“用c++编写程序,用于在linux用终端窗口右上角位置动态显示时间”,勾选“尝试思考(R1)”后,DeepSeek用时47秒洋洋洒洒的输出了一堆内容,用循环每隔一秒更新一次,用ANSI转义码\033[<行>;<列>H把光标移动到终端右上角输出时间;要注意时间长度变会有短残留字符的问题;要处理终端的resize事件检测新的宽度;以及隐藏光标用\033[?25l、恢复用\033[?25h等。
最后给出一段C++代码:
#include <iostream>
#include <chrono>
#include <ctime>
#include <iomanip>
#include <unistd.h>
#include <sys/ioctl.h>
#include <csignal>
#include <atomic>
#include <string>
using namespace std::chrono_literals;
std::atomic_bool keep_running(true);
// 信号处理函数
void signal_handler(int signal) {
if (signal == SIGINT) {
keep_running = false;
}
}
// 获取终端宽度
int get_terminal_width() {
struct winsize size{};
ioctl(STDOUT_FILENO, TIOCGWINSZ, &size);
return size.ws_col;
}
// 隐藏光标
void hide_cursor() {
std::cout << "\033[?25l";
}
// 显示光标
void show_cursor() {
std::cout << "\033[?25h";
}
int main() {
// 注册信号处理
std::signal(SIGINT, signal_handler);
// 隐藏光标
hide_cursor();
while (keep_running) {
// 获取当前时间
auto now = std::chrono::system_clock::now();
std::time_t now_time = std::chrono::system_clock::to_time_t(now);
std::tm* local_time = std::localtime(&now_time);
std::string time_str = std::to_string(local_time->tm_hour) + ":"
+ std::to_string(local_time->tm_min) + ":"
+ std::to_string(local_time->tm_sec);
// 获取终端宽度并计算位置
int term_width = get_terminal_width();
int time_len = time_str.length();
int pos = term_width - time_len;
// 使用ANSI转义码移动光标并输出时间
std::cout << "\033[1;" << pos << "H" // 移动到第一行右侧
<< time_str
<< std::flush;
// 每秒更新一次
std::this_thread::sleep_for(1s);
}
// 清理并恢复光标
std::cout << "\033[2K\033[1;1H"; // 清除第一行并移动光标到左上角
show_cursor();
std::cout << std::flush;
return 0;
}
瞅了一眼,应该没处理好滚动问题,再追加一个要求:“要求程序在后台运行,不影响用户输入命令”,DeepSeek深度思考60秒后再次给出一段代码:
#include <iostream>
#include <chrono>
#include <ctime>
#include <iomanip>
#include <unistd.h>
#include <sys/ioctl.h>
#include <csignal>
#include <atomic>
#include <string>
using namespace std::chrono_literals;
std::atomic_bool keep_running(true);
void signal_handler(int signal) {
if (signal == SIGINT) {
keep_running = false;
}
}
int get_terminal_width() {
struct winsize size{};
ioctl(STDOUT_FILENO, TIOCGWINSZ, &size);
return size.ws_col;
}
void hide_cursor() {
std::cout << "\033[?25l";
}
void show_cursor() {
std::cout << "\033[?25h";
}
int main() {
std::signal(SIGINT, signal_handler);
hide_cursor();
while (keep_running) {
auto now = std::chrono::system_clock::now();
std::time_t now_time = std::chrono::system_clock::to_time_t(now);
std::tm* local_time = std::localtime(&now_time);
// 格式化时间(修复个位数显示问题)
std::stringstream ss;
ss << std::setw(2) << std::setfill('0') << local_time->tm_hour << ":"
<< std::setw(2) << std::setfill('0') << local_time->tm_min << ":"
<< std::setw(2) << std::setfill('0') << local_time->tm_sec;
std::string time_str = ss.str();
int term_width = get_terminal_width();
int time_len = time_str.length();
int pos = term_width - time_len;
// 关键修改:保存光标位置 -> 输出时间 -> 恢复光标位置
std::cout << "\033[s" // 保存光标位置
<< "\033[1;" << pos << "H" // 移动到右上角
<< time_str
<< "\033[u" // 恢复光标位置
<< std::flush;
std::this_thread::sleep_for(1s);
}
// 退出时清除时间显示
std::cout << "\033[s\033[1;" << (get_terminal_width() - 8) << "H\033[0K\033[u";
show_cursor();
std::cout << std::flush;
return 0;
}
而且强调:
每次输出时间时,将光标移动到右上角,输出时间后立即将光标移回原来的位置,这样用户输入的命令不会被打断。例如,当用户在输入命令时,程序在后台每隔一秒将光标移到右上角,写入时间,然后移回原来的位置,这样用户的输入不会被覆盖。
这可能需要记录光标的当前位置,在输出时间后恢复。例如,使用ANSI转义码保存光标位置,移动输出时间,然后恢复。例如:
- 保存光标位置:\033[s
- 移动光标到右上角:\033[1;H
- 输出时间
- 恢复光标位置:\033[u
这样,用户在输入时,每次更新时间时,程序会保存当前光标位置,输出时间到右上角,然后恢复,这样用户的输入不会被干扰。
好吧,看样子它并没有理解我说的内容。还是先试试代码能不能运行。
三. 编译运行
DeekSeek给出运行方式:
# 编译程序
g++ -o clock clock.cpp -std=c++11 -lpthread
# 后台运行(推荐方式)
./clock &
# 完全脱离终端运行(关闭终端后仍然有效)
nohup ./clock > /dev/null 2>&1 &
毫无意外,报错了。
改用c++14来编译:
g++ -o clock clock.cpp -std=c++14 -lpthread
再次报错:
咱自己改一改,加上#include <thread>
后编译成功,运行clock直接输出当前时间,运行./clock & 实现在窗口右上角动态显示当前时间。
但是和脚本实现一样,会影响窗口滚动。要求DeepSeek再改进,反复出现“服务器繁忙,请稍后再试。”,没法进行只能放弃。
四. 总结
DeepSeek基本能按要求写出似模似样的代码,有些小问题修正后能够使用。
以上测试环境:Linux openEuler1 5.10.0-229.0.0.128.oe2203sp4.x86_64 #1 SMP Wed Sep 18 16:21:54 CST 2024 x86_64 x86_64 x86_64 GNU/Linux,SSH工具:PuTTY Release 0.72。
用DeepSeek写程序之一:编写在linux终端窗口右上角动态显示时间的c++程序的更多相关文章
- linux终端窗口字体缩放快捷键
环境:ubuntu16.04, 打开终端,有时候log输出一行显示不下 ‘ctrl’ + ‘-’字体缩小,一行显示更多的内容 ‘ctrl’ + ‘shift’ + ‘+’字体变大
- [Linux] PHP程序员玩转Linux系列-搭建代码开发环境
1.PHP程序员玩转Linux系列-怎么安装使用CentOS 2.PHP程序员玩转Linux系列-lnmp环境的搭建 有些同学可能觉得我写的都是啥yum安装的,随便配置一下而已,没啥技术含量,我的目的 ...
- [Linux] PHP程序员玩转Linux系列-备份还原MySQL
1.PHP程序员玩转Linux系列-怎么安装使用CentOS 2.PHP程序员玩转Linux系列-lnmp环境的搭建 3.PHP程序员玩转Linux系列-搭建FTP代码开发环境 前几天有个新闻,说是g ...
- [Linux] PHP程序员玩转Linux系列-自动备份与SVN
我的代码经常在开发修改,为了代码的安全性,比如哪天误删了文件,或者哪天改错东西了,可以恢复回来,我要搞代码备份.备份代码,我先做最简单的,使用linux的定时机制加shell命令打包文件,每天按日期保 ...
- [Linux] PHP程序员玩转Linux系列-nginx初学者引导
1.PHP程序员玩转Linux系列-怎么安装使用CentOS 2.PHP程序员玩转Linux系列-lnmp环境的搭建 3.PHP程序员玩转Linux系列-搭建FTP代码开发环境 4.PHP程序员玩转L ...
- [Linux] PHP程序员玩转Linux系列-Linux和Windows安装nginx
1.PHP程序员玩转Linux系列-怎么安装使用CentOS 2.PHP程序员玩转Linux系列-lnmp环境的搭建 3.PHP程序员玩转Linux系列-搭建FTP代码开发环境 4.PHP程序员玩转L ...
- [Linux] PHP程序员玩转Linux系列-Nginx中的HTTPS
1.PHP程序员玩转Linux系列-怎么安装使用CentOS 2.PHP程序员玩转Linux系列-lnmp环境的搭建 3.PHP程序员玩转Linux系列-搭建FTP代码开发环境 4.PHP程序员玩转L ...
- [Linux] PHP程序员玩转Linux系列-使用supervisor实现守护进程
1.PHP程序员玩转Linux系列-怎么安装使用CentOS 2.PHP程序员玩转Linux系列-lnmp环境的搭建 3.PHP程序员玩转Linux系列-搭建FTP代码开发环境 4.PHP程序员玩转L ...
- [Linux] PHP程序员玩转Linux系列-telnet轻松使用邮箱
1.PHP程序员玩转Linux系列-怎么安装使用CentOS 2.PHP程序员玩转Linux系列-lnmp环境的搭建 3.PHP程序员玩转Linux系列-搭建FTP代码开发环境 4.PHP程序员玩转L ...
- [Linux] PHP程序员玩转Linux系列-升级PHP到PHP7
1.PHP程序员玩转Linux系列-怎么安装使用CentOS 2.PHP程序员玩转Linux系列-lnmp环境的搭建 3.PHP程序员玩转Linux系列-搭建FTP代码开发环境 4.PHP程序员玩转L ...
随机推荐
- (Python基础教程之十八)Python字典交集–比较两个字典
Python示例,用于查找2个或更多词典之间的常见项目,即字典相交项目. 1.使用"&"运算符的字典交集 最简单的方法是查找键,值或项的交集,即 & 在两个字典之间 ...
- Python:pygame游戏编程之旅二(自由移动的小球)
本节实现一个在窗口中自由运动的小球程序,做了详细注释,不多做解释了. 代码: # -*- coding:utf-8 -*- import sys import pygame from pygame.l ...
- ArrayList源码分析(基于JDK1.6)
不积跬步,无以至千里:不积小流,无以成江海.从基础做起,一点点积累,加油! <Java集合类>中讲述了ArrayList的基础使用,本文将深入剖析ArrayList的内部结构及实现原理,以 ...
- ContosoRetailDW数据库恢复问题
https://www.microsoft.com/en-us/download/details.aspx?id=18279 下载 ContosoBIdemoBAK.exe和ContosoBIdemo ...
- manim边做边学--多面体
在Manim中,对于多面体,有一系列封装好的类可以直接使用. 使用它们,可以方便快速的构建正多面体: Polyhedron:通过顶点和面的参数构建任意多面体 Tetrahedron:四面体 Octah ...
- C# Redis 的基本使用
C# Redis 的基本使用 -迷恋自留地 Redis 概述 在我们日常的开发中,无不都是使用数据库来进行数据的存储,由于一般的系统任务中通常不会存在高并发的情况,所以这样看起来并没有什么问题,可是一 ...
- 一图一知-强大的js数组
平时在开发中,数组基本是每天都会用到的数据结构,通过ES6的更新,数组更是越发强大,特此记录数组那些有用而强大的api.
- OS之《CPU调度》
CPU调度层次 高级调度:是作业调度.将外村的作业加载到内存里,分配对应的资源,然后加入就绪队列 低级调度:将就绪队列中的进程调度到CPU执行 中级调度:为了提高内存的利用率和系统的吞吐量,将暂时不能 ...
- 多段区间的时间滑块slider实现方式
多段区间的时间滑块slider实现方式 写在前面:今天要实现一个尖峰平谷的数据配置,这可一下难倒我了,但是还好互联网上大神云集,感谢各位大神的倾情分享,现在就写下我的感悟,留给看到这篇文章的你 参考链 ...
- Gitlab 实现仓库完全迁移
方法一:最快 gitlab用url导入注意事项看图 方法二 首先需要在新的服务服务器上新建一个项目 然后用 Git Bash 执行以下命令 git clone --mirror 项目原代码仓库地址 / ...