1

I am using the SSH2 library in my PHP to execute a SH script on a remote server. When I run it manually on SSH, it works just fine. However, when I try to run it through PHP, the script starts, but never completes. (The script echos the size of two directories, and runs in a for loop echoing out the size until the two folders are the same size.). I have tried putting it in a screen, running with an ampersand to run in the background, disowned it, and more.

Here is the whole script:

echo "starting" > /var/www/html/$2.log
rep=`du -sk /home/repository_$1 | awk '{print $1}'`
dirsize=`du -sk /home/$2 | awk '{print $1}'`
while [ "$dirsize" -lt "$rep" ]; do
        dirsize=`du -sk /home/$2 | awk '{print $1}'`
        echo "New directory size: $dirsize."
        echo "$dirsize\\$rep" > /var/www/html/$2.log
        sleep 2;
done
echo "Loop Complete"
echo "done" > /var/www/html/$2.log

I have narrowed down the crash to the while loop. For some reason, that causes it to lock up. All code before it executes just fine. The script is being executed as root, and I have tried echoing out the variables from the while loop out to text files, so I know they are set and working properly.

DarthCaniac
  • 209
  • 1
  • 3
  • 8
  • the only place it looks like it can hang is in the `while` loop, did you check the values of the /var/www/html/$2.log file?, did you call `du -sk /home/$2 | awk '{print $1}'` and compare the 2 values of `$rep` and `$dirsize` – Tom May 29 '12 at 23:55
  • rather that the while loop "lock up" its more likely that its condition never evaluates to false during the invocation, under those circumstances. – Tom May 30 '12 at 00:22
  • another possibility is that the positional args get reset by something. try storing them to a local var, and using that instead. – Tom May 30 '12 at 00:26

2 Answers2

3

This is another idea that I had, which is that the loop might be losing the position args;

directory1=$1
directory2=$2
echo "starting" > /var/www/html/${directory2}.log
rep=`du -sk /home/repository_${directory1} | awk '{print $1}'`
dirsize=`du -sk /home/${directory2} | awk '{print $1}'`
while [ "$dirsize" -lt "$rep" ]; do
        dirsize=`du -sk /home/${directory2} | awk '{print $1}'`
        echo "New directory size: $dirsize."
        echo "$dirsize\\$rep" > /var/www/html/${directory2}.log
        sleep 2;
done
echo "Loop Complete"
echo "done" > /var/www/html/${directory2}.log

  1. try executing the script as /bin/bash rather than sh, as sh is lacking in some features (rubbish) ;-)

It's probable that the user that php/apache is running the script does not have permission to access one or more of the files in your script, or that selinux or some security restriction is preventing apache/php from starting the sh interpreter.

try $ ps -ef | egrep "(php|httpd|apache)" when the script is running to see if you can catch which user php is running as.

try to run the script as the apache user like so;

 sudo -u apache /bin/bash -x script.sh arg1 arg2

should provide some debugging enabled output to see where the problem might be.

If the script is running, but stuck, you can use strace to take a look at what is stuck doing like so;

# ps -ef | grep sleep
root     24242 22711  0 14:02 pts/0    00:00:00 sleep 10000
root     24249 22711  0 14:03 pts/0    00:00:00 grep sleep

# strace -fp 24242
Process 24242 attached - interrupt to quit
restart_syscall(<... resuming interrupted call ...> <unfinished ...>
Tom
  • 11,176
  • 5
  • 41
  • 63
  • Thanks for the suggestions! I tried using /bin/bash, as well as just "bash", but to no avail. Here is the result of the first command you sent me: http://gyazo.com/a001b415992fc301afe5286de0701f81. – DarthCaniac May 29 '12 at 21:29
  • once you find out what your php is running as (e.g. apache), start bash as that user and try and run the script like so; `sudo -u apache /bin/bash -x script.sh arg1 arg2` – Tom May 29 '12 at 21:33
  • I think you might need to give the full path to the `script.sh` file, e.g. `/var/www/html/script.sh` or `/bin/bash /home/userXXX/script.sh arg1 arg2` – Tom May 29 '12 at 21:38
  • Hmm, weird. I went and wrote in (Before the script freezes) for it to echo out "whoami" to a text file, it returns as "root", which is what I originally SSH'd in as in the script. Changing to the full path had no affect. When I SSH'd in to apache as you suggested, it could access almost nothing. – DarthCaniac May 29 '12 at 22:16
  • right, so your script cannot be run by the php/apache so you would need to adjust the permissions of the files until you can run the script as `sudo -u apache sh /path/to/script.sh arg1 arg2` – Tom May 29 '12 at 22:40
  • Sorry, I misread your original statement, and checked what user PHP was running as on the server. The actual server does not have any PHP on it (The code is being executed on this box through SSH, from PHP on another machine). All code is being executed as "root". – DarthCaniac May 29 '12 at 23:46
  • I would suggest re-working your question to be very specific about what is run where, and as which user. I suggest you provide the full invocation of each command to enable troubleshooting. – Tom May 29 '12 at 23:49
  • Good idea. I went ahead and updated the original post. – DarthCaniac May 30 '12 at 00:19
  • let us [continue this discussion in chat](http://chat.stackexchange.com/rooms/3596/discussion-between-darthcaniac-and-tom-h) – DarthCaniac May 30 '12 at 00:19
0

Try using full paths in your commands. Often the bash environment you are using when you login may not be the same when you run a command via a script. So some information, such as paths, can be lost.

jeffatrackaid
  • 4,142
  • 19
  • 22
  • Thanks for the suggestion. I double checked all my commands (In the script and when I called the script, and had them all use full paths, but it did not make a difference. – DarthCaniac May 29 '12 at 23:35