Streamlit黑科技!在线SSH终端神器,远程服务器管理一站式搞定(附源码+在线体验),于大爷.在线工具集

无需安装客户端,网页一键远程SSH,文件上传/下载/命令执行全搞定!

于大爷.在线工具集

一、你还在这样管理服务器吗?

  • ❌ 频繁切换Xshell、MobaXterm等客户端,效率低下
  • ❌ 文件传输靠命令行,出错率高
  • ❌ 服务器多,配置难管理,命令执行无记录
  • ❌ 远程办公/临时用手机,SSH连接超级麻烦

二、拯救方案:在线SSH终端工具

👉 在线体验地址:所有工具入口(功能持续更新,免登录直接用)

本项目基于Streamlit打造,支持:

  • 🔒 SSH远程连接配置(主机/端口/用户名/密码)
  • 📤 文件上传到服务器任意目录
  • 📥 服务器文件一键下载(支持大文件检测)
  • ⌨️ 多条命令批量执行,结果可视化展示
  • 📝 操作全程Web界面,手机/电脑都能用

三、核心功能界面

  • SSH连接配置:主机、端口、用户名、密码一键保存,支持连接测试
  • 文件上传:本地文件拖拽上传,自动创建远程目录
  • 文件下载:输入远程路径,支持大文件检测,下载后可直接预览CSV
  • 命令执行:多条命令批量执行,结果分块展示,状态码一目了然

四、核心代码展示(完整可用,直接集成Streamlit)

import streamlit as st
import paramiko
import pandas as pd
import os
from datetime import datetime

class SSHManager:
    def __init__(self, host, user, password, port):
        self.host = host
        self.user = user
        self.password = password
        self.port = port
    def sftp_upload_file(self, server_path, local_path, timeout=10):
        try:
            t = paramiko.Transport((self.host, self.port))
            t.banner_timeout = timeout
            t.connect(username=self.user, password=self.password)
            sftp = paramiko.SFTPClient.from_transport(t)
            sftp.put(local_path, server_path)
            t.close()
            return True
        except Exception as e:
            st.error("上传失败")
            return False
    def sftp_download_file(self, server_path, local_path, timeout=10):
        try:
            t = paramiko.Transport((self.host, self.port))
            t.banner_timeout = timeout
            t.connect(username=self.user, password=self.password)
            sftp = paramiko.SFTPClient.from_transport(t)
            sftp.get(server_path, local_path)
            t.close()
            return True
        except Exception as e:
            st.error(f"下载失败: {str(e)}")
            return False
    def ssh_exec_command(self, cmds, timeout=10):
        try:
            ssh = paramiko.SSHClient()
            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            ssh.connect(self.host, self.port, self.user, self.password, timeout=timeout)
            results = []
            for cmd in cmds:
                stdin, stdout, stderr = ssh.exec_command(cmd, get_pty=True, timeout=timeout)
                output = stdout.readlines()
                status = stdout.channel.recv_exit_status()
                results.append({
                    'command': cmd,
                    'output': output,
                    'status': status
                })
            ssh.close()
            return {'status': 0, 'data': results}
        except Exception as e:
            st.error(f"命令执行失败: {str(e)}")
            return None
    def ensure_remote_path_exists(self, path):
        try:
            ssh = paramiko.SSHClient()
            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            ssh.connect(self.host, self.port, self.user, self.password)
            cmd = f'mkdir -p {path}'
            stdin, stdout, stderr = ssh.exec_command(cmd)
            status = stdout.channel.recv_exit_status()
            ssh.close()
            return status == 0
        except Exception as e:
            st.error(f"创建远程目录失败: {str(e)}")
            return False

def main():
    st.title("🖥️ SSH文件管理工具")
    # 连接配置
    with st.container():
        st.subheader("📡 SSH连接配置")
        col1, col2, col3, col4 = st.columns(4)
        with col1:
            host = st.text_input("主机地址", value="172.23.165.3")
        with col2:
            port = st.number_input("端口", value=10022)
        with col3:
            user = st.text_input("用户名", value="root")
        with col4:
            password = st.text_input("密码", value="", type="password")
        col_btn1, col_btn2, _ = st.columns([1, 1, 4])
        with col_btn1:
            if st.button("💾 保存配置", use_container_width=True):
                st.session_state.ssh_manager = SSHManager(host, user, password, port)
                st.success("SSH配置已保存!")
        with col_btn2:
            if st.button("🔌 测试连接", use_container_width=True):
                try:
                    ssh = paramiko.SSHClient()
                    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
                    ssh.connect(host, port, user, password, timeout=5)
                    ssh.close()
                    st.session_state.ssh_connected = True
                    st.success("连接成功!")
                except Exception as e:
                    st.session_state.ssh_connected = False
                    st.error(f"连接失败: {str(e)}")
    st.divider()
    tab1, tab2, tab3 = st.tabs(["📤 文件上传", "📥 文件下载", "⌨️ 命令执行"])
    if 'ssh_manager' not in st.session_state:
        st.warning("请先配置SSH连接信息")
        return
    if not st.session_state.get('ssh_connected', False):
        st.warning("SSH连接未测试或连接失败,请先测试连接")
        return
    ssh_manager = st.session_state.ssh_manager
    # 文件上传
    with tab1:
        st.subheader("文件上传")
        col_upload1, col_upload2 = st.columns([2, 1])
        with col_upload1:
            uploaded_file = st.file_uploader("选择要上传的文件", label_visibility="collapsed")
        with col_upload2:
            server_path = st.text_input("服务器路径", value="/soft/d5000_his_data/", placeholder="输入服务器路径")
        if uploaded_file and st.button("📤 开始上传", use_container_width=True):
            if not ssh_manager.ensure_remote_path_exists(server_path):
                st.error("无法确保远程目录存在")
                return
            local_path = f"./temp/{uploaded_file.name}"
            os.makedirs("./temp", exist_ok=True)
            with open(local_path, "wb") as f:
                f.write(uploaded_file.getbuffer())
            if ssh_manager.sftp_upload_file(f"{server_path}/{uploaded_file.name}", local_path):
                st.success("文件上传成功!")
            os.remove(local_path)
    # 文件下载
    with tab2:
        st.subheader("文件下载")
        remote_path = st.text_input("远程文件路径", placeholder="输入要下载的远程文件的完整路径", help="例如:/path/to/your/file.csv")
        if remote_path and st.button("📥 获取文件", use_container_width=True):
            temp_dir = os.path.join(os.getcwd(), "temp")
            os.makedirs(temp_dir, exist_ok=True)
            try:
                ssh = paramiko.SSHClient()
                ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
                ssh.connect(ssh_manager.host, ssh_manager.port, ssh_manager.user, ssh_manager.password)
                sftp = ssh.open_sftp()
                file_stats = sftp.stat(remote_path)
                file_size_mb = file_stats.st_size / (1024 * 1024)
                if file_size_mb > 100:
                    st.error(f"文件大小 ({file_size_mb:.2f}MB) 超过限制 (100MB)")
                    return
                filename = os.path.basename(remote_path)
                local_temp_path = os.path.join(temp_dir, filename)
                if ssh_manager.sftp_download_file(remote_path, local_temp_path):
                    with open(local_temp_path, 'rb') as f:
                        file_content = f.read()
                    col_info1, col_info2, col_btn = st.columns([1, 1, 2])
                    with col_info1:
                        st.info(f"📁 文件名: {filename}")
                    with col_info2:
                        st.info(f"📊 大小: {file_size_mb:.2f} MB")
                    with col_btn:
                        st.download_button(
                            label=f"📥 下载 {filename}",
                            data=file_content,
                            file_name=filename,
                            mime="application/octet-stream",
                            use_container_width=True
                        )
                    if filename.lower().endswith('.csv'):
                        with st.expander("预览文件内容"):
                            df = pd.read_csv(local_temp_path)
                            st.dataframe(df)
                if os.path.exists(local_temp_path):
                    os.remove(local_temp_path)
            except Exception as e:
                st.error(f"文件下载失败: {str(e)}")
            finally:
                if os.path.exists(temp_dir):
                    import shutil
                    shutil.rmtree(temp_dir, ignore_errors=True)
    # 命令执行
    with tab3:
        st.subheader("命令执行")
        command = st.text_area("输入要执行的命令", placeholder="每行输入一条命令", height=100)
        if st.button("▶️ 执行命令", use_container_width=True):
            cmds = [cmd.strip() for cmd in command.split('\n') if cmd.strip()]
            result = ssh_manager.ssh_exec_command(cmds)
            if result:
                for cmd_result in result['data']:
                    with st.expander(f"🔍 命令: {cmd_result['command']}", expanded=True):
                        st.code(''.join(cmd_result['output']))
                        st.info(f"状态码: {cmd_result['status']}")
    with st.expander("📖 使用说明"):
        st.markdown("""
        1. 配置SSH连接信息并测试连接
        2. 选择功能标签页:文件上传/下载/命令执行
        3. 注意网络和权限,支持大文件检测
        """)
main()

五、使用说明

  1. 配置SSH连接:输入服务器信息,点击"测试连接"确保可用
  2. 文件上传/下载:选择对应标签页,按提示操作即可
  3. 命令执行:支持多条命令批量执行,结果分块展示
  4. 安全建议:建议使用专用低权限账号,避免生产环境误操作

六、在线体验 & 项目入口


七、联系作者

  • 邮箱:6686496@qq.com
  • 欢迎交流、合作、提建议!

如果觉得有用,欢迎点赞、收藏、关注!更多Streamlit黑科技持续更新中!

Logo

GitCode 天启AI是一款由 GitCode 团队打造的智能助手,基于先进的LLM(大语言模型)与多智能体 Agent 技术构建,致力于为用户提供高效、智能、多模态的创作与开发支持。它不仅支持自然语言对话,还具备处理文件、生成 PPT、撰写分析报告、开发 Web 应用等多项能力,真正做到“一句话,让 Al帮你完成复杂任务”。

更多推荐