Bitcoin Forum

Bitcoin => Bitcoin Technical Support => Topic started by: el_rlee on February 05, 2013, 12:38:12 PM



Title: bash script for starting application which depends on running bitcoind
Post by: el_rlee on February 05, 2013, 12:38:12 PM
Hello all,

 I got an application which I need to start AFTER bitcoind is responsive. I know it can only be a few lines of scripting, ashes over my head I can't figure it out myself.
I was thinking of something like a while loop which checks the output of "bitcoind getinfo" for the right text.

many thanks in advance!


Title: Re: bash script for starting application which depends on running bitcoind
Post by: davout on February 05, 2013, 12:52:46 PM
That sounds about right. Slightly dirty but I guess it would work.

Maybe you can parse the debug.log as it's written to and check that the block index and wallet have been loaded.


Title: Re: bash script for starting application which depends on running bitcoind
Post by: el_rlee on February 05, 2013, 01:22:32 PM
At the moment it's running like this:


#!/bin/bash
su bitcoin -c 'bitcoind getinfo'
su bitcoin -c 'bitcoind getinfo'
su bitcoin -c 'bitcoind getinfo'
cd /opt/app
su appuser -c 'app'


this was working because older versions of bitcoind wouldn't reply "error: couldn't connect to server" but just wait until they are fully fired up before giving the output. Unfortunately that's not the case any more and I need a new start up script for my application. Could anybody help with the actual bash loop?
Thanks!


Title: Re: bash script for starting application which depends on running bitcoind
Post by: mintymark on February 05, 2013, 01:44:27 PM
The following seems to work:

while ! /usr/bin/bitcoind getinfo > /dev/null 2>&1; do echo waiting ; sleep 1; done

or you can write it as:


while ! /usr/bin/bitcoind getinfo > /dev/null 2>&1
do
   echo waiting
   sleep 1
done

How does this work:

It looks for the exit status of bitcoind. The exit status is normal if the command works, and seems to be 87 if it doesnt.
The while statement checks for any non-zero exit status.
The output is diverted to /dev/null, we do nort want to see this, and also the error output which contains the message cannot connect to server, the 2>&1 combines these
two output streams so that they both go to /dev/null, and we do not see them.
The echo waiting is debug really and you can remove it.
sleep 1 waits for 1 second, sleep 10 would be just as good here, you need it to be at least 1 second as otherwise the loop will execute too fast and may use up too
much resources while running.

regards,

 Mark.



Title: Re: bash script for starting application which depends on running bitcoind
Post by: mintymark on February 07, 2013, 12:46:35 AM
So did this work for you? It seems rather bad manners if it did and you didnt say. Perhaps it didn't in which case I'd also like to know. Or did you just loose interest and not bother even reading replies to your post ?


Title: Re: bash script for starting application which depends on running bitcoind
Post by: el_rlee on February 07, 2013, 04:03:41 AM
Hi,

 I am really really sorry for not answering... I however sent a donation to your address shortly after you posted - humble but still. Didn't you notice?
The thing is: I needed a solution swiftly so I called a freaky friend which came up with:

Code:
#!/bin/bash
while [ `su bitcoin -c 'bitcoind getinfo'` == "error: couldn't connect to server" ]; do sleep 1; done;

I know it's dirty and yours is much more elegant, but as I already had implemented and tried the dirty one I figured I'll wait with digging up your post until they change the text of the error message in a future version of bitcoind...
I have just been to ashamed to tell you this.


Title: Re: bash script for starting application which depends on running bitcoind
Post by: kjj on February 07, 2013, 12:25:38 PM
You can add a second stage to that loop, if you need bitcoind to be not just running, but close to being current.  Note that bitcoind does not reliably report that it is current, so if you are starting from scratch, this will end while bitcoind is still several hundred blocks behind.  But, it appears to be the best you can do without consulting an outside service to find the proper block count.

Code:
# Waits for bitcoin to catch up
STATUS=`$BITCOIND getwork 2>&1`
P1=`echo $STATUS | grep -o "error"`
P2=`echo $STATUS | grep -o "download"`
CNT=`$BITCOIND getinfo | grep blocks | cut -d : -f 2 | cut -d , -f 1 | cut -d " " -f 2`
while [[ "$P1" = "error" || "$P2" = "download" ]] ; do
 echo -n "Waiting for local bitcoin node to catch up "
 if [ "" != "$CNT" ] ; then
  echo -n "($CNT)"
 fi
 echo ""
 sleep 13
 STATUS=`$BITCOIND getwork 2>&1`
 P1=`echo $STATUS | grep -o "error"`
 P2=`echo $STATUS | grep -o "download"`
 CNT=`$BITCOIND getinfo | grep blocks | cut -d : -f 2 | cut -d , -f 1 | cut -d " " -f 2`
done


Title: Re: bash script for starting application which depends on running bitcoind
Post by: mintymark on February 07, 2013, 02:38:37 PM
Thanks for the donation el_rlee. Sorry I was impatient, just wondered if it was what you needed!

Cheers!


Title: Re: bash script for starting application which depends on running bitcoind
Post by: el_rlee on February 18, 2013, 11:41:29 AM
I somehow don't get it working... output below - maybe somebody smarter than me has mercy and helps me out.

Code:
root@box:~# cat /sbin/bitcoindgetinfo
#!/bin/bash
while ! `su bitcoin -c 'bitcoind getinfo'` > /dev/null 2>&1; do echo waiting ; sleep 1; done

root@box:~# su bitcoin -c 'bitcoind getinfo'
{
    "version" : 70200,
    "protocolversion" : 60002,
    "walletversion" : 10500,
    "balance" : XX
    "blocks" : 221842,
    "connections" : 8,
    "proxy" : "",
    "difficulty" : 3651011.63069321,
    "testnet" : false,
    "keypoololdest" : 1350131298,
    "keypoolsize" : 101,
    "paytxfee" : 0.00000000,
    "errors" : ""
}
root@box:~# bitcoindgetinfo
waiting
waiting
waiting
waiting
waiting
^C
root@box:~#

The app needing bitcoind to be responsive over JSON RPC already runs without problems at this time


Title: Re: bash script for starting application which depends on running bitcoind
Post by: mintymark on February 18, 2013, 06:45:19 PM
I suspect your problem may be the use of su. This accepts a user as the first argument. The default is root, but in this case it may be looking for a user bitcoind.

Do you need su ?

The correct statement is this
while ! /usr/bin/bitcoind getinfo > /dev/null 2>&1

remove the backticks you have you do not need them.


Title: Re: bash script for starting application which depends on running bitcoind
Post by: el_rlee on February 19, 2013, 02:50:33 AM
I need the su because bitcoind is running as another user - so

Code:
root@box:~# bitcoind getinfo
error: incorrect rpcuser or rpcpassword (authorization failed)

doesn't work.

however this does:

Code:
root@box:~# cat /sbin/bitcoindgetinfo
#!/bin/bash
su bitcoin -c 'while ! bitcoind getinfo > /dev/null 2>&1; do echo waiting ; sleep 1; done'


Title: Re: bash script for starting application which depends on running bitcoind
Post by: mintymark on February 19, 2013, 09:57:07 AM
Yes, that looks ok to me.

It often happens that bits of script that start as  one-liners get more complex and eventually you want to put them in their own file.

This has the advantage of saving on typing, making it easier to incorporate more functionality, and calling it something memorable.

You may have reached this stage.

You need to do two things to do this, and perhaps you already know, but just saying.

1) The first line must be
    #!/bin/bash
    with no space befor the #
2) Give the file execute permission. You can do it like this:
    chmod +x myfile

You also need to ensure that the file is in the path or you give the full path, perhaps like this:

     ./myfile

dot in this context means the current directory, myfile will only work if the current directory happens to be in the pathlist contained in the $PATH environment variable.