当前位置: 首页 > news >正文

关于命令行交互自动化,及pyinstaller打包wexpect的问题

Python自动化工具

用来执行命令并进行交互,比如需要输入账号密码或者确认的场景
linux平台可以用pexpect,但是windows平台有一些差异,比较好用的是pexpect的变种wexpect,如果脚本中用了wexpect,并且要打包成onefile,可以
参考github首先打包wexpect
1.进入wexpect目录执行

pyinstaller __main__.py -n wexpect

会生成dist文件夹
2.python代码A.py中使用wexpect,注意wexpect.spawn前后必须按照下面添加代码

import sys,os,wexpect
#spawn前
real_executable = sys.executable
try:if sys._MEIPASS is not None:sys.executable = os.path.join(sys._MEIPASS, "wexpect", "wexpect.exe")
except AttributeError:pass
child = wexpect.spawn('ssh root@192.168.47.128')
sys.executable = real_executable
#spawn后
try:child.expect('password',timeout=1)child.sendline("root@123")child.expect('#',timeout=1)child.sendline("touch wexpect")child.sendline("exit")
except Exception as e:print("timeout")
print('1.before = ',child.before)
print('2.after = ',child.after)
child.wait()

3.打包成onefile

pyinstaller --onefile --add-data “wexpect路径\dist;.” A.py

Windows伪控制台

很少用到,只能参考windows官方文档自己写,启动伪控制台,并且通过管道直接和伪控制台交互,非常方便,传送门
自己随便写的demo如下:

// PseudoConsoleDemo.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//#include <iostream>
#include <windows.h>
#include <stdio.h>
#include <thread>
#include <string>
#include <codecvt>
#include <memory>
using namespace std;void Log(string info) 
{//string cmd = "echo " + info;printf(info.c_str());
}std::string UTF8ToLocale(const std::string& utf8Str)
{//Convert utf8 to Unicodestd::wstring_convert<std::codecvt_utf8<wchar_t> > conv;std::wstring tmpWstr = conv.from_bytes(utf8Str);//Conver widestr to system code pageint len = WideCharToMultiByte(CP_ACP, NULL, tmpWstr.c_str(), -1, NULL, NULL, NULL, NULL);char *str = new char[len];WideCharToMultiByte(CP_ACP, NULL, tmpWstr.c_str(), -1, str, len, NULL, NULL);return str;
}HRESULT PrepareStartupInformation(HPCON hpc, STARTUPINFOEXW* psi)
{// Prepare Startup Information structureSTARTUPINFOEXW si;ZeroMemory(&si, sizeof(si));si.StartupInfo.cb = sizeof(STARTUPINFOEX);// Discover the size required for the listSIZE_T bytesRequired;InitializeProcThreadAttributeList(NULL, 1, 0, &bytesRequired);// Allocate memory to represent the listsi.lpAttributeList = (PPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), 0, bytesRequired);if (!si.lpAttributeList){return E_OUTOFMEMORY;}// Initialize the list memory locationif (!InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &bytesRequired)){HeapFree(GetProcessHeap(), 0, si.lpAttributeList);return HRESULT_FROM_WIN32(GetLastError());}// Set the pseudoconsole information into the listif (!UpdateProcThreadAttribute(si.lpAttributeList,0,PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE,hpc,sizeof(hpc),NULL,NULL)){HeapFree(GetProcessHeap(), 0, si.lpAttributeList);return HRESULT_FROM_WIN32(GetLastError());}*psi = si;return S_OK;
}
bool WritePipe(HANDLE pipeHd, const char DataBuffer[])
{DWORD dwBytesToWrite = (DWORD)strlen(DataBuffer);DWORD dwBytesWritten = 0;BOOL bErrorFlag = FALSE;bErrorFlag = WriteFile(pipeHd,           // open file handleDataBuffer,      // start of data to writedwBytesToWrite,  // number of bytes to write&dwBytesWritten, // number of bytes that were writtenNULL);return bErrorFlag;
}bool ReadPipe(HANDLE pipeHd)
{const int BUFFERSIZE = 4096;char   ReadBuffer[BUFFERSIZE] = { 0 };if (pipeHd == INVALID_HANDLE_VALUE){//printf(("Terminal failure: unable to open file \"\" for read.\n"));return false;}// Read one character less than the buffer size to save room for// the terminating NULL character. DWORD dwBytesRead;DWORD dwBytesToRead = BUFFERSIZE - 1;if (FALSE == ReadFile(pipeHd, ReadBuffer, dwBytesToRead, &dwBytesRead, NULL)){//printf("Terminal failure: Unable to read from file.\n GetLastError=%08x\n", GetLastError());return false;}// This is the section of code that assumes the file is ANSI text. // Modify this block for other data types if needed.if (dwBytesRead > 0 && dwBytesRead <= dwBytesToRead){ReadBuffer[dwBytesRead] = '\0'; // NULL character//printf(("Data read from  (%d bytes): \n"), dwBytesRead);//PseudoConsole use utf8 encodeLog(UTF8ToLocale(ReadBuffer));return true;}else if (dwBytesRead == 0){//printf(("No data read from file\n"));}else{//printf("\n ** Unexpected value for dwBytesRead ** \n");}return false;
}
PWSTR String2PWSTR(const string& str)
{PWSTR pwstr;int len = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.size(), NULL, 0);pwstr = new WCHAR[len + 1];MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.size(), pwstr, len);pwstr[len] = '\0';return pwstr;
}
HPCON SetUpPseudoConsole(std::string cmd, HANDLE& read, HANDLE& write, PROCESS_INFORMATION& proc)
{COORD size = { 1000, 500 };HRESULT hr = S_OK;// Create communication channels// - Close these after CreateProcess of child application with pseudoconsole object.HANDLE inputReadSide, outputWriteSide;// - Hold onto these and use them for communication with the child through the pseudoconsole.HANDLE outputReadSide, inputWriteSide;if (!CreatePipe(&inputReadSide, &inputWriteSide, NULL, 0)){return NULL;}if (!CreatePipe(&outputReadSide, &outputWriteSide, NULL, 0)){return NULL;}HPCON hPC;hr = CreatePseudoConsole(size, inputReadSide, outputWriteSide, 0, &hPC);if (FAILED(hr)){return NULL;}STARTUPINFOEXW siEx;PrepareStartupInformation(hPC, &siEx);// Create mutable text string for CreateProcessW command line string.const string cmdStr = "C:\\windows\\system32\\cmd.exe /k \"echo off\"";PCWSTR childApplication = String2PWSTR(cmdStr);//PCWSTR childApplication = L"C:\\windows\\system32\\cmd.exe /k \"net use \\\\192.168.47.128\"";// Create mutable text string for CreateProcessW command line string.const size_t charsRequired = wcslen(childApplication) + 1; // +1 null terminatorPWSTR cmdLineMutable = (PWSTR)HeapAlloc(GetProcessHeap(), 0, sizeof(wchar_t) * charsRequired);if (!cmdLineMutable){return NULL;}wcscpy_s(cmdLineMutable, charsRequired, childApplication);PROCESS_INFORMATION pi;ZeroMemory(&pi, sizeof(pi));// Call CreateProcessif (!CreateProcessW(NULL,cmdLineMutable,NULL,NULL,FALSE,EXTENDED_STARTUPINFO_PRESENT,NULL,NULL,&siEx.StartupInfo,&pi)){HeapFree(GetProcessHeap(), 0, cmdLineMutable);return NULL;}CloseHandle(inputReadSide);CloseHandle(outputWriteSide);//if (!WritePipe(inputWriteSide, "net use \\\\192.168.47.128\r")) {//	printf("write error");//}read = outputReadSide;write = inputWriteSide;proc = pi;return hPC;
}
int main()
{auto t = std::thread([]() {HANDLE read, write;PROCESS_INFORMATION pi;HPCON hpc = SetUpPseudoConsole("net use \\\\192.168.47.128", read, write, pi);DWORD exitCode;if (GetExitCodeProcess(pi.hProcess, &exitCode)) {//printf("get exit code success ,code=%d", exitCode);STILL_ACTIVE;if (exitCode == STILL_ACTIVE) {//printf("process alive");}}else {Log("get exit code failed");}if (!ReadPipe(read)) {Log("read error");}if (!WritePipe(write, "net use \\\\192.168.47.128\r")) {Log("write error");}if (!ReadPipe(read)) {Log("read error");}if (!WritePipe(write, "smbshare\r")) {Log("write error");}if (!ReadPipe(read)) {Log("read error");}if (!WritePipe(write, "smbshare\r")) {Log("write error");}if (!ReadPipe(read)) {Log("read error");}Sleep(100);if (GetExitCodeProcess(pi.hProcess, &exitCode)) {Log("get exit code success ,code=" + exitCode);STILL_ACTIVE;if (exitCode == STILL_ACTIVE) {Log("process alive");}}WaitForSingleObject(pi.hProcess, 0);WaitForSingleObject(pi.hThread, 0);CloseHandle(pi.hProcess);CloseHandle(pi.hThread);ClosePseudoConsole(hpc);//TerminateProcess});t.join();
}

相关文章:

关于命令行交互自动化,及pyinstaller打包wexpect的问题

Python自动化工具 用来执行命令并进行交互&#xff0c;比如需要输入账号密码或者确认的场景 linux平台可以用pexpect&#xff0c;但是windows平台有一些差异&#xff0c;比较好用的是pexpect的变种wexpect&#xff0c;如果脚本中用了wexpect&#xff0c;并且要打包成onefile&a…...

8.4 【MySQL】文件系统对数据库的影响

因为 MySQL 的数据都是存在文件系统中的&#xff0c;就不得不受到文件系统的一些制约&#xff0c;这在数据库和表的命名、表的大小和性能方面体现的比较明显&#xff0c;比如下边这些方面&#xff1a; 数据库名称和表名称不得超过文件系统所允许的最大长度。 每个数据库都对应…...

Python WEB框架FastAPI (二)

Python WEB框架FastAPI &#xff08;二&#xff09; 最近一直在使用fastapi&#xff0c;随着使用的深入发现我对于它的了解还是太少了&#xff0c;以至于踩了一些坑。所以在这里记录一下&#xff0c;愿看到的小伙伴不迷路。 路径传参并发问题 一、路径传参 这是对上一个传参…...

基于Java网络书店商城设计实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…...

怒刷LeetCode的第3天(Java版)

目录 第一题 题目来源 题目内容 解决方法 方法一&#xff1a;动态规划 第二题 题目来源 题目内容 解决方法 方法一&#xff1a;模拟 方法二&#xff1a;数学规律 方法三&#xff1a;分组 第三题 题目来源 题目内容 解决方法 方法一&#xff1a;数学方法 方法…...

JavaScript数组去重常用方法

数组去重是在 JavaScript 开发中经常遇到的问题。本文将从前言、分析、使用场景、具体实现代码和注意事项等方面&#xff0c;详细讨论 JavaScript 数组去重的方法。 前言&#xff1a; 在 JavaScript 中&#xff0c;数组是一种常用的数据结构&#xff0c;用于存储多个值。然而…...

蓝牙电话之HFP—电话音频

1 媒体音频&#xff1a; 播放蓝牙音乐的数据&#xff0c;这种音频对质量要求高&#xff0c;数据发送有重传机制&#xff0c;从而以l2cap的数据形式走ACL链路。编码方式有&#xff1a;SBC、AAC、APTX、APTX_HD、LDAC这五种编码方式&#xff0c;最基础的编码方式是SBC&#xff0…...

JDBC基本概念

什么是JDBC JDBC概念 JDBC&#xff08;Java DataBase Connectivity&#xff09;是一套统一的基于Java语言的关系数据库编程接口规范。 该规范允许将SQL语句作为参数通过JDBC接口发送给远端数据库&#xff0c; …...

leetcode876 链表的中间节点

题目 给你单链表的头结点 head &#xff0c;请你找出并返回链表的中间结点。 如果有两个中间结点&#xff0c;则返回第二个中间结点。 示例 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[3,4,5] 解释&#xff1a;链表只有一个中间结点&#xff0c;值为 3 。 输入&a…...

了解方法重写

父类 package com.mypackage.oop.demo07;//重写都是方法的重写&#xff0c;与属性无关 public class B {public static void test(){System.out.println("B>test.()");}public void test2(){System.out.println("B2>test.()");} }子类 package com…...

2、从“键鼠套装”到“全键盘游戏化”审核

1、风行内容仓的增效之路 - 前言 内容仓成立初期&#xff0c;安全审核组是规模最大的小组&#xff0c;占到部门人数的半壁江山&#xff0c;因此增效工作首先就从安全审核开始。 早期安全审核每天的达标值在800条左右&#xff0c;每天的总审核量不到1万&#xff0c;距离业务部门…...

【flutter】架构之商城main入口

架构之商城main入口 前言一、项目模块的划分二、入口main的配置三、配置文件怎么做总结 前言 本栏目我们将完成一个商城项目的架构搭建&#xff0c;并完善中间的所有功能&#xff0c;总页面大概200个&#xff0c;如果你能看完整个栏目&#xff0c;你肯定能独立完成flutter 项目…...

linux学习实操计划0103-安装软件

本系列内容全部给基于Ubuntu操作系统。 系统版本&#xff1a;#32~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Fri Aug 18 10:40:13 UTC 1 安装deb格式软件 Debian包是Unixar的标准归档&#xff0c;将包文件信息以及包内容&#xff0c;经过gzip和tar打包而成。 处理这些包的经典程序是…...

git vscode

01&#xff1a;工作区 **02&#xff1a;暂存区 git add . 3&#xff1a;本地库 git commit -m ’ 4&#xff1a;远程库 git push example 点击箭头之后...

Linux命令行批量删除文件

1、 删除当前目录下60min前的所有.log结尾文件 find ./ -type f -name "*.log" -mmin 60 -delete 2、删除当前目录下30天前的所有.log结尾文件 find ./ -type f -name "*.log" -mtime 30 -delete...

CAN - 基础

CAN 基础 概念分类特点物理层收发器线与编码方式通信方式采样点/位 常见故障 数据链路层CAN控制器数据帧分类数据帧格式数据帧DBC解析CRC校验远程帧 总线竞争与仲裁非破坏性仲裁机制 节点状态与错误处理机制节点状态错误处理机制错误帧 概念 分类 CANCAN FD高速CAN低俗容错CA…...

【Hash表】找出出现一次的数字-力扣 136

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kuan 的首页,持续学…...

Resize和centerCrop的区别

首先要记住,transforms只能对PIL读入的图片进行操作,而且PIL和opencv只能读取H * W * C形式的图片。 resize(size)&#xff1a;将图片的短边缩放成size的比例&#xff0c;然后长边也跟着缩放&#xff0c;使得缩放后的图片相对于原图的长宽比不变。如果想要resize成自己想要的图…...

无涯教程-JavaScript - SUM函数

描述 SUM函数可添加值。 语法 SUM (number1, [number2]...)争论 Argument描述Required/Optionalnumber1The first number you want to add. The number can be a value, a cell reference, or a cell range.Requirednumber2, …You can specify up to 255 additional numbe…...

ChatGLM P-Tuningv2微调定制AI大模型

前言 什么是模型微调 想象一下,你正在学习如何弹奏一首钢琴曲目。你已经学会了一些基本的钢琴技巧,但你想要更进一步,尝试演奏一首特定的曲目。这时,你会选择一首你感兴趣的曲目,并开始深度练习。 Fine-tuning(微调)在机器学习中也是类似的概念。当我们使用预先训练好…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动

一、前言说明 在2011版本的gb28181协议中&#xff0c;拉取视频流只要求udp方式&#xff0c;从2016开始要求新增支持tcp被动和tcp主动两种方式&#xff0c;udp理论上会丢包的&#xff0c;所以实际使用过程可能会出现画面花屏的情况&#xff0c;而tcp肯定不丢包&#xff0c;起码…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器

一.自适应梯度算法Adagrad概述 Adagrad&#xff08;Adaptive Gradient Algorithm&#xff09;是一种自适应学习率的优化算法&#xff0c;由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率&#xff0c;适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

剑指offer20_链表中环的入口节点

链表中环的入口节点 给定一个链表&#xff0c;若其中包含环&#xff0c;则输出环的入口节点。 若其中不包含环&#xff0c;则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...

【算法训练营Day07】字符串part1

文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接&#xff1a;344. 反转字符串 双指针法&#xff0c;两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...

ETLCloud可能遇到的问题有哪些?常见坑位解析

数据集成平台ETLCloud&#xff0c;主要用于支持数据的抽取&#xff08;Extract&#xff09;、转换&#xff08;Transform&#xff09;和加载&#xff08;Load&#xff09;过程。提供了一个简洁直观的界面&#xff0c;以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文全面剖析RNN核心原理&#xff0c;深入讲解梯度消失/爆炸问题&#xff0c;并通过LSTM/GRU结构实现解决方案&#xff0c;提供时间序列预测和文本生成…...

初探Service服务发现机制

1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能&#xff1a;服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源&#xf…...

Go 并发编程基础:通道(Channel)的使用

在 Go 中&#xff0c;Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式&#xff0c;用于在多个 Goroutine 之间传递数据&#xff0c;从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...