# How to install TCL in FreeBSD?



## blades (May 22, 2015)

Howdy guys.

Yesterday, iI tried to install eggdrop in my FreeBSD machine. I got a problem with wget at first but then iI made a research and I tried and it resolve.

Now, the problem is with tcl. In the shell, it says that I have to install TCL. I tried with `pkg install tcl85` but failed.

Any idea/suggestion? Thanks.


----------



## xavi (May 22, 2015)

Try the following:

`pkg install lang/tcl85`

If that still fails then please post the errors that you are getting.
You should also note that tcl86 is the latest version.


----------



## blades (May 22, 2015)

ok xavi. I've done it. It shows like this. http://pastebin.com/uw5jmC6u .

Is it okay now? How to test it?


----------



## xavi (May 22, 2015)

Unfortunately I'm at work so can't look at the link that you posted. However, to run Tcl interactively type `tclsh` at the command prompt to take you into the interactive interpreter. More info on running Tcl can be found here  https://www.tcl.tk/man/tcl8.5/tutorial/Tcl0a.html.


----------



## blades (May 22, 2015)

```
root@FreeBSD:~ # [CMD]tclsh[/CMD]
tclsh: Command not found.
```

Thanks anyway xavi for your effort. I will read the link you gave.


----------



## robroy (May 22, 2015)

Good day Blade,

I see "This paste has been removed" when I visit your URL.

To allow multiple Tcl versions to be installed on the same computer, the `tclsh` executable carries the Tcl version in its name.

Try running Tcl by typing `tclsh8.5` instead of `tclsh`.

Here's how this looks on my computer:


```
% freebsd-version
10.1-RELEASE-p6
% pkg info | grep tcl
tcl86-8.6.3                    Tool Command Language
tcllib-1.16                    Collection of utility modules for Tcl
% which tclsh
tclsh not found
% which tclsh8.6
/usr/local/bin/tclsh8.6
```

To make a particular Tcl version the default, use the root account to create a symbolic link from `tclsh8.5` to `tclsh`, like this:


```
# cd /usr/local/bin
# pwd
/usr/local/bin
# ln -s tclsh8.5 tclsh
```

A related tip:  if you wind up writing any Tcl scripts, here's a portable way to begin them:


```
#!/bin/sh
# Re-start with Tcl \
exec tclsh $0 $@

# Begin your Tcl code here
```

This allows your scripts to work as long as `tclsh` is in one of the directories in your shell's path.  If the root account will ever be used to run your Tcl scripts and/or if you're concerned about security, avoid this convenience and hard-code the path to tclsh instead--otherwise, your script may wind up being run by a malicious wrapper around tclsh.


----------



## tobik@ (May 22, 2015)

robroy said:


> ```
> #!/bin/sh
> # Re-start with Tcl \
> exec tclsh $0 $@
> ...


Why not env(1)?

```
#!/usr/bin/env tclsh
# Begin your Tcl code here
```


----------



## robroy (May 22, 2015)

Good day Tobik,

The `env` trick is sure simpler, and it probably works well for most people.  I actually use it with Python since, as you know, the `exec` trick (well, the exact same trick at least) doesn't work with Python (since a backslash can make a comment to span multiple lines in Tcl, but not in Python).

I picked up the `exec` habit while writing Tcl scripts meant to run on both FreeBSD and SCO OpenServer.

A fresh SCO OpenServer 5.0.6 installation keeps `env` in /bin, but not in /usr/bin, so the `env` trick doesn't work across FreeBSD and OpenServer.  The `exec` trick does, since both systems keep `sh` in /bin.

Based on what I've read in threads like this, fans of the `exec` trick guess that `sh` being located in /bin is a safer bet (applies to more Unix types) than `env` being in /usr/bin.  Yet I'm guessing that some Unix types don't locate `sh` in /bin either, so perhaps neither method applies universally.


----------



## tobik@ (May 22, 2015)

Thanks for explaining. I am concerned about the `exec` trick because it destroys any argument that has whitespace in it, because `sh` does its own tokenization of $@. E.g. the following TCL snippet prints each argument on their own lines:

```
#!/bin/sh
# \
exec tclsh8.5 $0 $@
foreach arg $::argv {puts $arg}
```
If invoked like `./script "bla" "asdf asdf"` it prints 3 lines where I would expect just 2 lines:

```
bla
asdf
asdf
```
With `env` it does the right thing:

```
bla
asdf asdf
```

EDIT:
Reading your link in more detail my script above should be:

```
#!/bin/sh
# \
exec tclsh8.5 "$0" "$@"
foreach arg $::argv {puts $arg}
```
Then it does the right thing.


----------



## robroy (May 22, 2015)

Tobik, thanks for pointing out that the $0 and $@ should be in double-quotes; I think I've been doing that wrong forever, and just lucked out with avoiding multi-word arguments.


----------

