Home > front end >  NodeJS child.exec bash argument is empty
NodeJS child.exec bash argument is empty

Time:06-20

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\'"'

CodePudding user response:

Your issue is here:

if ( hosts = "" ){
    hosts = "na";
}

Try this:

if ( hosts == "" ){
    hosts = "na";
}
  • Related