Custom agent monitor in Peach fuzzer - python

Is it possible to use a python file as Agent Monitor in place of WindowsDebugger monitor in peach? If yes, is there any guide that has the specifications (if any) for the python file?

Maybe a little late
But maybe you can use the socket monitor: peach will consider a fault if it receive a message on a specific socket:
<Agent name="Local">
<Monitor class="Socket">
<Param name="Port" value="6666" />
<Param name="Timeout" value="5000" />
</Monitor>
</Agent>
and an example (process detection in powershell)
$q = "Select * from win32_ProcessStartTrace where processname 'Process.exe'"
$port=6666
$remoteHost = "127.0.0.1"
$message = "[fault]"
Register-CimIndicationEvent -Query $q -SourceIdentifier test
while ($true) {
Start-Sleep -Seconds 1
$var = (Get-Event -SourceIdentifier test -ErrorAction SilentlyContinue | findstr "RunspaceId")
if ($var) {
echo "Fault detected"
$socket = new-object System.Net.Sockets.TcpClient($remoteHost, $port)
$data = [System.Text.Encoding]::ASCII.GetBytes($message)
$stream = $socket.GetStream()
$stream.Write($data, 0, $data.Length)
Remove-Event -SourceIdentifier test
$var = $null
}
}

Related

Wordpress Password Saving Functions To Python

3 weeks back I posted a question on here to understand how WordPress saves passwords to db. Mystical suggested I look at the source code, and I tried to but I am not too good with php so I am trying to convert relevant functions to python. Here is what I have so far:
Python:
import base64
from email.encoders import encode_base64
from hashlib import md5
prefix = '$P$B'
salt = 'KcFRBGXE'
password = '^zVw*wSFshV2' #password i enter to login
real_hashed_pass = '$P$BKcFRBGXEWOVYQShBC1edT7f3e3Nca1' #this is stored in wp db
hashed_pass = md5((salt + password).encode('utf-8')).hexdigest()
for i in range(8193):
hashed_pass = md5((hashed_pass + password).encode('utf-8')).hexdigest()
# for i in range(17):
# hashed_pass = base64.standard_b64encode(hashed_pass)
hashed_pass = prefix + salt + hashed_pass
print(hashed_pass == real_hashed_pass)
Relevant PHP (full code):
<?php
class PasswordHash {
var $itoa64;
var $iteration_count_log2;
var $portable_hashes;
var $random_state;
function __construct($iteration_count_log2, $portable_hashes)
{
$this->itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
if ($iteration_count_log2 < 4 || $iteration_count_log2 > 31)
$iteration_count_log2 = 8;
$this->iteration_count_log2 = $iteration_count_log2;
$this->portable_hashes = $portable_hashes;
$this->random_state = microtime();
if (function_exists('getmypid'))
$this->random_state .= getmypid();
}
function encode64($input, $count)
{
$output = '';
$i = 0;
do {
$value = ord($input[$i++]);
$output .= $this->itoa64[$value & 0x3f];
if ($i < $count)
$value |= ord($input[$i]) << 8;
$output .= $this->itoa64[($value >> 6) & 0x3f];
if ($i++ >= $count)
break;
if ($i < $count)
$value |= ord($input[$i]) << 16;
$output .= $this->itoa64[($value >> 12) & 0x3f];
if ($i++ >= $count)
break;
$output .= $this->itoa64[($value >> 18) & 0x3f];
} while ($i < $count);
return $output;
}
function crypt_private($password, $setting)
{
$output = '*0';
if (substr($setting, 0, 2) === $output)
$output = '*1';
$id = substr($setting, 0, 3);
# We use "$P$", phpBB3 uses "$H$" for the same thing
if ($id !== '$P$' && $id !== '$H$')
return $output;
$count_log2 = strpos($this->itoa64, $setting[3]);
if ($count_log2 < 7 || $count_log2 > 30)
return $output;
$count = 1 << $count_log2;
$salt = substr($setting, 4, 8);
if (strlen($salt) !== 8)
return $output;
# We were kind of forced to use MD5 here since it's the only
# cryptographic primitive that was available in all versions
# of PHP in use. To implement our own low-level crypto in PHP
# would have resulted in much worse performance and
# consequently in lower iteration counts and hashes that are
# quicker to crack (by non-PHP code).
$hash = md5($salt . $password, TRUE);
do {
$hash = md5($hash . $password, TRUE);
} while (--$count);
$output = substr($setting, 0, 12);
$output .= $this->encode64($hash, 16);
return $output;
}
function CheckPassword($password, $stored_hash)
{
if ( strlen( $password ) > 4096 ) {
return false;
}
$hash = $this->crypt_private($password, $stored_hash);
if ($hash[0] === '*')
$hash = crypt($password, $stored_hash);
# This is not constant-time. In order to keep the code simple,
# for timing safety we currently rely on the salts being
# unpredictable, which they are at least in the non-fallback
# cases (that is, when we use /dev/urandom and bcrypt).
return $hash === $stored_hash;
}
}
My goal is to have the python code produce the same hashed password as the wordpress code. I think the error in the python code is at the commented out loop but I am not sure how to fix it.
Thank you for the help!
UPDATE
When someone enters their passcode you hash it.
$hash1 = hash('ripemd320',$passcode);
$sql = "SELECT `hash` FROM `Client` WHERE `Number` = $client LIMIT 1";
$results = mysqli_query($link,$sql);
list($hash2) = mysqli_fetch_array($results, MYSQLI_NUM);
if($hash1 == $hash2){unlock the pearly gates;}
END OF UPDATE
No 0one should ever save a password in a db. So when you ask "how WordPress saves passwords to db" the answer is they do not.
Are you working ona Word Press add on or do you want to "save passwords" in the same manner as WP?
Word Press is not the place to copy any PHP coding techniques.
When you bring Python into the equation I have to think you are not working with WP but want to do it the same was as WP. That would be a bad idea.
Passwords are not that complicated. And it only takes a few lines of code.
When the password is created you save the hash in the user's table. When they login you get the hash from the table, hash the password given and compare the two.
I recommend using only numerical usernames. Then when you get the username you convert it to an integer and SQL injection is impossible.

Jenkins build failing without updating Xray with the failed status

Please forgive me if this is not the place to ask this question. I'm running python scripts in a Jenkins pipeline from a Jenkinsfile. I am also updating Jira Xray tickets within the Jenkisfile. Behave is being used to validate the test status. If the check fails then the Jenkins build fails without getting the Xray ticket updated with the failure. I've attempted to use "try" to capture the failure but have not succeeded in getting the failure to propagate to the Xray ticket.
Would anyone here know where I might find an answer? I would be in your dept.
Jenkinsfile
node() {
def repoURL = '<GitLab URL>/prod-003.git'
def STC_INSTALL = "/opt/STC_CLIENT/Spirent_TestCenter_5.22/Spirent_TestCenter_Application_Linux/"
try {
stage("Prepare Workspace") {
echo "*** Prepare Workspace ***"
cleanWs()
env.WORKSPACE_LOCAL = sh(returnStdout: true, script: 'pwd').trim()
env.BUILD_TIME = "${BUILD_TIMESTAMP}"
echo "Workspace set to:" + env.WORKSPACE_LOCAL
echo "Build time:" + env.BUILD_TIME
sh """
cd ${env.WORKSPACE_LOCAL}
rm -fr *
"""
}
stage('Checkout Code') {
echo "*** Checking Code Out ***"
git branch: 'master', credentialsId: '', url: repoURL
}
stage('Executing Tests') {
if (env.WanModeCheck == "Yes") {
echo "Executing WAN Mode Change Before FW Upgrade"
sh """
/var/lib/jenkins/.pyenv/shims/python WanMode.py -i $modemIP -m $WanMode
"""
echo "Starting Firmware Upgrade"
sh """
cd ${env.WORKSPACE_LOCAL}
./ModemUpgrade.sh -i $modemIP -f $FW -p2
/var/lib/jenkins/.pyenv/shims/behave -f cucumber -o storetarget-bdd/reporting/cucumber.json --junit --format=json -o target/behave.json --junit ./features/PROD-003.feature
"""
} else {
echo "#######################\n# Skipping WAN Mode Change #\n#######################"
}
if (env.WanModeCheck == "No") {
echo "Starting Firmware Upgrade"
sh """
cd ${env.WORKSPACE_LOCAL}
./ModemUpgrade.sh -i $modemIP -f $FW -p2
/var/lib/jenkins/.pyenv/shims/behave -f cucumber -o storetarget-bdd/reporting/cucumber.json --junit --format=json -o target/behave.json --junit ./features/fwupgrade.feature
"""
}
// Setting variables to use for the Xray Test Execution
res = sh(returnStdout: true, script: 'awk "/##/{f=1;next} /#####/{f=0} f" PROD-003-Out.txt | sed -e "s/#//g" -e "s/^ * //g" | tr "\n" "%" | sed -e "s/^%%%%%%//g" -e "s/%%$//g" -e "s/%/\\\\\\\\Z/g" -e "s/Z/n/g"')
env.STResults = res.strip()
model = sh(returnStdout: true, script: 'grep Model: PROD-003-Out.txt')
env.Model = model.strip()
wanmode = sh(returnStdout: true, script: 'grep CPE PROD-003-Out.txt')
env.WanMode = wanmode.strip()
serialnum = sh(returnStdout: true, script: 'grep Number: PROD-003-Out.txt')
env.SerialNum = serialnum.strip()
echo "End of test phase"
}
stage('Expose report') {
echo "*** Expose Reports ***"
echo "*** Archive Artifacts ***"
archiveArtifacts "**/cucumber.json"
echo "*** cucumber cucumber.json ***"
cucumber '**/cucumber.json'
junit skipPublishingChecks: true, allowEmptyResults: true, keepLongStdio: true, testResults: 'reports/*.xml'
cucumber buildStatus: "UNSTABLE",
fileIncludePattern: "**/cucumber.json",
jsonReportDirectory: 'reports'
}
stage('Import results to Xray') {
echo "*** Import Results to XRAY ***"
def description = "Jenkins Project: ${env.JOB_NAME}\\n\\nCucumber Test Report: [${env.JOB_NAME}-Link|${env.BUILD_URL}/cucumber-html-reports/overview-features.html]\\n\\nJenkins Console Output: [${env.JOB_NAME}-Console-Link|${env.BUILD_URL}/console]\\n\\nCPE IP: ${modemIP}\\n\\nCPE FW File Name: ${FW}\\n\\n${env.STResults}"
def labels = '["regression","automated_regression"]'
def environment = "DEV"
def testExecutionFieldId = 10552
def testEnvironmentFieldName = "customfield_10372"
def projectKey = "AARC"
def projectId = 10608
def xrayConnectorId = "e66d84d8-f978-4af6-9757-93d5804fde1d"
// def xrayConnectorId = "${xrayConnectorId}"
def info = '''{
"fields": {
"project": {
"id": "''' + projectId + '''"
},
"labels":''' + labels + ''',
"description":"''' + description + '''",
"summary": "''' + env.JOB_NAME + ' ' + env.Model + ' ' + env.WanMode + ' ' + env.SerialNum + ''' Test Executed ''' + env.BUILD_TIME + ''' " ,
"issuetype": {
"id": "''' + testExecutionFieldId + '''"
}
}
}'''
echo info
step([$class: 'XrayImportBuilder',
endpointName: '/cucumber/multipart',
importFilePath: 'storetarget-bdd/reporting/cucumber.json',
importInfo: info,
inputInfoSwitcher: 'fileContent',
serverInstance: xrayConnectorId])
}
}
catch(e) {
// If there was an exception thrown, the build failed
currentBuild.result = "FAILED"
throw e
} finally {
// Success or failure, always send notifications
echo "Sending final test status to Slack"
// notifyBuild(currentBuild.result)
}
}
def notifyBuild(String buildStatus = 'STARTED') {
// build status of null means successful
buildStatus = buildStatus ?: 'SUCCESSFUL'
// Default values
def colorName = 'RED'
def colorCode = '#FF0000'
def subject = "${buildStatus}: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'"
def summary = "${subject} (${env.BUILD_URL})"
def details = """<p>STARTED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]':</p>
<p>Check console output at &QUOT;<a href='${env.BUILD_URL}'>${env.JOB_NAME} [${env.BUILD_NUMBER}]</a>&QUOT;</p>"""
// Override default values based on build status
if (buildStatus == 'STARTED') {
color = 'BLUE'
colorCode = '#0000FF'
msg = "Build: ${env.JOB_NAME} has started: ${BUILD_TIMESTAMP}"
} else if (buildStatus == 'UNSTABLE') {
color = 'YELLOW'
colorCode = '#FFFF00'
msg = "Build: ${env.JOB_NAME} was listed as unstable. Look at ${env.BUILD_URL} and Report: ${env.BUILD_URL}/cucumber-html-reports/overview-features.html"
} else if (buildStatus == 'SUCCESSFUL') {
color = 'GREEN'
colorCode = '#00FF00'
msg = "Build: ${env.JOB_NAME} Completed Successfully ${env.BUILD_URL} Report: ${env.BUILD_URL}/cucumber-html-reports/overview-features.html"
} else {
color = 'RED'
colorCode = '#FF0000'
msg = "Build: ${env.JOB_NAME} had an issue ${env.BUILD_URL}/console"
}
// Send notifications
slackSend (color: colorCode, message: summary)
slackSend baseUrl: 'https://hooks.slack.com/services/',
channel: '#wopr-private',
color: colorCode,
message: msg,
teamDomain: '<Slack URL>',
tokenCredentialId: 'Jenkins-Slack-Token',
username: 'JenkinsAutomation'
}
feature file
Feature: SNMP Firmware Upgrade Test
#demo #AARC-3428
Scenario: SNMP Firmware Upgrade Executed against the DUT
Given ModemUpgrade.sh Script Exists
When SNMP Firmware Upgrade Executed
Then I expect Result Pass
step file
from behave import *
import pathlib
from pathlib import Path
#given('ModemUpgrade.sh Script Exists')
def step_impl(context):
STCFile = pathlib.Path('ModemUpgrade.sh')
if STCFile.exists():
print("SNMP Firmware Upgrade file exists")
pass
# else:
# print("SNMP Firmware Upgrade file does not exists")
# assert context.failed
#when('SNMP Firmware Upgrade Executed')
def step_impl(context):
path_to_file = 'PROD-003-Out.txt'
path = Path(path_to_file)
if path.is_file():
print(f'Output file {path_to_file} exists')
else:
print(f'Output file {path_to_file} does not exists')
#then('I expect Result Pass')
def step_impl(context):
Result = False
with open("PROD-003-Out.txt") as FwUpgradeResults:
for line in FwUpgradeResults:
if 'Upgrade Status: Passed'.lower() in line.strip().lower():
Result = True
break
else:
Result = False
break
if Result is False:
print("Error: Upgrade Failed")
assert context.failed
The suggestion of using || /usr/bin/true appears to have worked for the above mentioned code. Now I have a second instance where my Python test is throwing an exception when the DUT fails DHCP bind
def wait_for_dhcp_bind():
try:
stc.perform("Dhcpv4BindWait", objectlist=project)
except Exception:
raise Exception("DHCP Bind Failed")
I attempted to add the same after the Python script but the Jenkins build fails without the Xray test getting updated with a failure.
Here is what this looks like in the Jenkinsfile
echo "Starting Speed Test"
// def ModemMac = sh(returnStdout: true, script: './ModemUpgrade.sh -i ${modemIP} -f mac')
sh """
export STC_PRIVATE_INSTALL_DIR=${STC_INSTALL}
cd ${env.WORKSPACE_LOCAL}
/var/lib/jenkins/.pyenv/shims/python SpeedTest.py -d $dsp -u $usp -i $iterations -x $imix -f $frames -m $ModemMac || /usr/bin/true
/var/lib/jenkins/.pyenv/shims/behave -f cucumber -o storetarget-bdd/reporting/cucumber.json --junit --format=json -o target/behave.json --junit ./features/speedtest.feature || /usr/bin/true
"""
Your case should be easy to fix. Behave utility returns exit code 1 if tests fails..
Just add this to the end of your behave command || /usr/bin/true (please make sure of the path of the "true" command).
This will make your command to always return true even if some problems exist with behave.
So your overall command should be something like:
/var/lib/jenkins/.pyenv/shims/behave -f cucumber -o storetarget-bdd/reporting/cucumber.json --junit --format=json -o target/behave.json --junit ./features/PROD-003.feature || /usr/bin/true

Convert PowerShell output to Python and store it in variable

Sorry in advance for silly question.
I am trying to write simple python script that runs virtual machine using PowerShell commands.
I have got a little problem with converting output from PowerShell command to a variable in Python.
The idea is:
I launch virtual machine, after that I check the state of it and, if the state is Running - start all the activity.
It is not a problem to do it in PowerShell, I wrote all the commands (launch VM, check state, if statement etc), but it is a problem to do it from py file.
My script looks like that:
import subprocess
import time
import os
class Utils(object):
def __init__(self):
self.ps_exec = r"C:\path\PsExec.exe"
self.power_shell = r"C:\path\powershell.exe"
def vm(self, apply_vm_script):
subprocess.Popen([self.power_shell, apply_vm_script])
util = Utils()
def turn_on_vm(vm_name, checkpoint_name):
apply_vm_script = 'Invoke-Command -Computername name -ScriptBlock ' \
'{ Get-VM ''"' + vm_name + '"'' | get-vmsnapshot -Name ' + '"' + checkpoint_name + '" | ' \
'Restore-VMSnapshot -Confirm:$false ; Start-VM -Name ''"' + vm_name + '"''}'
util.vm(apply_vm_script)
time.sleep(10)
def check_if_vm_on(vm_name):
check_vm_script = 'Invoke-Command -Computername name -ScriptBlock { Get-VM | where {$_.Name -eq ' + vm_name + ' } | where { $_.State -eq "Running" } | select Name,State}'
util.vm(check_vm_script)
time.sleep(3)
def test():
turn_on_vm('VM_name', 'checkpoint_name')
if(check_if_vm_on('VM_name')):
Do my activity
def main():
test()
if __name__ == '__main__':
main()
Also, I can perform all if actions in PowerShell, but also can't convert bool output into Python:
if($State -like '*Running*') { Write-Output "True" }
State was defined earlier, no problem with variables.
Any ideas how to solve it?
Thank you in advance!!!
You need to get the stdout from the powershell script to your python program. This can be done with Popen.communicate().
def vm(self, apply_vm_script):
p = subprocess.Popen([self.power_shell, apply_vm_script], stdout=subprocess.PIPE)
result = p.communicate()[0]
return str(result)
Also you need to return this value from check_if_vm_on
def check_if_vm_on(vm_name):
check_vm_script = 'Invoke-Command -Computername name -ScriptBlock { Get-VM | where {$_.Name -eq ' + vm_name + ' } | where { $_.State -eq "Running" } | select Name,State}'
result = util.vm(check_vm_script)
time.sleep(3)
return result
Then you will be able to check it with the if statement:
if(check_if_vm_on('VM_name') == "True"):
Do my activity

Running a powershell on multiple python threads

I have a Backup software made in Python. This backup software lists all the computers on a network and I need to backup the computers to a given directory. My thought was: When the user click on backup on a certain computer, it launches a Thread where a Powershell script is executed and the percentage ((Bytes Copied / Total Bytes to be Copied)*100) is displayed. Everything works fine and I'm able to copy a single computer without problem.
But here's the problem: Whenever I launch a second thread (I click backup on another Computer), it seems like the process from Powershell stops as there's no more output and the only running process is the new Powershell process launched on the second thread.
Thread run method:
def run(self):
'''
Initialise the runner function with passed args, kwargs.
'''
self.setAlive(True)
p = subprocess.Popen(["powershell.exe",".\script.ps1 . .\\Backups"],stdout=subprocess.PIPE)
self.signals.progress.emit(self.CurrentComp['RowIndex'], 0, self)
percentage = 0.0
a = ""
displayPercentage = 0.0
while a != "Done Copying":
a = p.stdout.readline()
a = a.decode("utf-8").strip()
try:
percentage = float(a)
print(percentage)
while displayPercentage != int(percentage):
displayPercentage += 1
sleep(0.03)
self.signals.progress.emit(self.CurrentComp['RowIndex'], displayPercentage ,self)
except ValueError:
pass
self.signals.finished.emit()
Param([String[]]$paths,[String]$Destination)
function Copy-WithProgress {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[string] $Source
, [Parameter(Mandatory = $true)]
[string] $Destination
, [int] $Gap = 200
, [int] $ReportGap = 2000
)
$RegexBytes = '(?<=\s+)\d+(?=\s+)';
$CommonRobocopyParams = '/MIR /NP /NDL /NC /BYTES /NJH /NJS';
$StagingLogPath = '{0}\temp\{1} robocopy staging.log' -f $env:windir, (Get-Date -Format 'yyyy-MM-dd HH-mm-ss');
$StagingArgumentList = '"{0}" "{1}" /LOG:"{2}" /L {3}' -f $Source, $Destination, $StagingLogPath, $CommonRobocopyParams;
Start-Process -Wait -FilePath robocopy.exe -ArgumentList $StagingArgumentList -NoNewWindow;
$StagingContent = Get-Content -Path $StagingLogPath;
$TotalFileCount = $StagingContent.Count - 1;
[RegEx]::Matches(($StagingContent -join "`n"), $RegexBytes) | % { $BytesTotal = 0; } { $BytesTotal += $_.Value; };
$RobocopyLogPath = '{0}\temp\{1} robocopy.log' -f $env:windir, (Get-Date -Format 'yyyy-MM-dd HH-mm-ss');
$ArgumentList = '"{0}" "{1}" /LOG:"{2}" /ipg:{3} {4}' -f $Source, $Destination, $RobocopyLogPath, $Gap, $CommonRobocopyParams;
$Robocopy = Start-Process -FilePath robocopy.exe -ArgumentList $ArgumentList -Verbose -PassThru -NoNewWindow;
Start-Sleep -Milliseconds 100;
#region Progress bar loop
while (!$Robocopy.HasExited) {
Start-Sleep -Milliseconds $ReportGap;
$BytesCopied = 0;
$LogContent = Get-Content -Path $RobocopyLogPath;
$BytesCopied = [Regex]::Matches($LogContent, $RegexBytes) | ForEach-Object -Process { $BytesCopied += $_.Value; } -End { $BytesCopied; };
#Write-Verbose -Message ('Bytes copied: {0}' -f $BytesCopied);
#Write-Verbose -Message ('Files copied: {0}' -f $LogContent.Count);
$Percentage = 0;
if ($BytesCopied -gt 0) {
$Percentage = (($BytesCopied/$BytesTotal)*100)
}
Write-Host $Percentage
}
Write-Host "Done Copying"

How to automatically start and stop a python script in nodejs?

I am developing a temperature monitoring application in a hen house with a web interface. I use two arduinos and a Raspberry.
Arduino 1: I connected a temperature / humidity sensor and an RF433Mhz transmitter.
Arduino 2: An RF433Mhz receiver is connected to it. It receives data from Arduino 1.
Raspberry: Arduino 2 is connected to my raspberry which reads the data received in the serial monitor and send them to the web page via the websockets (package ws of nodejs).
At first I wanted to read this data directly with Nodejs, but I had some problems with the installation of the serial port package.
So I changed my approach: I read the data in the serial monitor with python, write it in files, and Nodejs reads these files and sends the data to the web page.
here are the two codes I use:
Phyton script
import serial
import time
ser = serial.Serial('/dev/ttyACM0', 9600)
while True:
data = ser.readline()
if data:
t = data[0:2]
h = data[6:8]
#decode utf-8
tc = t.decode("utf-8")
hc = h.decode("utf-8")
#write the temperature in the temp file
fileTc=open('temp', 'w')
fileTc.write(str(tc))
fileTc.close
#write the humidity in the hum file
fileHc=open('hum', 'w')
fileHc.write(str(hc))
fileHc.close
#sleep
time.sleep(.1)
Nodejs Script
var express = require("express");
const WebSocket = require('ws');
const wss = new WebSocket.Server({port: 4400});
var path = require("path");
var fs = require("fs");
var sys = require("util");
var exec = require("child_process").exec;
var tempcpu = 0;
var temp = 0;
var hum = 0;
var app = express();
app.set("port", process.env.PORT || 5500);
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "ejs");
app.use('/', express.static('public'));
wss.on('connection', function connection(ws) {
ws.on('message', function incoming(message) {
console.log('received: %s', message);
});
setInterval(function(){
child1 = exec("cat /sys/class/thermal/thermal_zone0/temp",
function(error, stdout,stderr){
if (error !== null){
console.log('exec error: ' +error);
} else{
tempcpu = parseFloat(stdout)/1000;
}
});
child2 = exec("cat temp", function(error, stdout,stderr){
if (error !== null){
console.log('exec error: ' +error);
} else{
temp = parseFloat(stdout);
}
});
child3 = exec("cat hum", function(error, stdout,stderr){
if (error !== null){
console.log('exec error: ' +error);
} else{
hum = parseFloat(stdout);
}
});
var tempCPU = JSON.stringify(["cpu",tempcpu]);
var temperature = JSON.stringify(["temp",temp]);
var humidity = JSON.stringify(["hum",hum]);
ws.send(tempCPU);
ws.send(temperature);
ws.send(humidity);
}, 5000);
});
app.get("/", function(request, response) {
response.render("dashboard");
});
app.listen(app.get("port"), function() {
console.log("Server started at port " + app.get("port"));
});
for now I have to launch both scripts separately. I would like to run my python script directly from nodejs when I start the node server, and stop it when I stop my nodejs code (CTRL + C).
Do you have an idea of ​​how to do it?
What you want to achieve is spawn a new process in which you execute something from either a Node app or a Python app:
NodeJS approach: Child process
const { spawn } = require('child_process');
const pythonApp = spawn('python', ['my_python_app.py']);
Python approach: Subprocess
import subprocess
node_app = subprocess.Popen(["node","my_node_app.js"], stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
EDIT
Regarding catching the INTERRUPT (CTRL+C) signal, this can also be done in both languages; and leveraged to kill the process you spawned:
With NodeJS:
process.on('SIGINT', () => {
console.log("Caught interrupt signal");
if(pythonApp) pythonApp.exit();
});
With Python:
import sys
try:
# Your app here...
except KeyboardInterrupt:
print("Caught interrupt signal")
if node_app: node_app.kill()
sys.exit()

Categories