# Running Vivado TCL as a script

**URL:** <https://forum.spacecubics.com/t/running-vivado-tcl-as-a-script/92>\
**Category:** Community\
**Tags:** lang-ja\
**Created:** [April 24, 2023, 5:10pm UTC](https://forum.spacecubics.com/t/running-vivado-tcl-as-a-script/92 "2023-04-24T17:10:51Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![yashi](https://yyz1.discourse-cdn.com/flex029/user_avatar/forum.spacecubics.com/yashi/32/10_2.png) [@yashi](https://forum.spacecubics.com/u/yashi)\
**Post date:** [April 24, 2023, 5:10pm UTC](https://forum.spacecubics.com/t/running-vivado-tcl-as-a-script/92/1 "2023-04-24T17:10:51Z")

</div>

Vivado で TCLファイルを、シェルスクリプトのように実行することができます。

**TL;DR**

スクリプトの先頭を以下のようにしておくと、 `vivado` で TCLスクリプトを簡単に実行することができます。

```auto
#!/bin/sh
# Make the next line a comment line for TCL \
exec vivado -mode batch -nolog -nojournal -notrace -tempDir $(mktemp -d /tmp/vivado.XXXXXXXXXX) -source "$0" -tclargs ${1+"$@"}

```

**Details**

たとえば、

```tcl
puts "hello world"

```

というファイルを `tclsh` で実行する場合は、

```tcl
#!/bin/sh
# the next line restarts using tclsh \
exec tclsh "$0" ${1+"$@"}

puts "hello world"

```

と、します。 実際には シェルスクリプトとして起動されますが、 `exec` コマンドによって自分を `tclsh` に置き換えます。このとき、 `tclsh` には実行しているファイルが第一引数 (`$0`) として渡され、それ以外の引数があれば、それら (`${1+"$@"}`) も渡されます。  
`tclsh` としてこのファイルを読みだした場合、 2行目の `\` によって 3行目も `tclsh` にとってはコメント行の扱いとなります。 3行目以降には TCLが書かれているので `tclsh` はいつも通り TCL を解釈します。  
この Hackは `tchsh` の [manページ](https://www.tcl.tk/man/tcl/UserCmd/tclsh.html)に記載されています。

長々説明しましたが、実は Linux の場合 `puts "hello world"` くらいであれば、こんな Hack は不要です。

```tcl
#!/usr/bin/tclsh
puts "hello world"

```

これで正しく実行できます。

では、なぜこんな面倒な説明をしているのかというと `#!` ではいくつか制限があるためです。最大の問題は `$PATH` 環境変数からコマンドを探してくれないという問題です。

現実的には、この問題は `env` を使うことでほとんどの場合は解決します。 `python3` を使う人は よく  
`#! /usr/bin/env python3` という shebang を見るはずです。 `env` は歴史的に `/usr/bin/env` に install されているので、これをつかって `python3` を探します。

この解決方法によって、 さらに問題が発生します。 `env` は (こちらも歴史的に) 引数をまとめて渡すという仕様になっています。最近の GNU coreutils に含まれる `env` では `-S` オプションがあるので問題ないのですが、逆に古い `env` を使っているシステムとの互換性がなくなります。[このへんは Wikipedia に詳細](https://en.wikipedia.org/wiki/Shebang_(Unix))がかかれているので、興味がある人は確認してみてください。

で、 `env -S` に依存しない方法として、一度 shell script として実行し、置き換えるという手法がとられるのでした。

`vivado` を利用する場合は、以下の通りです。

```tcl
#!/bin/sh
# Make the next line a comment line for TCL \
exec vivado -mode batch -nolog -nojournal -notrace -tempDir $(mktemp -d /tmp/vivado.XXXXXXXXXX) -source "$0" -tclargs ${1+"$@"}
puts "hello world"

```

- `-mode`: `vivado` には 3つのモード(`gui`, `tcl`, `batch`)があります。 script のときは `batch`を指定
- `nolog`: `vivado.log` ファイルの生成を抑制
- `nojournal`: `vivado.jou` ファイルの生成を抑制
- `notrace`: TCLの実行トレースの表示を抑制 (指定しても表示されるものはある)
- `tempDir`: `vivado` が使用する temporary directory を指定。これを指定しないと、複数の `vivado` コマンドが同じディレクトリを使って、想定外の挙動をすることがある
- `source`: スクリプトのソースファイルの指定
- `-tclargs`: スクリプトファイルへの引数の指定
