nodejs child.exec bash参数为空
我正在运行一个类似的脚本:
const someString = "text@ip:ip,text@ip:,";
const arg2 = "5";
let result = await new Promise((resolve, reject) => {
child.exec(`"/path/to/script.sh" "${someString}" "${arg2}"`,
(error=child.ExecException, stdout=string, stderr=string) => {
if (error) {
isErr = true;
reject(error);
}else {
resolve(stdout);
}
});
});
脚本接收arg2
罚款为$ 2
。但是,$ 1
显示一个空白字符串。我已经在我的node.js应用程序中记录了字符串,这是正确的。可能与字符串中的特殊字符有关吗?
相对于应用程序,需要异步运行脚本,并且相对于其父函数同步运行(在上面的代码段中是这种情况)。
编辑: 这是我无法使用的原始代码。它是动态生成一个可行的库存。
nodejs:
async function buildInventory(site){
const agentNumber = site.agentData.agentNumber;
let hostsByType = {};
let hosts = "";
if ( site.hosts.length > 0 ){
site.hosts.forEach(host => {
if (hostsByType.hasOwnProperty(`${host.type}`)) {
hostsByType[`${host.type}`].push(`${host.ip}`);
}else{
hostsByType[`${host.type}`] = [ `${host.ip}` ];
}
});
}
if ( hostsByType != {} ){
for (const key in hostsByType) { // create arg in format type@ip:,type@ip:ip:,
if (Object.hasOwnProperty.call(hostsByType, key)) {
hosts = hosts + `${key}@`;
hostsByType[key].forEach(ip => {
hosts = hosts + `${ip}:`;
});
hosts = hosts + ',';
}
console.log(hosts); // string logged is in expected format
}
}
if ( hosts = "" ){
hosts = "na";
}
let isErr = false;
let result = await new Promise((resolve, reject) => {
child.exec(`"/usr/raindrop/app/ansible/mkinv" "${hosts}" "${agentNumber}"`,
(error=child.ExecException, stdout=string, stderr=string) => {
if (error) {
isErr = true;
reject(error);
}else {
resolve(stdout);
}
});
});
if( !isErr ){
result = result.split(/\r?\n/)[0];
if ( result == "genskipped" ){
logger.log('info', `Inventory generation skipped(no hosts)`);
return true;
}else if ( result == "gensuccess"){
logger.log('info', `Inventory generated`);
return true;
}else {
logger.log('warn', `Unknown response from inventory generation script`);
console.log(result);
return false;
}
}else{
logger.log('error', `Inventory generation error: ${result}`);
return false;
}
}
bash脚本:
#!/bin/bash
mkdir -p /data/ansible/$2
cd /data/ansible/$2
while [[ $1 == "na" ]];do
echo "genskip"
exit 0;
done
touch inventory.yml
echo "all:" > inventory.yml
echo " children:" >> inventory.yml
IFS=',' read -a hostsByType <<< "$1" # arg in format type@ip:,type@ip:ip:,
echo $1 >> /logs/ansible-debug.log
for val in "$hostsByType";do
while [[ "$val" != "" ]];do
IFS='@' read -a data <<< "$val"
echo " ${data[0]}:" >> inventory.yml
IFS=':' read -a hosts <<< "${data[1]}"
c=1
for host in "$hosts";do
while [[ "$host" != "" ]];do
echo " host${c}: $host"
c=$(($c + 1))
break;
done
done
break;
done
done
subnet=$(cat /data/vpn/rain.conf | grep 'ipv4=')
IFS='=' read -a arr <<< $subnet
subnet=${arr[1]}
agent_ip="${subnet}${2}"
echo " vars:" >> inventory.yml
echo " ansible_port: 22" >> inventory.yml
echo " ansible_user: sisadm" >> inventory.yml
echo " private_key_file: /data/ssh/keys/$2" >> inventory.yml
echo " ansible_ssh_common_args: '-o StrictHostKeyChecking=no -o ProxyCommand=\"ssh -o \'ForwardAgent yes\' agent@$agent_ip -p 11522 \'ssh-add /home/agent/.ssh/id_rsa && nc %h %p\'\"'" >> inventory.yml
echo "gensuccess"
edit2: /logs/asible-debug.log
每次运行脚本时都会显示一条新行。 库存。脚本创建:
all:
children:
vars:
ansible_port: 22
ansible_user: sisadm
private_key_file: /data/ssh/keys/2
ansible_ssh_common_args: '-o StrictHostKeyChecking=no -o ProxyCommand="ssh -o \'ForwardAgent yes\' [email protected] -p 11522 \'ssh-add /home/agent/.ssh/id_rsa && nc %h %p\'"'
I'm running a script like so:
const someString = "text@ip:ip,text@ip:,";
const arg2 = "5";
let result = await new Promise((resolve, reject) => {
child.exec(`"/path/to/script.sh" "${someString}" "${arg2}"`,
(error=child.ExecException, stdout=string, stderr=string) => {
if (error) {
isErr = true;
reject(error);
}else {
resolve(stdout);
}
});
});
The script receives arg2
fine as $2
. However, $1
shows a blank string. I've logged the string in my Node.js app and it is correct. Possibly something to do with special characters in the string?
The script need to be run asynchronously relative to the application and synchronously relative to it's parent function(which is the case in the code snippet above).
EDIT:
Here is the original code that I can't get working. It is to dynamically generate an ansible inventory.
nodejs:
async function buildInventory(site){
const agentNumber = site.agentData.agentNumber;
let hostsByType = {};
let hosts = "";
if ( site.hosts.length > 0 ){
site.hosts.forEach(host => {
if (hostsByType.hasOwnProperty(`${host.type}`)) {
hostsByType[`${host.type}`].push(`${host.ip}`);
}else{
hostsByType[`${host.type}`] = [ `${host.ip}` ];
}
});
}
if ( hostsByType != {} ){
for (const key in hostsByType) { // create arg in format type@ip:,type@ip:ip:,
if (Object.hasOwnProperty.call(hostsByType, key)) {
hosts = hosts + `${key}@`;
hostsByType[key].forEach(ip => {
hosts = hosts + `${ip}:`;
});
hosts = hosts + ',';
}
console.log(hosts); // string logged is in expected format
}
}
if ( hosts = "" ){
hosts = "na";
}
let isErr = false;
let result = await new Promise((resolve, reject) => {
child.exec(`"/usr/raindrop/app/ansible/mkinv" "${hosts}" "${agentNumber}"`,
(error=child.ExecException, stdout=string, stderr=string) => {
if (error) {
isErr = true;
reject(error);
}else {
resolve(stdout);
}
});
});
if( !isErr ){
result = result.split(/\r?\n/)[0];
if ( result == "genskipped" ){
logger.log('info', `Inventory generation skipped(no hosts)`);
return true;
}else if ( result == "gensuccess"){
logger.log('info', `Inventory generated`);
return true;
}else {
logger.log('warn', `Unknown response from inventory generation script`);
console.log(result);
return false;
}
}else{
logger.log('error', `Inventory generation error: ${result}`);
return false;
}
}
bash script:
#!/bin/bash
mkdir -p /data/ansible/$2
cd /data/ansible/$2
while [[ $1 == "na" ]];do
echo "genskip"
exit 0;
done
touch inventory.yml
echo "all:" > inventory.yml
echo " children:" >> inventory.yml
IFS=',' read -a hostsByType <<< "$1" # arg in format type@ip:,type@ip:ip:,
echo $1 >> /logs/ansible-debug.log
for val in "$hostsByType";do
while [[ "$val" != "" ]];do
IFS='@' read -a data <<< "$val"
echo " ${data[0]}:" >> inventory.yml
IFS=':' read -a hosts <<< "${data[1]}"
c=1
for host in "$hosts";do
while [[ "$host" != "" ]];do
echo " host${c}: $host"
c=$(($c + 1))
break;
done
done
break;
done
done
subnet=$(cat /data/vpn/rain.conf | grep 'ipv4=')
IFS='=' read -a arr <<< $subnet
subnet=${arr[1]}
agent_ip="${subnet}${2}"
echo " vars:" >> inventory.yml
echo " ansible_port: 22" >> inventory.yml
echo " ansible_user: sisadm" >> inventory.yml
echo " private_key_file: /data/ssh/keys/$2" >> inventory.yml
echo " ansible_ssh_common_args: '-o StrictHostKeyChecking=no -o ProxyCommand=\"ssh -o \'ForwardAgent yes\' agent@$agent_ip -p 11522 \'ssh-add /home/agent/.ssh/id_rsa && nc %h %p\'\"'" >> inventory.yml
echo "gensuccess"
EDIT2:/logs/ansible-debug.log
shows a new line every time the script is run.
The inventory.yml the script creates:
all:
children:
vars:
ansible_port: 22
ansible_user: sisadm
private_key_file: /data/ssh/keys/2
ansible_ssh_common_args: '-o StrictHostKeyChecking=no -o ProxyCommand="ssh -o \'ForwardAgent yes\' [email protected] -p 11522 \'ssh-add /home/agent/.ssh/id_rsa && nc %h %p\'"'
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的问题在这里:
尝试以下操作:
Your issue is here:
Try this: