如何通过SSH.NET在.NET中修改远程Linux服务器文件?
远程Linux文件修改的正确做法
为什么用System.IO.File会报错
System.IO.File是针对本地文件系统设计的工具,它无法识别远程服务器路径——你传入的/home/user/test.properties会被它直接解析成Windows本地路径C:\home\user\test.properties,找不到文件是必然的。必须使用SSH.NET提供的远程文件操作能力,或者直接在远程服务器执行命令来修改文件。
方法一:用SFTP操作(推荐)
SSH.NET自带SftpClient,可以直接完成远程文件的下载、本地修改、上传覆盖全流程,步骤清晰可靠:
using (var sshClient = new SshClient(server, username, password)) using (var sftpClient = new SftpClient(server, username, password)) { sshClient.Connect(); sftpClient.Connect(); string remoteFilePath = "/home/user/test.properties"; // 生成本地临时文件路径 string localTempFile = Path.GetTempFileName(); try { // 下载远程文件到本地 using (var localStream = File.OpenWrite(localTempFile)) { sftpClient.DownloadFile(remoteFilePath, localStream); } // 本地修改文件内容,这里以替换配置项为例 string content = File.ReadAllText(localTempFile); content = content.Replace("old_config=123", "new_config=456"); File.WriteAllText(localTempFile, content); // 上传修改后的文件覆盖远程原文件 using (var localStream = File.OpenRead(localTempFile)) { sftpClient.UploadFile(localStream, remoteFilePath, true); // true表示覆盖已有文件 } } finally { // 清理本地临时文件 if (File.Exists(localTempFile)) { File.Delete(localTempFile); } sftpClient.Disconnect(); sshClient.Disconnect(); } }
如果当前账号没有直接访问目标文件的权限,需要通过sudo提权的话,建议先通过SSH命令临时调整文件权限,或者直接用目标用户的账号连接SFTP更省事。
方法二:直接在远程执行命令修改
别用交互式的vi命令了,改用非交互式的sed等命令直接修改文件,不需要处理复杂的Shell交互逻辑:
using (var client = new SshClient(server, username, password)) { client.Connect(); // 用sudo切换到user用户,执行sed替换配置项 string modifyCmd = @"sudo su - user -c 'sed -i ""s/old_config=123/new_config=456/g"" /home/user/test.properties'"; var result = client.RunCommand(modifyCmd); if (!string.IsNullOrEmpty(result.Error)) { Console.WriteLine($"修改出错:{result.Error}"); } else { Console.WriteLine("文件修改完成"); } client.Disconnect(); }
要是sudo需要输入密码怎么办?
如果你的账号执行sudo必须输入密码,RunCommand无法处理这种交互场景,就得用ShellStream模拟手动输入的流程:
private static void ModifyFileWithSudoPassword(ShellStream stream, string sudoPassword) { // 发送修改命令 stream.WriteLine(@"sudo su - user -c 'sed -i ""s/old/new/g"" /home/user/test.properties'"); Thread.Sleep(500); // 输入sudo密码 stream.WriteLine(sudoPassword); Thread.Sleep(500); // 发送标记确认执行完成 stream.WriteLine("echo modify-done"); // 等待并读取输出结果 while (stream.Length == 0) Thread.Sleep(500); string output = stream.ReadToEnd(); Console.WriteLine(output); }
内容的提问来源于stack exchange,提问作者ShlomiK
相关产品推荐
相关产品推荐

