From d7f071d4d2b3f91de77b57a85bcf2647d2484e2c Mon Sep 17 00:00:00 2001 From: mirivlad Date: Mon, 23 Feb 2026 16:17:46 +0800 Subject: [PATCH] Save working directory after compound cd commands Co-authored-by: Qwen-Coder --- bot.py | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/bot.py b/bot.py index eaad6d5..50a63eb 100644 --- a/bot.py +++ b/bot.py @@ -681,6 +681,73 @@ async def execute_cli_command_from_message(update: Update, command: str): ) return + # Проверка на составную команду с cd - выполняем и сохраняем конечную директорию + if "cd " in cmd_stripped and ("&&" in cmd_stripped or ";" in cmd_stripped): + # Добавляем pwd в конец для получения конечной директории + command_with_pwd = f"{cmd_stripped} && pwd" + logger.info(f"Выполнение составной команды с cd: {command_with_pwd} в директории: {working_dir}") + + await update.message.reply_text( + f"⏳ *Выполнение...*\n\n`{cmd_stripped}`", + parse_mode="Markdown" + ) + + try: + process = await asyncio.create_subprocess_shell( + command_with_pwd, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, + cwd=working_dir + ) + + stdout, stderr = await asyncio.wait_for( + process.communicate(), + timeout=30 + ) + + output = stdout.decode("utf-8", errors="replace").strip() + error = stderr.decode("utf-8", errors="replace") + + # Последняя строка - это pwd, сохраняем её + if output and process.returncode == 0: + lines = output.split('\n') + final_dir = lines[-1].strip() + # Проверяем, что это действительно путь + if Path(final_dir).is_dir(): + state.working_directory = final_dir + # Убираем pwd из вывода + output = '\n'.join(lines[:-1]) + + result = f"✅ *Результат:*\n\n" + result += f"```\n{cmd_stripped}\n```\n\n" + + if output: + if len(output) > 4000: + output = output[:4000] + "\n... (вывод обрезан)" + result += f"*Вывод:*\n```\n{output}\n```\n" + + if error: + if len(error) > 4000: + error = error[:4000] + "\n... (вывод обрезан)" + result += f"*Ошибки:*\n```\n{error}\n```\n" + + result += f"\n*Код возврата:* `{process.returncode}`" + + await update.message.reply_text(result, parse_mode="Markdown") + + except asyncio.TimeoutError: + await update.message.reply_text( + "❌ *Таймаут*\n\nКоманда выполнялась дольше 30 секунд и была прервана.", + parse_mode="Markdown" + ) + except Exception as e: + logger.error(f"Ошибка выполнения команды: {e}") + await update.message.reply_text( + f"❌ *Ошибка:*\n```\n{str(e)}\n```", + parse_mode="Markdown" + ) + return + logger.info(f"Выполнение команды: {command} в директории: {working_dir}") try: