12. SubProcess
The subprocess object is a built-in object that provides process communication functions between external applications using pipes.
Functional overview:
- Provides the ability to respectively pipe standard input (stdin), standard output (stdout), and standard error output (stderr) of an external application and send and receive data in real time.
- Provides the function to send specific signals to external applications.
- Provides the function to retrieve the exit code of an external application.
Limitations:
- The number of command execution resources that can be used is
5
. (Version 00.00.03+) (Previous version:3
)
subprocess Global Object
Methods()/Properties | Summary | Version | Note |
---|---|---|---|
subprocess.create() | Creates a command execution instance. |
subprocess.create(cmd[,options])
Creates a command execution instance.
Name | Type | M/O | Summary | Note |
---|---|---|---|---|
cmd | string, Array | mandatory | Specify the command execution path in string. If command arguments are required, specify them separated by spaces after the command execution path. If a string containing a space character is to be treated as a single argument, enclose the target string range in single quote ' or double quote " . The maximum number of command characters is 4095 bytes and the maximum number of command argument including command execution path is 32 .Specify the command execution path in an array of strings. If command arguments are required, specify them additionally in the element after the command execution path. The maximum length of the array is 32 , and the total size of the string length of each element plus 1 must be within 4096 bytes. | Using redirects or pipes to execute multiple commands in combination is not supported. ( Array supported: Version 00.00.03+) |
options | Object | optional | Options Refer to Options for details. | |
return | {Exec}, null | - | {Exec} : Generated {Exec} null : If instance creation fails due to lack of resources | If the parameter is abnormal, an exception occurs. |
Options
Name | Type | M/O | Summary | Note |
---|---|---|---|---|
readBuffSize | number | optional | Read buffer size [Byte] Range: 1 - 2,147,483,647 The default value is 4096. | |
abortSigNo | number | optional | Signal number for forced termination Specify the signal number to be sent when forcibly aborting the command execution process by .abort() method call, etc. Note that the execution process must always be terminable by this signal number. Range: 1 (SIGHUP), 2 (SIGINT), 9 (SIGKILL), 15 (SIGTERM)The default value is 15 (SIGTERM). |
The following is a usage example.
When handling simple commands, it is useful to specify by string.
If the command argument contains single quote '
or double quote "
, or when handling complex commands, it is useful to specify by array.
var exec = subprocess.create('date');
var exec = subprocess.create("uname -a");
var exec = subprocess.create("ls -l /tmp");
var exec = subprocess.create("cat /tmp/memo.txt");
var exec = subprocess.create("tail -f /tmp/memo.txt");
var exec = subprocess.create('/usr/bin/myApp "hello world"');
var exec = subprocess.create('/home/user/start.sh "abc" 1 2 3');
var exec = subprocess.create(['date']);
var exec = subprocess.create(['uname', '-a']);
var exec = subprocess.create(['ls', '-l', "/tmp"]);
var exec = subprocess.create(['cat', "/tmp/memo.txt"]);
var exec = subprocess.create(['tail', '-f', "/tmp/memo.txt"]);
var exec = subprocess.create(['/usr/bin/myApp', "hello world"]);
var exec = subprocess.create(['/home/user/start.sh', "abc", '1', '2', '3']);
var exec = subprocess.create(['bash', '-c', 'echo "hello world"']);
var exec = subprocess.create(['bash', '-c', "echo \"hello world\""]);
var exec = subprocess.create(['bash', '-c', "grep processor /proc/cpuinfo | wc -l"]);
{Exec}
Methods()/Properties | Summary | Version | Note |
---|---|---|---|
.on() | Registers an event handler. | ||
.execute() | Starts command execution. | ||
.read() | Reads standard output (stdout) data received from the command execution process. | ||
.readError() | Reads standard error output (stderr) data received from the command execution process. | ||
.write() | Sends data to the standard input (stdin) of the command execution process. | ||
.sendSignal() | Sends the specified signal to the command execution process. | ||
.isBusy() | Gets the execution status of the command execution process. | ||
.getResult() | Gets the exit code of the command execution process. | ||
.abort() | Aborts the command execution process forcibly. | ||
.release() | Releases a command execution resource. |
Details
.on(event,callback)
Registers an event handler.
Name | Type | M/O | Summary | Note |
---|---|---|---|---|
event | string | mandatory | Event name Names that can be used are: stdout, stderr, exit | |
callback | function | mandatory | Executes callback processing when an event occurs. | |
return | undefined | - | - | If the parameter is abnormal, an exception occurs. |
event : ’stdout’
Executes callback processing when standard output (stdout) data is received from the command execution process and data is stored in the read buffer.
event : ’stderr’
Executes callback processing when standard error output (stderr) data is received from the command execution process and the data is stored in the read buffer.
event : ’exit’
Executes callback processing when the command execution process is exited.
Note that if the process exits with data in the standard output (stdout) and standard error output (stderr) read buffers, the callback process will not be executed immediately. It is necessary to read all data with the .read() and/or .readError() method.
.execute()
Starts command execution.
The command will be executed with Superuser (root
) privileges.
Name | Type | M/O | Summary | Note |
---|---|---|---|---|
return | boolean | - | true: Success false: Failure |
.read([isBin])
Reads standard output (stdout) data received from the command execution process.
Name | Type | M/O | Summary | Note |
---|---|---|---|---|
isBin | boolean | optional | Specify the readout data format. true: Readout in binary data format false: Readout in string format The default value is false. | |
return | ArrayBuffer, string | - | Readout data The return type is determined by isBin. If isBin is true, the type is ArrayBuffer; otherwise, the type is string. | The readout data will be less than or equal to the size specified by readBuffSize. If there is no readout data, the size will be 0. If the parameter is abnormal, an exception occurs. |
.readError([isBin])
Reads standard error output (stderr) data received from the command execution process.
Name | Type | M/O | Summary | Note |
---|---|---|---|---|
isBin | boolean | optional | Specify the readout data format. true: Readout in binary data format false: Readout in string format The default value is false. | |
return | ArrayBuffer, string | - | Readout data The return type is determined by isBin. If isBin is true, the type is ArrayBuffer; otherwise, the type is string. | The readout data will be less than or equal to the size specified by readBuffSize. If there is no readout data, the size will be 0. If the parameter is abnormal, an exception occurs. |
.write(data)
Sends data to the standard input (stdin) of the command execution process.
Name | Type | M/O | Summary | Note |
---|---|---|---|---|
data | string, ArrayBuffer | mandatory | Sent data | |
return | number | - | Sent data size If the sending fails, -1 is returned. | If the parameter is abnormal, an exception occurs. |
.sendSignal(sigNo)
Sends the specified signal to the command execution process.
Name | Type | M/O | Summary | Note |
---|---|---|---|---|
sigNo | number | mandatory | Signal number Range: 1 - 31 | |
return | boolean | - | true: Success false: Failure | If the parameter is abnormal, an exception occurs. |
.isBusy()
Gets the execution status of the command execution process.
Name | Type | M/O | Summary | Note |
---|---|---|---|---|
return | boolean | - | Execution state true: In process false: Terminated or stopped state |
.getResult()
Gets the exit code of the command execution process.
This method is used after the command execution process is exited.
Name | Type | M/O | Summary | Note |
---|---|---|---|---|
return | {ExecStatus} | - | {ExecStatus} : Exit code |
{ExecStatus}
The exit code and the exit signal number are basically exclusive, with either one having the invalid value -1
.
If the command has not been executed or is in progress, all property values are set to -1
.
Name | Type | Summary | Note |
---|---|---|---|
.exitCode | number | Exit code of the command execution process (0 - 255) The exit code is set when the command execution process exits normally. | |
.sigNo | number | Exit signal number of the command execution process If the command execution process is terminated by a signal, the signal number that caused the termination is set. | |
.wstatus | number | Exit Status Information (Reference data) This value is the original data in which the exit code and the exit signal information are stored. |
.abort()
Aborts the command execution process forcibly.
This method is valid only when the command is in progress.
Name | Type | M/O | Summary | Note |
---|---|---|---|---|
return | undefined | - | - |
.release()
Releases a command execution resource.
The command in execution will be forced to terminate.
Name | Type | M/O | Summary | Note |
---|---|---|---|---|
return | undefined | - | - |
Object Usage Examples
Sample 1
This is a sample of executing a command.
Execute the uname -a
command to display system information.
var exec = subprocess.create("uname -a");
exec.execute();
while(1) {
var resp = exec.read();
if(resp.length) {
print('response : ' + resp);
}
if(!exec.isBusy()) {
break;
}
}
exec.release();
exec = undefined;
print('done');
Sample 2
This is a sample of executing a command using the .on() event callback.
Execute the uname -a
command to display system information.
var done = false;
var exec = subprocess.create("uname -a");
exec.on('stdout', function() {
var resp = exec.read();
print('response : ' + resp);
});
exec.on('exit', function() {
done = true;
});
exec.execute();
while(1) {
if(done) {
break;
}
}
exec.release();
exec = undefined;
print('done');
Sample 3
This is a sample that directly executes a shell command from neqto.js via the bash command.
Periodically executes commands while maintaining command execution resources and displays disk usage of the /tmp
area.
var timerInterval = 1000; //ms
var maxNumOfTimes = 20;
var shellCmd = "df -h /tmp | sed '1d' | awk '{print $5}'";
//var exec = subprocess.create('bash -c "' + shellCmd + '"');
var exec = subprocess.create(['bash', '-c', shellCmd]);
var resp = false;
var done = false;
exec.on('stdout', function() { resp = true; });
exec.on('exit', function() { done = true; });
var trigger = false;
var tm = setInterval(function() {
if(trigger) print('overwritten');
trigger = true;
}, timerInterval);
var cnt = 0;
var state = 0;
while(1) {
if(state == 0) {
if(trigger) {
exec.execute();
cnt++;
state++;
}
} else if(state == 1) {
if(resp) {
var result = exec.read();
print(cnt, result.replace(/\n/g, ''));
state++;
}
} else if(state == 2) {
if(done) {
trigger = false;
resp = false;
state = 0;
if(cnt >= maxNumOfTimes) break;
}
}
}
clearInterval(tm);
exec.release();
exec = undefined;
print('script done');
Sample 4
This is a sample that executes a shell script file placed externally.
Launches the following test shell script (test.sh) to display the standard output and standard error output received from the shell script. Also, after a certain period of time, sends "end"
via standard input and terminates the shell script.
Before executing this script, it is necessary to place "test.sh" under /tmp
and add execution permission.
test.sh
#!/bin/bash
CNT=0
while true; do
read -t 1 ENTER
if [ -n "$ENTER" ]; then
echo "$ENTER"
break
fi
if [ $((${CNT} % 2)) = 1 ]; then
echo "$CNT" 1>&2
else
echo "$CNT"
fi
CNT=$((CNT+1))
done
neqto.js
var delay = 10000; //ms
var done = false;
var exec = subprocess.create('/tmp/test.sh');
if(!exec) { throw new Error('Subprocess is out of resource'); }
exec.on('stdout', function() {
var str = exec.read();
print('stdout : ' + str.replace(/\n/g, ''));
});
exec.on('stderr', function() {
var str = exec.readError();
print('stderr : ' + str.replace(/\n/g, ''));
});
exec.on('exit', function() {
done = true;
});
exec.execute();
var tm = setTimeout(function() {
exec.write('end\n');
}, delay);
while(1) {
if(done) {
var res = exec.getResult();
print('.exitCode : ' + res.exitCode)
print('.sigNo : ' + res.sigNo)
break;
}
}
clearTimeout(tm);
exec.release();
exec = undefined;
print('script done');
Sample 5
This is a sample of executing a shell script directly from on neqto.js utilizing the bash command.
Place the "test.sh" used in Sample 4 on neqto.js and execute it directly.
var delay = 10000; //ms
var shellCmd =
"CNT=0\n" +
"while true; do\n" +
"read -t 1 ENTER\n" +
"if [ -n \"$ENTER\" ]; then\n" +
"echo \"$ENTER\"\n" +
"break\n" +
"fi\n" +
"if [ $((${CNT} % 2)) = 1 ]; then\n" +
"echo \"$CNT\" 1>&2\n" +
"else\n" +
"echo \"$CNT\"\n" +
"fi\n" +
"CNT=$((CNT+1))\n" +
"done\n" +
"";
var done = false;
var exec = subprocess.create(['bash', '-c', shellCmd]);
if(!exec) { throw new Error('Subprocess is out of resource'); }
exec.on('stdout', function() {
var str = exec.read();
print('stdout : ' + str.replace(/\n/g, ''));
});
exec.on('stderr', function() {
var str = exec.readError();
print('stderr : ' + str.replace(/\n/g, ''));
});
exec.on('exit', function() {
done = true;
});
exec.execute();
var tm = setTimeout(function() {
exec.write('end\n');
}, delay);
while(1) {
if(done) {
var res = exec.getResult();
print('.exitCode : ' + res.exitCode)
print('.sigNo : ' + res.sigNo)
break;
}
}
clearTimeout(tm);
exec.release();
exec = undefined;
print('script done');