提问人:Paul 提问时间:10/9/2023 最后编辑:Heretic MonkeyPaul 更新时间:10/9/2023 访问量:26
js 文件格式化为 json 的 .ssh/config
Js file formatting in json of the .ssh/config
问:
我有以下文件:
# Personal account - default config
Host github.com-user1
HostName github.com
User git
IdentityFile ~/.ssh/id_rsa_user1
# Official account
Host github.com-user2
HostName github.com
User git
IdentityFile ~/.ssh/id_rsa_user2
我希望它成为以下 JSON:
[
{
Host: 'github.com-user1',
HostName: 'github.com',
User: 'git',
IdentityFile: '~/.ssh/id_rsa_user1'
},
{
Host: 'github.com-user2',
HostName: 'github.com',
User: 'git',
IdentityFile: '~/.ssh/id_rsa_user2'
}
]
应该删除多少条以 # 开头的注释,键的名称将是该行的第一个元素,其值在空格之后找到。
我写了下面的代码,它可以工作,但我想优化它。 例如,它不接受reduce中的最后一个元素,我不得不将其插入到reduce之外。
除了输入的键值之外,可能还有其他键值,例如 ForwardAgent、AddKeysToAgent 和 UseKeyChain。
唯一可以肯定的是,每个帐户都必须从主机密钥开始。
你能帮我一把吗?
import { exec as cExec } from "child_process";
import { promisify } from "util";
const exec = promisify(cExec);
async function ssh() {
const cmd = 'while IFS= read -r line; do echo "$line"; done < "$HOME/.ssh/config"'
const { stdout, stderr } = await exec(cmd);
if (stderr) throw new Error(stderr);
const a = stdout.replace("\n", "");
let obj = {};
const b = stdout.trim().split("\n").reduce((r, a) => {
if (!a.includes("#")) {
let [name, value] = a.trim().split(" ");
if (name === "Host") {
if (Object.keys(obj).length > 0) r.push(obj);
obj = {};
obj[name] = value;
} else {
obj[name] = value;
}
}
return r;
}, []);
if (Object.keys(obj).length > 0) b.push(obj);
return b
}
答:
0赞
Tomi
10/9/2023
#1
最好使用现有的库来解析 ssh 配置,比如 ssh-config。
ssh 配置格式比您想象的要复杂。例如,您遗漏的一些细节:
- 关键字可以不区分大小写
#
只有当行以 it 开头时,才是一个注释- 某些关键字可能具有多个带引号或空格分隔的参数,而不仅仅是 1 个值
- 该关键字还开始了一个新部分,而不仅仅是
Match
Host
ssh-config 库可以处理这个问题。
但是,既然你问了“reduce”:抽象地说,如果你正在解析一个没有良好现有库的类似格式,那么实现的结构可以是这样的:
const content = fs.readFileSync(process.env.HOME + "/.ssh/config", "utf8");
const sections = [];
for (const line of content.trim().split("\n")) {
if (line.trim() === "" || line.includes("#")) {
continue;
}
let [name, value] = line.trim().split(" ");
if (name === "Host" || sections.length === 0) {
sections.push({});
}
sections[sections.length - 1][name] = value;
}
return sections;
请注意,此代码并不能解决上述问题!这只是一个例子,你仍然应该使用一个库!
评论
JSON.stringify