So I'm creating a process in Perl like this:
my $process = `nohup ./run > /dev/null 2>&1 &`;
Which returns something along the lines of
[1] 2905
How do I go about getting the process ID from this so later on in the script execution I can run something like:
exec("kill -9 $pid");
Here's what I've got so far:
/\[1\] ([0-9]+)/g
but it looks quite messy, is there any way to improve upon this regular expression? Will that regex always work? Is there any case where it wont be [1]?
how about
#ar = split(/\s+/, $process);
$pid = $ar[1];
You should probably be using a "fork and exec" pattern here.
if (my $pid = fork()) {
# You're in the parent process
# $pid contains the PID of the new child process
...
} else {
# You're in the new child process
# exec() your new command
exec($cmd);
# Execution never gets here
}
Edit: Actually, given that you're basically creating a daemon process here, perhaps you should look at Proc::Daemon instead.
Related
is it possible wit Qt Qprocess to detect if a mounted Loacation(maybe NAS) is connected?
Generally i would check in /proc/mounts if there is an entry, but if i disconnect to the NAS the file doesn't realizes it.
with the df command i can check if a mountpoint is available. But if the connection is disconnected the df process doesn't gives an output. Maybe infinite.
I tried it with
QProcess p;
p.start("bash", QStringList() << "-c" <<
"df -P -T /media/storage/ | grep QIS | awk -F ' ' '{print $1}'");
if (p.waitForFinished(2))
{
qDebug() << "Nothing";
p.close();
}
But nothing happens.
It seems that my program "freezes" when i try to df to a directory which ist'n mounted. Is it possible to cancel the process if there is no answer from the df process after, for example, 2 seconds?
Regarding QProcess, QProcess::waitForFinished takes msec as argument, not sec. Furthermore, it is better to connect to QProcess::finished signal instead of blocking the event loop.
That being said, why using QProcess, when there is a QStorageInfo with a mountedVolumes method:
for (const auto &storage : QStorageInfo::mountedVolumes()) {
if (storage.isValid() && storage.isReady()) {
if (!storage.isReadOnly()) {
// ...
}
}
}
I have created a bash script that runs on several machines that contain different git local repositories. It tests many conditions and tells me if the repository has uncommitted files, untracked files, and one test in particular tells me that the local is ahead or behind the remote by the number of commits. The problem with the script is that it doesn't return or set an 'ok' flag which I use to echo the "ok" message if everything is in sync. So, I get the message that it's ahead or behind, but then get the "ok" message. Here is the portion of the script that does the ahead or behind, and I can't see how to get it to set an ok = false somehow.
git fetch>/dev/null && git branch -v |
perl -wlne'
print "$ENV{reponame} [$1] --> $3 $2"
if /^..(\S+)\s+([a-f0-9]+)\s+(\[(?:ahead|behind)\s+\d+\])/
' |
while IFS= read -r MOD; do
ok=false
printf ' %s\n' "$MOD" # Replace with code that uses $MOD
done
if $ok; then
echo " OK --> $reponame [$br] $rev"
fi
I copied this from another script and don't really understand the IFS = read -r MOD; section that I thought might set the flag, but it doesn't occur.
This is the output I get:
bin [develop] --> [behind 1] 026e1ad
OK --> bin [develop] 026e1ad
OK --> notes [develop] 4cd077f
OK --> indecks [develop] e6b4293
OK --> queue [develop] 5469679
OK --> frameworks [master] 05fedb6
OK --> dashboard [isolate] f8b1101
OK --> nodejs [develop] 5af2ea7
OK --> perl-forth [master] 45cc837
OK --> blog [master] c19edfd
Note that for bin I get:
bin [develop] --> [behind 1] 026e1ad
OK --> bin [develop] 026e1ad
I'd rather not get that OK after the behind 1! Another script checks for any non-OK in the left column and sends me an email.
With the perl and all the piping, how could I set the ok variable before it prints?
In most shell implementations, all processes in a pipeline are run in a subshell. In this case, you're running a while loop at the end of a pipeline, so it (and it alone) is in the subshell. Whether you set ok to false or not, it has no effect on the if block because that's run the main shell, which doesn't inherit variables from the subshell.
zsh and AT&T ksh (but not other ksh implementations) execute the last command in the main shell and not a subshell. POSIX permits either behavior, but the bash behavior is far more common among shells.
The easiest way to handle this is to run the entire command you're interested in in a subshell:
git fetch>/dev/null && git branch -v |
perl -wlne'
print "$ENV{reponame} [$1] --> $3 $2"
if /^..(\S+)\s+([a-f0-9]+)\s+(\[(?:ahead|behind)\s+\d+\])/
' |
(while IFS= read -r MOD; do
ok=false
printf ' %s\n' "$MOD" # Replace with code that uses $MOD
done
if $ok; then
echo " OK --> $reponame [$br] $rev"
fi)
This puts both parts using the ok variable in the same subshell, so you can modify it and it will have an effect.
I am currently using a template_file to provision user_data into an aws_launch_configuration, like so:
resource "aws_launch_configuration" "launch_config" {
...
user_data = "${data.template_file.init.rendered}"
}
data "template_file" "init" {
template = "${file("router-init.sh.tpl")}"
vars {
hub_ip_addresses = "${join(",", aws_instance.gridHub.*.private_ip)}"
}
}
I am feeding in a variable (i.e. hub_ip_addresses) into the router-init.sh.tpl file, and in this file I am making use of the argument like so:
`#!/bin/sh
...
IFS=',' read -r -a array <<< "$hub_ip_addresses"
for element in "${array[#]}"
do
#do stuff with $element
done
Basically, I am splitting the string based on a delimiter, and then looping through each ip address in the array.
This bash script works fine when I run it on my local machine -- however, when terraform executes it, it throws a error:
* data.template_file.init: data.template_file.init: failed to render : parse error at 13:25: expected expression but found invalid sequence "#"
I'm supposing the '#' symbol is causing an issue. Is there a reason why this is so? Do I need to escape it with a '\' ?
EDIT: Not sure if related to this issue, but in the preceeding line in the bash script, IFS=',' read -r -a array <<< "$hub_ip_addresses", the <<< seems to be causing everything else that follows to look as if they are inside a comment (i.e. greyed out as if it was within a quotation mark ').)
You need to escape the $ characters in your template by doubling them up or Terraform will attempt to interpolate them as the input variables to the template.
The template docs cover this briefly although the example given is for inline templates rather than for all templates, including those that are loaded with the file() function.
So something like:
#!/bin/sh
...
IFS=',' read -r -a array <<< "$hub_ip_addresses"
for element in "$${array[#]}"
do
#do stuff with $$element
done
I am actually using wamp 2.5 with PHP 5.5.12 and when I try to create a phar file it returns me the following message :
Uncaught exception 'UnexpectedValueException' with message 'creating archive "..." disabled by the php.ini setting phar.readonly'
even if I turn to off the phar.readonly option in php.ini.
So how can I enable the creation of phar files ?
I had this same problem and pieced together from info on this thread, here's what I did in over-simplified explanation:
in my PHP code that's generating this error, I added echo phpinfo(); (which displays a large table with all sort of PHP info) and in the first few rows verify the path of the php.ini file to make sure you're editing the correct php.ini.
locate on the phpinfo() table where it says phar.readonly and note that it is On.
open the php.ini file from step 1 and search for phar.readonly. Mine is on line 995 and reads ;phar.readonly = On
Change this line to phar.readonly = Off. Be sure that there is no semi-colon at the beginning of the line.
Restart your server
Confirm that you're phar project is now working as expected, and/or search on the phpinfo()table again to see that the phar.readonly setting has changed.
phar.readonly can only be disabled in php.ini due to security reasons.
If you want to check that it's is really not done using other method than php.ini then in terminal type this:-
$ php -r "ini_set('phar.readonly',0);print(ini_get('phar.readonly'));"
If it will give you 1 means phar.readonly is On.
More on phar.configuration
Need to disable in php.ini file
Type which php
Gives a different output depending on machine e.g.
/c/Apps/php/php-7.2.11/php
Then open the path given not the php file.
E.g. /c/Apps/php/php-7.2.11
Edit the php.ini file
could do
vi C:\Apps\php\php-7.2.11\php.ini
code C:\Apps\php\php-7.2.11\php.ini
[Phar]
; http://php.net/phar.readonly
phar.readonly = Off
; http://php.net/phar.require-hash
phar.require_hash = Off
Save
Using php-cli and a hashbang, we can set it on the fly without messing with the ini file.
testphar.php
#!/usr/bin/php -d phar.readonly=0
<?php
print(ini_get('phar.readonly')); // Must return 0
// make sure it doesn't exist
#unlink('brandnewphar.phar');
try {
$p = new Phar(dirname(__FILE__) . '/brandnewphar.phar', 0, 'brandnewphar.phar');
} catch (Exception $e) {
echo 'Could not create phar:', $e;
}
echo 'The new phar has ' . $p->count() . " entries\n";
$p->startBuffering();
$p['file.txt'] = 'hi';
$p['file2.txt'] = 'there';
$p['file2.txt']->compress(Phar::GZ);
$p['file3.txt'] = 'babyface';
$p['file3.txt']->setMetadata(42);
$p->setStub('<?php
function __autoload($class)
{
include "phar://myphar.phar/" . str_replace("_", "/", $class) . ".php";
}
Phar::mapPhar("myphar.phar");
include "phar://myphar.phar/startup.php";
__HALT_COMPILER();');
$p->stopBuffering();
// Test
$m = file_get_contents("phar://brandnewphar.phar/file2.txt");
$m = explode("\n",$m);
var_dump($m);
/* Output:
* there
**/
✓ Must be set executable:
chmod +x testphar.php
✓ Must be called like this:
./testphar.php
// OUTPUT there
⚠️ Must not be called like this:
php testphar.php
// Exception, phar is read only...
⚠️ Won't work called from a CGI web server
php -S localhost:8785 testphar.php
// Exception, phar is read only...
For anyone who has changed the php.ini file, but just doesn't see any changes. Try to use the CLI version of the file. For me, it was in /etc/php/7.4/cli/php.ini
Quick Solution!
Check:
cat /etc/php/7.4/apache2/php.ini | grep phar.readonly
Fix:
sed -i 's/;phar.readonly = On/;phar.readonly = Off/g' /etc/php/7.4/apache2/php.ini
Hello everyone and happy new year! I have a text from which I like to return a specific area from a specific string using a python script!
This is the text I have
#!/bin/sh
case "$1" in
start)
ulimit -s 1024
/usr/bin/oscam --config-dir /etc/tuxbox/config/oscam --daemon --pidfile /tmp/oscam.pid --restart 2 --utf8
;;
stop)
kill `cat /tmp/oscam.pid` 2> /dev/null
;;
restart|reload)
$0 stop
sleep 1
$0 start
;;
version)
echo "svn8631"
;;
info)
echo "oscam svn8631"
;;
*)
echo "Usage: $0 start|stop|restart"
exit 1
;;
esac
exit 0
from the text above I need to create a python command that always returns only what is written where the oscam svn8631 is written between the quotes! So far the only thing I managed to do is return another area of this text using this code
try:
f = open("/etc/init.d/softcam", "r")
content = f.read()
f.close()
except:
content = ""
contentInfo = content.split("\n")
if (content != ""):
for line in contentInfo:
if line.__contains__("usr/bin/"):
idex = line.index("n/")
line = line[(idex + 2):]
return line
This of course returns what's after the usr/bin text, and I need another area which comes after the word info). Can anyone help me please? I don't know how to make my script read this specific area I need! Thanks in advance!
Using the content variable that you have created, the
"oscam svn8631" text can be extracted with:
for chunk in content.split(";;"):
if chunk.strip().startswith('info)'):
return chunk.split('"')[1]
The natural way to break up a bash case statement is by splitting it on ";;". Then, we identify the info section (chunk.strip().startswith('info)')) and select the first quoted string in that section (chunk.split('"')[1]).