# Console bittorrent and bittorrent (psuedo) deamon HOWTO

## chunderbunny

Someone asked about this elsewhere on the forum, and I realised that there wasn't a good howto anywhere detailing the console based bittorrent clients, so I thought I would write one!

Most of you already know how to use the gui bittorrent client (and indeed have moved on to other, improved clients like azureus and shadows experimental client) but fewer people know about the console based clients that come with standard bittorrent package. The console client is best used in combination with screen, since screen allows you to run programs in the background. If you are administering a computer over an SSH connection than screen is especially useful since it doesn't quit when the SSH connection is killed and the screen session can be resumed from any computer that connects via SSH. If you don't already have screen installed then 

```
emerge -av screen
```

to install it. 

If you already have bittorrent installed then the console client is also already installed and you needn't do anything. If you need to install bittorrent, then setting the -X USE flag not install the dependencies of the gui client (which includes xorg and wxpython among other things) 

```
echo "net-p2p/bittorrent -X" >> /etc/portage/package.use

emerge -av bittorrent
```

The basic bittorrent console client is btdownloadcurses.py, or btdownloadheadless.py if you prefer not to have the curses library in memory. There are two ways of using this client, either download the torrent file manually and set the client to use the local file, or you can get the client to download and execute the torrent file all in one step. 

The choice is up to you, personally I find it easier and more useful to download the torrent files using lynx or wget, since then it's very easy to resume a download if the need arises. You can also browse for torrents using lynx on most websites. Once you have your torrent file, save it in your download directory and start a screen session.

```
screen -S bittorrent
```

Next, execute the download client

```
btdownloadcurses.py /path/to/file.torrent
```

And voila! The torrent should start downloading. Note that the file will be downloaded to the directory in which the client was started by default. You can change this by using the option --saveas

```
btdownloadcurses.py /path/to/file.torrent --saveas /save/directory/filename
```

Note that you have to specify the save path AND the filename when using the --saveas option, if this option is not used then the filename is chosen from the data in the .torrent file.

If you want the client to fetch the torrent file for you then you have to specify the url of the torrent file using the --url option

```
btdownloadcurses.py --url http://www.torrentfiles.com/some_torrentfile.torrent
```

Remember that you can't use wildcards in urls and you have to specify 'http://' or 'ftp://' or it won't work. If the file name has a space in it, then replace the space with '%20', similarly, a left bracket '(' should be replaced with '%28' and a right hand bracket ')' with '%29'. 

Now detach the screen by pressing crtl + a, followed by d, the download will continue in the background, even if you log out or close your SSH session. You can monitor the progress of your downloads by issuing the command 

```
screen -r bittorrent
```

And you can detach it using ctrl+a then d, as before. Simple huh? If you want to stop the download, reattach the screen and then press 'q'. Be patient, it may take a few seconds for the client to quit if it's a large file. 

If you want to download multiple files simultaneously you can either set up a seperate screen session for each file, or you can use the btlaunchmanycurses.py client (or btlaunchmany.py if you're not using the curses interface.) Again, in order to run in the background btlaunchmanycurses needs a screen session

```
screen -S bittorrent
```

In this case you don't specify an actual torrent file to begin a download, rather a directory in which the torrent files are located. All torrent files in this directory wil be activated when the client is started.

```
btlaunchmanycurses.py /path/to/torrents/
```

Now all you have to do is put any torrents in the /path/to/torrents/ directory and btlaunchmancurses will automatically start downloading the files. When you remove the torrent file the download stops. Again, by default the files will be downloaded to the directory in which the client was started. Remember that when a file has finished downloading the bittorrent client will continue to upload the file.

Some options you might want to append to the btdownloadcurses.py or btlaunchmanycurses.py command:

```
--max_uploads <arg>

          the maximum number of uploads to allow at once. (defaults to 7)

--display_interval <arg>

          time between updates of displayed information (defaults to 0.5)

--max_upload_rate <arg>

          maximum kB/s to upload at, 0 means no limit (defaults to 0) 

```

There are more options, run btdownloadheadless.py with no arguments to get a full list. Note that in the case of --max_upload_rate, the upload on each individual transfer is capped, rather than the total upload of all the transfers.Last edited by chunderbunny on Thu Mar 17, 2005 7:00 pm; edited 1 time in total

----------

## czo

Hmmmmm i like the way you rock  :Smile: !!!!!!

----------

## MooktaKiNG

If you really want a smart bittorrent multi downloader, here's what i created:

http://www.mooktakim.com/code/show.php?id=3

It works really well.

All you do is run btdir ./TorrentFile and it will download all the torrents from TorrentFile.

Oh and you better change the default save folder inside the script.

It download one torrent after another. Once a torrent has completed download it exits and starts the next torrent download.

I also run this inside screen session.

----------

## Doxer

I think it doesn't work with torrent-files with spaces in it.

----------

## MooktaKiNG

 *Doxer wrote:*   

> I think it doesn't work with torrent-files with spaces in it.

 

Yeh. i never liked spaces in file names. I always use a script to replace spaces with a _.

----------

## Doxer

ok  :Wink: 

Is it possibel to change your script to work with spaces. I don't have the knowledege to change it.

----------

## MooktaKiNG

I'm afraid not.

The problem arrises here:

```
files=$(cd $dir && ls *.torrent)
```

This basicly gets the output from ls and splits it up using spaces and puts it inside files.

Therefore if you have spaces in the name of one file. It will think its 2 files.

I'm afraid i haven't figured out how to sort this out.

However, it might have been easier to use Python or something like that.

Bash is bash  :Very Happy: 

----------

## Twink

Not the most elegant fix but here is one (perhaps someone else can figure out a better one)

```

dir -1 *.torrent | while true

do

  read file

  [[ "$file" == "" ]] && break

  echo $file

done

```

note that is a "dir -1" (one)  not L or I

----------

## Doxer

First: Thx for your responce.

Second: I solved it:

Here ist the new btdir.sh

```
#!/bin/bash

#########################################################

#  Md Mooktakim Ahmed   mma@mooktakim.com               #

#  http://www.mooktakim.com                             #

#                                                       #

# This is a script i use to start multiple bittorrent   #

# downloads. Basicly i've edited the         #

# btdownloadcurses.py file so that it exits after a   #

# complete download. Then this script runs many    #

# downloads one after the other, so that multiple    #

# downloads is possible, without any intervention.   #

# and i must say it works very well. It keeps a log and   #

# renames the torrent files into .OLD so that it does   #

# not get redownloaded. There is also some nice    #

# colourful outputs, just to complete the whole script   #

#                                                       #

# As always, this script is GPL Licensed.               #

#                                                       #

#########################################################

TMP="btdir.log"

DATE=`date +%Y-%m-%d`

TIME=`date +%r`

##ADDED

IFS="

"

##ADDED end

die()

{

   echo -e $*

   exit 1

}

echo "$DATE - $TIME -- ### New download started ###" >> $TMP

dir=$*

test -d $dir || die "[1;33m$dir [1;31mdoesn't exist\nUsage:\n\tbtdir <dir>"

ls $dir/*.torrent >/dev/null 2>&1 || die "[1;31mNo torrents available in $dir"

files=$(cd $dir && ls *.torrent)

for I in $files

do

   if `test -e $dir/$I`

   then 

      echo "[1;33m$I [1;35mexists"

   else

      echo "-- Torrents doesn't exist" >> $TMP

      echo "-- $dir/$I does not exist" >> $TMP

      echo "-- EXITING" >> $TMP

      die "[1;31mTorrent [1;33m$dir/$I [1;31mdoesn't exist"

   fi

done

echo "-- Torrents exist" >> $TMP

echo "-- Download will now be started..." >> $TMP

echo "[1;36m*** [1;35mAll torrents exist."

echo "[1;36m*** [1;35mDownload will now be started..."

echo "[1;31m***""[1;33m Downloading from $dir ""[1;31m***""[1;36m"

sleep 5

for I in $files

do

   cd $dir || die "[1;31mERROR: [1;31mCannot change to directory [1;33$dir"

   echo "$TIME -- $dir/$I --- Started" >> $TMP

##MODIFIED

   btdownloadcurses.py --minport 6900 --max_upload_rate 3 --maxport 6999 --responsefile "$I" || die "[1;31mERROR: [1;31mbittorrent exited with an error for [1;33$I"

##MODIFIED end

   echo "$TIME -- $dir/$I --- DONE!" >> $TMP

   echo "[1;31m***""[1;33m $I ""[1;31m***""[1;36m"

   mv $I $I.OLD

done

echo "[1;31m***""[1;33m #### ALL ### DONE ### ""[1;31m***""[1;36m"

echo "$TIME -- *** #### ALL ### DONE ### ***" >> $TMP 
```

The important thing is the IFS. I've changed it in the beginning of the script, so the bash doesn't use a space for splitting.

----------

## MooktaKiNG

 *Doxer wrote:*   

> First: Thx for your responce.
> 
> Second: I solved it:
> 
> Here ist the new btdir.sh
> ...

 

Wow  :Very Happy:  :Very Happy: 

absolutely fantastic.

I never heard about this IFS before.

Thanks alot.

----------

## MooktaKiNG

I've now updated the script in my website.

----------

## wjholden

I'd like to run a bittorrent of the x86 Univeral Gentoo Install CD 24/7.  I'm a student at North Carolina State University and we have an OC3 line that's been capped pretty severely, but it can still max out the 10 MBps cables in my dorm pretty easily and I'm really not worried about using TONS of bandwidth.  If they say anything then I have a perfectly legitamite reason to use so much bandwidth and I read the Terms Of Service and it only says that you can't do things that actively damage the network, so uploading a legal torrent should be fine.  I'd like to seed the LiveCD in order to contribute something to the Gentoo project.

However, I really don't feel like opening a window each time I logout or restart my PC (which isnt' very often), so how can I make a console-based bittorrent client run as a Cron job to begin as soon as I boot up?

----------

## chunderbunny

Well it depends on your crom deamon I think. In vixie cron you can set a cron job like this :

```
@reboot screen launchmanycurses.py /path/to/torrents
```

The '@reboot' is a special string which is used to execute a command once, at startup. Screen will automatically launch any program you specify and screen will exit if the program exits.

----------

## Wi1d

Great ideas and topic. My hd curses you all.   :Smile: 

----------

## wjholden

And that's going to run in the background, right?

Are there any cool tricks that I use to grab it from the background and see how much it's uploaded?  Better yet, is there a piece of software or command to monitor all of my combined bandwidth useage?

----------

## chunderbunny

Actually, having just tried it it doesn't work. For some reason Vixie cron isn't executing @reboot commands. But yeah, if you could find a way of executing 'screen btlaunchmanycurses.py /path/to/torrents' at startup (perhaps using /etc/conf.d/local.startup.. but then it runs as root which isn't good) then it would run bittorrent in the background. If you read the how to carefull you will also note that you can use 'screen -r' to reattach the screen session and monitor the bittorrent transfer.

----------

## apyh

http://sourceforge.net/projects/btmanager/

----------

## MooktaKiNG

put it in /etc/conf.d/local.start (using something like "screen btclient" That should start a screen session with the bt command running, when you boot.

Then you can check the session whenever you want.

----------

## chunderbunny

If you put it in /etc/conf.d/local.start the screen and bt session will as root, which isn't exactly ideal. Is there a way to have it executed as a certain user?

----------

## elias`

 *chunderbunny wrote:*   

> If you put it in /etc/conf.d/local.start the screen and bt session will as root, which isn't exactly ideal. Is there a way to have it executed as a certain user?

 

You could just put in there

```
su user -c "command"
```

----------

## wjholden

That's awesome.  Thanks, guys.  I'll be seeding the athlon-xp packages CD and the x86 Universal Install CD once I get everything configured here.  Good thing I work for the campus ISP...lol.

----------

## pharaoh

Ever since I read this thread I've been using btlaunchmanycurses and I love it   :Very Happy: 

I'm curious though - is there any way to change the --max_upload_rate after it's already running?  I like to leave my upload maxed over night, but once I'm using my internet I need to cut it down a little so I can load pages without waiting 5 minutes.  Any ideas?

----------

## wjholden

I don't have an answer to your question.

I'm just wondering what bttrack is when you run rc-update show.  Anyone???

----------

## chunderbunny

That's the tracker service. Every torrent file has an associated tracker server that coordinates the swapping of chunks between peers. If you want to run your own tracker then you start bttrack.

----------

## Deranger

Nice howto. I'm Direct Connect user, but because there's no decent DC client on GNU/Linux yet, I tried BT out and I like it very much  :Wink: 

Especially many instances on screens  :Wink: 

Thanks!

----------

## nx12

what about webtorrent?

----------

## Twink

I remembered seeing this script a month or so back and thinking that I'd have to test it out sometime, well i finally have and like it however I thought of a few extensions that might be nice but i'm having a little trouble with it.

I want to run this as a cron job every X minutes, easy enough however obviously it will have to check if the script is already running before doing anything.  

```

if [ "`ps -A | grep btdir.sh`" != "" ]; then

  exit

fi

```

Looks good but can't be placed inside the same script as it will detect its current instance and exit thus never working.  It could be moved to a different script and execute btdir.sh if the pass checks, it could check for btdownloadcurses.py instead of btdir.sh, or it could 

```

if [ "`ps -A | grep btdir.sh | wc -l`" != "1" ]; then

  exit

fi

```

although I haven't tested this one it should in theory work fine.

Next problem is btdownloadcurses and even btdownloadheadless dont seem to like running without being attached to a terminal for me, no idea why at all.  So i figured screen could come to the rescue.

screen -R bt -X screen btdownloadcurses.py --minport 6900 --max_upload_rate 3 --maxport 6999 --responsefile "$I" ||...

so what that should do in theory is resume (or create) a screen session called bt, then create a new window in the screen and run the btdownload command, doesn't seem to work for me.  I figure i must be doing something wrong but unsure.

So if anyone has done anything similar with this, or with another client etc it would be nice to know about it.  I hear Azureus can monitor directories but i'd rather not have something that relies on X, also i'd like to be able to check up on it remotely which i dont know if i can do with Azureus (rather not run yet another web module thingy, unless it uses like apache maybe?)

----------

## andyfaeglasgow

```
#!/bin/bash

#########################################################

#  Md Mooktakim Ahmed   mma@mooktakim.com               #

#  http://www.mooktakim.com                             #

#                                                       #

# This is a script i use to start multiple bittorrent   #

# downloads. Basicly i've edited the         #

# btdownloadcurses.py file so that it exits after a   #

# complete download. Then this script runs many    #

# downloads one after the other, so that multiple    #

# downloads is possible, without any intervention.   #

# and i must say it works very well. It keeps a log and   #

# renames the torrent files into .OLD so that it does   #

# not get redownloaded. There is also some nice    #

# colourful outputs, just to complete the whole script   #

#                                                       #

# As always, this script is GPL Licensed.               #

#                                                       #

#########################################################

TMP="btdir.log"

DATE=`date +%Y-%m-%d`

TIME=`date +%r`

##ADDED

IFS="

"

##ADDED end

die()

{

   echo -e $*

   exit 1

}

echo "$DATE - $TIME -- ### New download started ###" >> $TMP

dir=$*

test -d $dir || die "[1;33m$dir [1;31mdoesn't exist\nUsage:\n\tbtdir <dir>"

ls $dir/*.torrent >/dev/null 2>&1 || die "[1;31mNo torrents available in $dir"

files=$(cd $dir && ls *.torrent)

for I in $files

do

   if `test -e $dir/$I`

   then 

      echo "[1;33m$I [1;35mexists"

   else

      echo "-- Torrents doesn't exist" >> $TMP

      echo "-- $dir/$I does not exist" >> $TMP

      echo "-- EXITING" >> $TMP

      die "[1;31mTorrent [1;33m$dir/$I [1;31mdoesn't exist"

   fi

done

echo "-- Torrents exist" >> $TMP

echo "-- Download will now be started..." >> $TMP

echo "[1;36m*** [1;35mAll torrents exist."

echo "[1;36m*** [1;35mDownload will now be started..."

echo "[1;31m***""[1;33m Downloading from $dir ""[1;31m***""[1;36m"

sleep 5

for I in $files

do

   cd $dir || die "[1;31mERROR: [1;31mCannot change to directory [1;33$dir"

   echo "$TIME -- $dir/$I --- Started" >> $TMP

##MODIFIED

   btdownloadcurses.py --minport 6900 --max_upload_rate 3 --maxport 6999 --responsefile "$I" || die "[1;31mERROR: [1;31mbittorrent exited with an error for [1;33$I"

##MODIFIED end

   echo "$TIME -- $dir/$I --- DONE!" >> $TMP

   echo "[1;31m***""[1;33m $I ""[1;31m***""[1;36m"

   mv $I $I.OLD

done

echo "[1;31m***""[1;33m #### ALL ### DONE ### ""[1;31m***""[1;36m"

echo "$TIME -- *** #### ALL ### DONE ### ***" >> $TMP 
```

Alternatively it can be done in one line; thus  :Smile: 

```

find . -name '*.torrent' -exec yourTunedTorrentClient.py '{}' ';'

```

Where "yourTunedTorrentClient.py" is one that exits some time after finishing it's download.  (I'd recommend putting a sleep for 10 mins in the .py file to help other uploaders).  Any parameters you wish to pass to the client should be placed after '{}' and before ';'  You could even use this to queue all torrent files in your system, wherever they may be, simply replace the . after find with / .  I'll leave other possibilities up to your imagination.

----------

## eyebex

Nice How-To guys, thanks. However, I just emerged net-p2p/bittorrent-4.1.7 and there are no traces of btdownloadcurses.py or btlaunchmany.py. What do I need to do to get these?

EDIT: I solved the issue by writing my own ebuild for BitTorrent 4.1.8, see https://forums.gentoo.org/viewtopic-p-2889013.html#2889013.

----------

## ra0

I think you should try rtorrent.

IMHO it's the best console bittorrent client out there. It's small,fast and supports multiple downloads.

```
emerge rtorrent
```

----------

## ayem

and works perfectly with screen - so this tutorial is apropriate for this one too.

----------

