Dart进程交互方法及Git命令用户名密码输入失败问题
1. 如何在Dart中与进程进行交互?
在Dart里和系统进程交互主要靠dart:io库的Process类,常用的有两种方式,适配不同场景:
Process.run():适合一次性执行命令,等命令跑完直接拿输出和退出码,不需要实时互动。Process.start():适合需要实时通信的场景——比如给进程输入内容、实时监听输出,也就是你代码里用的方式。
基础使用示例
1. 用Process.run()执行简单命令
import 'dart:io'; import 'dart:convert'; void main() async { var result = await Process.run('ls', ['-l']); print('退出码: ${result.exitCode}'); print('标准输出: ${utf8.decode(result.stdout as List<int>)}'); print('错误输出: ${utf8.decode(result.stderr as List<int>)}'); }
2. 用Process.start()做实时交互
这种方式能实时监听进程输出,还能给进程输入数据,比如你尝试和Git交互的场景:
import 'dart:io'; import 'dart:convert'; void interactWithProcess() async { var process = await Process.start('echo', ['Hello, Dart!']); // 监听标准输出 process.stdout.transform(utf8.decoder).listen((output) { print('进程输出: $output'); }); // 监听错误输出 process.stderr.transform(utf8.decoder).listen((error) { print('进程错误: $error'); }); // 等进程结束,拿退出码 var exitCode = await process.exitCode; print('进程退出码: $exitCode'); }
2. 如何在Git命令中传入用户名和密码?(解决你的报错问题)
先拆解你遇到的问题:为什么你的代码只有stderr触发,还报退出码128?
Git需要验证用户名/密码时,根本不会通过stdout输出"Username"或"Password"提示——它是直接从终端的tty设备读取输入的,所以你的stdout监听器根本抓不到这些提示,自然没法往stdin写密码,最后Git因为拿不到密码报错退出(退出码128就是Git认证失败的典型码)。
下面给你几个可行的解决方案:
方案1:在Git远程URL里直接嵌入凭证(临时场景用)
把用户名和密码直接写进远程仓库URL里,Git执行命令时会自动用这个凭证,不用交互:
import 'dart:io'; import 'dart:convert'; void shell() async { // 替换成你的实际仓库地址,格式:https://用户名:密码@仓库地址 var repoUrl = "https://user.name:123456789@bitbucket.org/your-username/your-repo.git"; // 先临时把远程地址改成带凭证的版本 var setUrlProcess = await Process.start( 'git', ["remote", "set-url", "origin", repoUrl], workingDirectory: "directory/repot" ); await setUrlProcess.exitCode; // 等设置完成 // 再执行remote show origin命令 var process = await Process.start( 'git', ["remote", "show", "origin"], workingDirectory: "directory/repot" ); process.stdout.transform(utf8.decoder).listen((event) { print("git命令输出: " + event); }); process.stderr.transform(utf8.decoder).listen((event) { print("错误输出: " + event); }); var exitCode = await process.exitCode; print("退出码: " + exitCode.toString()); }
注意:这种方式会把明文密码存在Git配置里,有安全风险,只建议在测试或临时场景用,用完记得改回原远程地址。
方案2:用Git凭证助手存凭证(推荐)
为了安全,推荐用Git的凭证助手来存用户名和密码,之后执行Git命令就不用手动输入了:
- 先在终端配置凭证助手(以存到系统密钥链为例):
# 存储到本地文件(简单但不如密钥链安全) git config --global credential.helper store # macOS用系统密钥链 # git config --global credential.helper osxkeychain # Windows用系统凭据管理器 # git config --global credential.helper wincred
- 手动执行一次需要验证的Git命令(比如
git pull),输入用户名和密码后,Git会自动存好凭证。 - 之后在Dart里执行Git命令,直接跑就行,不用管密码输入:
import 'dart:io'; import 'dart:convert'; void shell() async { var process = await Process.start( 'git', ["remote", "show", "origin"], workingDirectory: "directory/repot" ); process.stdout.transform(utf8.decoder).listen((event) { print("git命令输出: " + event); }); process.stderr.transform(utf8.decoder).listen((event) { print("错误输出: " + event); }); var exitCode = await process.exitCode; print("退出码: " + exitCode.toString()); }
方案3:通过环境变量传凭证
你可以设置GIT_USERNAME和GIT_PASSWORD环境变量,配合Git的credential.helper自动填充凭证:
import 'dart:io'; import 'dart:convert'; void shell() async { // 复制当前环境变量,再加上Git凭证 var env = { ...Platform.environment, 'GIT_USERNAME': 'user.name', 'GIT_PASSWORD': '123456789' }; var process = await Process.start( 'git', ["-c", "credential.helper='!f() { echo username=\$GIT_USERNAME; echo password=\$GIT_PASSWORD; }; f'", "remote", "show", "origin"], workingDirectory: "directory/repot", environment: env ); process.stdout.transform(utf8.decoder).listen((event) { print("git命令输出: " + event); }); process.stderr.transform(utf8.decoder).listen((event) { print("错误输出: " + event); }); var exitCode = await process.exitCode; print("退出码: " + exitCode.toString()); }
内容的提问来源于stack exchange,提问作者Tiago P Casemiro
相关产品推荐
相关产品推荐

