0

I'm trying to run a script from a PHP on my server.

<?php exec("sh /var/www/scripts/script.sh", $output); ?>

my script is:

#!/bin/bash
sh Stop.sh
nohup java -jar RestApiRandonSender.jar&      # You send it in background
MyPID=$!                        # You sign it's PID
echo $MyPID                     # You print to terminal
echo "kill -9 $MyPID" > Stop.sh  
echo "rm Stop.sh" >> Stop.sh

My folder structure is:

/var/www/
/html/restart.php
/scripts/script.sh

all group and users are root.

When I access the PHP page from Chrome (localhost/restart.php), nothing happens.

But when I'm in the folder scripts and I run

sudo php ../html/restart.php

the scripts restarts the jar file and creates the Stop.sh, but the script doesn't end until I press Ctrl+c or Ctrl+z.

I'm new to Linux. I hope I gave all the details needed..

EDIT: I changed the path to the full file path in script.sh and now it is almost working.

The process still never ends. The webpage from chrome is waiting for response and the process id of the jar file is completely different from the process id I get in the Stop.sh

$ ps -ef | grep java
apache   10086     1 76 11:23 ?        00:05:00 java -jar /var/www/scripts/RestApiRandonSender.jar 
Opal
  • 81,889
  • 28
  • 189
  • 210

1 Answers1

0

Your current problem is probably based around not dealing with directories at all: rm, like most Unix-esque commands, operates from the current directory if none is specified. When you run from another directory by calling ../html/restart.php, it will be trying to run the Stop.sh script in the current directory, failing (silently probably - you should fix that), and then continuing on running the new Java server, which I suspect if you examine its logs (have you done this?) will be stuck permanently trying to bind to a TCP port, which it can't because the other process is still alive.

Within your Bash script, you need to handle where to find / create the Stop script. you should either:

  1. hard-code a directory (e.g. /var/run/blah...) to the Stop.sh script within your script,
  2. or make it relative to the script's director - you can use dirname $0 to find this in Bash.
  3. or, don't re-write the script every time, just rewrite the PID of the process. This is effectively what most service managers do anyway. You just write MyPID, in your case, to the file and then execute that:

Combining elements of the last two, you could try (untested):

#!/bin/bash
PIDFILE=$(dirname $0)/PID           # Read the current PID, if any
pid=$(cat $PIDFILE) && kill -9 pid  # Kill it off if it's there
nohup java -jar RestApiRandonSender.jar &
pid=$!
echo $pid > $PIDFILE                # Write the new PID to the file

Other problems with your setup to think about:

  • Never run your web process as root if you can possibly avoid it, for security. At the very least set up sudo privileges for the most limited set of things you need to do.
  • concurrency (what happens when several people run this script (URL) at once?). You might get away with not dealing with this, as it's a hard problem usually.
  • What happens when you restart the server itself. I suggest, longer term, you look into creating a Linux service out of your Java server - see Linux: process into a service for some examples. This also deals with the previous point...
Community
  • 1
  • 1
declension
  • 4,110
  • 22
  • 25