Using go run with #!

3,828 views
Skip to first unread message

Miki Tebeka

unread,
Feb 26, 2012, 11:03:25 AM2/26/12
to golan...@googlegroups.com
Greetings,

Is there a way to make the new "go run" command play with #!  (so I can have scripts)?
(And yeah, I know about goscript and gorun)

Thanks,
--
Miki

kritic

unread,
Feb 26, 2012, 11:09:47 AM2/26/12
to golang-nuts
Actually, there is a program out there called "gorun". If you use
Ubuntu you can check out the wiki here https://wiki.ubuntu.com/gorun

It allows you to run programs as "scripts" with the #!.

Pretty wicked little program.

Christoffer Hallas

unread,
Feb 26, 2012, 11:39:53 AM2/26/12
to kritic, golang-nuts
If you know about gorun and goscript, then why do you ask?

Archos

unread,
Feb 26, 2012, 1:09:02 PM2/26/12
to golang-nuts
I'm the author of goscript which was renamed to gonow(https://
github.com/kless/GoNow).

The only way that I had to run a Go program like if it were an
executable Python script was using a little trick: to checking the
first line to see if it has the shebang/hash-bang mechanism (#!); if
it's found then there are 2 options, one is copy all file excep the
first line (I did this one in my first versions), and the another one
is comment that first line, so the Go compiler can compile it.

To avoid that trick there are two ways:

(1) That the Go compiler accepts the shebang before of the package
clause. I was request it here when I was building GoNow but it was
rejected.

(2) That the bash shell (and another ones) accept "//!" like shebang
mechanism. This solution looks me very acceptable so there would be to
ask it to the maintainer of those programs.

Rémy Oudompheng

unread,
Feb 26, 2012, 1:32:48 PM2/26/12
to Archos, golang-nuts
Le 26 février 2012 19:09, Archos <raul...@sent.com> a écrit :
> (2) That the bash shell (and another ones) accept "//!" like shebang
> mechanism. This solution looks me very acceptable so there would be to
> ask it to the maintainer of those programs.

Including patching the Linux kernel itself?

Rémy.

Archos

unread,
Feb 26, 2012, 1:41:30 PM2/26/12
to golang-nuts
The patch would be simple, in "fs/binfmt_script.c". Anyway, this
solution would be only valid for Unix systems.

On Feb 26, 6:32 pm, Rémy Oudompheng <remyoudomph...@gmail.com> wrote:

John Eikenberry

unread,
Feb 26, 2012, 4:51:38 PM2/26/12
to golang-nuts
Rémy Oudompheng wrote:

With binfmt_misc support this isn't necessary. You can get Linux to recognize
the go script and run it based on the extension or magic number. To get it to
run via the extension you can do this on any Debian based system.


apt-get install binfmt-support

cd ~

cat > gorun << EOF
#!/bin/sh

cd \$(dirname \$@)
/full/path/to/go run "\$(basename \$@)"
EOF

chmod 755 gorun

sudo update-binfmts --install go ~/gorun --extension go


It is probably possible to get this working with the magic number using as
well. This could be added to the packages for those platforms. But this is
Linux specific.

--

John Eikenberry
[ j...@zhar.net - http://zhar.net ]
[ PGP public key @ http://zhar.net/jae_at_zhar_net.gpg ]
________________________________________________________________________
"Perfection is attained, not when no more can be added, but when no more
can be removed." -- Antoine de Saint-Exupery

signature.asc

Mike Rosset

unread,
Feb 26, 2012, 5:49:12 PM2/26/12
to Miki Tebeka, golan...@googlegroups.com


I created a go program to register .go files with binfmt and then run
them with go run.

Install go-binfmt.

$ go get github.com/str1ngs/go-binfmt


To use go-binfmt first register it with binfmt.

$ sudo $GOPATH/bin/go-binfmt -register

To run a go file give it executable permissions, and then run it.

$ chmod +x main.go
$ ./main.go

Miki Tebeka

unread,
Feb 27, 2012, 9:59:34 AM2/27/12
to golan...@googlegroups.com, kritic
I'm using "gorun" now, but I was wondering if this can be done in "pure" go toolchain.


On Sunday, February 26, 2012 8:39:53 AM UTC-8, Christoffer Hallas wrote:
If you know about gorun and goscript, then why do you ask?

Gustavo Niemeyer

unread,
Feb 27, 2012, 12:18:41 PM2/27/12
to Miki Tebeka, golan...@googlegroups.com, kritic
Hi Miki,

On Mon, Feb 27, 2012 at 11:59, Miki Tebeka <miki....@gmail.com> wrote:
> I'm using "gorun" now, but I was wondering if this can be done in "pure" go
> toolchain.

I've already offered to include gorun into the standard distribution,
but the consensus was that having it as its own tool was a better
approach.

This sounds fine, to be honest. "go get launchpad.net/gorun" isn't
really a big deal.

--
Gustavo Niemeyer
http://niemeyer.net
http://niemeyer.net/plus
http://niemeyer.net/twitter
http://niemeyer.net/blog

-- I'm not absolutely sure of anything.

Jens-Uwe Mager

unread,
Feb 27, 2012, 3:21:19 PM2/27/12
to golan...@googlegroups.com, Miki Tebeka, kritic
I do use gorun, and while it runs fine on tip on Linux, for OS X I had to do the following change:

$ bzr diff
=== modified file 'gorun.go'
--- gorun.go    2012-02-24 00:36:45 +0000
+++ gorun.go    2012-02-27 15:08:25 +0000
@@ -269,7 +269,7 @@
     }
     infos, err := d.Readdir(-1)
     for _, info := range infos {
-        atim := sysStat(info).Atim
+        atim := sysStat(info).Atimespec
         access := time.Unix(int64(atim.Sec), int64(atim.Nsec))
         if access.Before(cleanLine) {
             os.Remove(filepath.Join(rundir, info.Name()))

Gustavo Niemeyer

unread,
Feb 27, 2012, 5:25:45 PM2/27/12
to Jens-Uwe Mager, golan...@googlegroups.com, Miki Tebeka, kritic
Ah, thanks for the note. I'll make sure it builds out of the box for
you as well.

dlin

unread,
Feb 28, 2012, 5:59:31 AM2/28/12
to golan...@googlegroups.com
I prefer native "#!" support of Go. (Just like python).
So, the tool set about vex,fix,fmt can work on it.

There are something should be supported.

1. Go can skip first line if it is started with "#!"
2. #! /usr/bin/env gorun      # can launch it directly, here use 'gorun' instead of "go run"
3. #! /usr/bin/go run # it may be not so good, because go is not necessary to install into /usr/bin


Miki Tebeka於 2012年2月27日星期一UTC+8上午12時03分25秒寫道:

Rob 'Commander' Pike

unread,
Feb 28, 2012, 6:08:39 AM2/28/12
to dlin, golan...@googlegroups.com

On 28/02/2012, at 9:59 PM, dlin wrote:

> I prefer native "#!" support of Go. (Just like python).

Go is not just like Python. It's abusive to run a compiler and linker every time a command is run.

The design of Go is careful about dependencies and the cost of program construction. That care should not be disregarded.

You are not expected to understand this.

-rob


mattn

unread,
Feb 28, 2012, 8:11:52 AM2/28/12
to golan...@googlegroups.com, Jens-Uwe Mager, Miki Tebeka, kritic
It seems that gorun does not run on windows.


But this removed some part to check UID/EUID in sysStat.

Sorry about OT.

DisposaBoy

unread,
Feb 28, 2012, 1:21:49 PM2/28/12
to golan...@googlegroups.com
FYI Python doesn't have any special support for the shebang line and neither does your shellscripts. it's a comment in the source code.

Gustavo Niemeyer

unread,
Feb 28, 2012, 1:37:09 PM2/28/12
to mattn, golan...@googlegroups.com, Jens-Uwe Mager, Miki Tebeka, kritic
On Tue, Feb 28, 2012 at 10:11, mattn <matt...@gmail.com> wrote:
> It seems that gorun does not run on windows.

That's only because Windows isn't home for Gustavo. Patches that
enable it to work without changing Linux/MacOS semantics accepted,
though.

unread,
Feb 28, 2012, 2:02:49 PM2/28/12
to golang-nuts
The Go compiler is slow for this. It would be disturbing to wait up to
1 second every time you run the script.

The idea would need a compiler cache in order to work.

André Moraes

unread,
Feb 28, 2012, 2:07:27 PM2/28/12
to golang-nuts
> The Go compiler is slow for this. It would be disturbing to wait up to
> 1 second every time you run the script.

I think this is what Rob pointed above.

> The idea would need a compiler cache in order to work.

gorun does that.

--
André Moraes
http://andredevchannel.blogspot.com/

unread,
Feb 28, 2012, 2:10:00 PM2/28/12
to golang-nuts
I do not understand why he isn't expected to understand it. It is a
simple idea.

minux

unread,
Feb 28, 2012, 2:11:14 PM2/28/12
to golang-nuts


2012/2/29 André Moraes <and...@gmail.com>

> The Go compiler is slow for this. It would be disturbing to wait up to
> 1 second every time you run the script.

I think this is what Rob pointed above.
Yeah, and I think compiler speed is one design goal of Go.
And I think the gc compiler do achieve that goal (compared to gccgo).
[Of course, gccgo do provide better binaries.]

minux

unread,
Feb 28, 2012, 2:15:57 PM2/28/12
to ⚛, golang-nuts
I think he is simply making a joke citing some early Unix comment: http://swtch.com/unix/

unread,
Feb 28, 2012, 2:34:46 PM2/28/12
to golang-nuts
On Feb 28, 8:15 pm, minux <minux...@gmail.com> wrote:
It is probable you are right it was a joke related to http://swtch.com/unix/

In any case: In my opinion, recompilation of source code is a decision
that should be left to the programmer/user. The worst example is Bash:
editing the source code of a running Bash script (especially at the
beginning of the file) will probably cause a syntax error in the
running script.

Krzysztof Kowalczyk

unread,
Feb 28, 2012, 6:59:41 PM2/28/12
to Rob 'Commander' Pike, dlin, golan...@googlegroups.com
On Tue, Feb 28, 2012 at 3:08 AM, Rob 'Commander' Pike <r...@google.com> wrote:
>
> On 28/02/2012, at 9:59 PM, dlin wrote:
>
>> I prefer native "#!" support of Go. (Just like python).
>
> Go is not just like Python. It's abusive to run a compiler and linker every time a command is run.
>
> The design of Go is careful about dependencies and the cost of program construction. That care should not be disregarded.

If implemented, it wouldn't change the existing properties of Go
compiler for existing use cases.

Even if it was slow, that's a new use case and if I'm willing to take
the startup hit for the convenience of being able to replace my Python
scripts with scripts written in Go then why someone else's opinion of
what is slow should matter?

Except it doesn't have to be slow. Correct me if I'm wrong, but go
compiler is already smart enough to not recompile and relink if the
source code being compiled and all of it's dependencies hasn't changed
and that's exactly the logic needed for making this use case fast.

Really all we're asking is that Go doesn't barf with syntax error if
first line of the .go file starts with #! and skip it.

Even if Go team doesn't personally think that gorun-like usage is
useful or needs to be supported by go distribution, that small change
alone would allow others to easily implement gorun-like capability.

It would be preferable to have that simply as part of Go distribution
but the second best option would be apt-get install gorunner written
by whomever and being able to chmod u+x myscript.go && ./myscript.go
to run it as long as it has the magic #!

-- kjk

Rob 'Commander' Pike

unread,
Feb 28, 2012, 7:05:09 PM2/28/12
to Krzysztof Kowalczyk, dlin, golan...@googlegroups.com

You dropped the last sentence of my message.

-rob

Jessta

unread,
Feb 28, 2012, 7:41:05 PM2/28/12
to Krzysztof Kowalczyk, golan...@googlegroups.com
On Wed, Feb 29, 2012 at 10:59 AM, Krzysztof Kowalczyk
<kkowa...@gmail.com> > It would be preferable to have that simply as

part of Go distribution
> but the second best option would be apt-get install gorunner written
> by whomever and being able to chmod u+x myscript.go && ./myscript.go
> to run it as long as it has the magic #!

The standard Go distribution shouldn't encourage developers to write
slow code. Adding a #! syntax would be an encouragement to do
something silly. Right now the silliness is limited to the people
determined enough to install an external program and thus requires
that they at least have thought about how silly it is.

Perhaps a better option for you is to setup an inotify that runs the
compiler every time you change one of the scripts, thus it only needs
to invoke the compiler when changes occur instead of every time the
script is run. That would be far more sensible.


--
=====================
http://jessta.id.au

Krzysztof Kowalczyk

unread,
Feb 28, 2012, 7:46:00 PM2/28/12
to Rob 'Commander' Pike, dlin, golan...@googlegroups.com
Because I don't particularly care to decode your crypticism. I can
match anyone's snark but its Tuesday so I try to stay constructive.

If you want to stay on topic and backup your previous assertions that
gorun-like tool cannot be made fast or englighten us why it's such a
big deal to skip #! then please do, preferably in non-cryptic way.

-- kjk

Krzysztof Kowalczyk

unread,
Feb 28, 2012, 7:57:25 PM2/28/12
to Jessta, golan...@googlegroups.com
A little more respect to people who have different opinion than you
would be nice. Calling me (and designers and users of perl, php,
python, ruby, to name a few) "silly" is ad hominem and not
constructive.

I described how it's trivial to avoid speed penalty in that system so
your performance arguments are wrong.

Sure, there are many possible Goldberg contraptions that I could use
but that defeats the purpose which is: convenience.

There's a reason #! convention is honored by virtually every dynamic
language implementation:
"silly" people want it because people use it because it's a useful feature.

-- kjk

Andrew Gerrand

unread,
Feb 28, 2012, 8:00:58 PM2/28/12
to Krzysztof Kowalczyk, Rob 'Commander' Pike, dlin, golan...@googlegroups.com
On 29 February 2012 11:46, Krzysztof Kowalczyk <kkowa...@gmail.com> wrote:
> Because I don't particularly care to decode your crypticism. I can
> match anyone's snark but its Tuesday so I try to stay constructive.
>
> If you want to stay on topic and backup your previous assertions that
> gorun-like tool cannot be  made fast or englighten us why it's such a
> big deal to skip #! then please do, preferably in non-cryptic way.

The issue has been discussed ad nauseam on this very mailing list.
Search the archives. (I apologize that the Groups search isn't very
good.)

This was a design decision and such decisions can't suit everyone. We
can talk about it all day, but the decision has already been made. For
what it's worth, no new points have been raised by this thread.

Jessta has done a reasonable job of summarizing the rationale.

On 29 February 2012 11:57, Krzysztof Kowalczyk <kkowa...@gmail.com> wrote:
> There's a reason #! convention is honored by virtually every dynamic
> language implementation:
> "silly" people want it because people use it because it's a useful feature.

Go isn't a dynamic language.

You seem hurt that your opinion isn't being heard - but please know
that you are not alone in your opinions. Others have held the same
opinion and have already been heard. Don't take it personally that we
don't have time to re-hash old discussions. It's not much fun, anyway.

Andrew

Gustavo Niemeyer

unread,
Feb 28, 2012, 8:27:52 PM2/28/12
to Krzysztof Kowalczyk, Rob 'Commander' Pike, dlin, golan...@googlegroups.com
On Tue, Feb 28, 2012 at 21:46, Krzysztof Kowalczyk <kkowa...@gmail.com> wrote:
> If you want to stay on topic and backup your previous assertions that
> gorun-like tool cannot be  made fast or englighten us why it's such a
> big deal to skip #! then please do, preferably in non-cryptic way.

Why are you spending your energy arguing? Installing gorun is
trivial, and it works as you want. Just put it to good use and spend
your energy having fun with some Go code.

Joseph Poirier

unread,
Feb 29, 2012, 1:13:35 AM2/29/12
to Andrew Gerrand, Krzysztof Kowalczyk, Rob 'Commander' Pike, dlin, golan...@googlegroups.com
On Tue, Feb 28, 2012 at 7:00 PM, Andrew Gerrand <a...@golang.org> wrote:
> On 29 February 2012 11:46, Krzysztof Kowalczyk <kkowa...@gmail.com> wrote:
>> Because I don't particularly care to decode your crypticism. I can
>> match anyone's snark but its Tuesday so I try to stay constructive.
>>
>> If you want to stay on topic and backup your previous assertions that
>> gorun-like tool cannot be  made fast or englighten us why it's such a
>> big deal to skip #! then please do, preferably in non-cryptic way.
>
> The issue has been discussed ad nauseam on this very mailing list.
> Search the archives. (I apologize that the Groups search isn't very
> good.)
>
> This was a design decision and such decisions can't suit everyone. We
> can talk about it all day, but the decision has already been made. For
> what it's worth, no new points have been raised by this thread.
>
> Jessta has done a reasonable job of summarizing the rationale.
>
> On 29 February 2012 11:57, Krzysztof Kowalczyk <kkowa...@gmail.com> wrote:
>> There's a reason #! convention is honored by virtually every dynamic
>> language implementation:
>> "silly" people want it because people use it because it's a useful feature.
>
> Go isn't a dynamic language.

I don't care one way or the other about this feature but the FUD is ridiculous.

Serious misnomer...there's not much scripting happening when all the
sha-bang is being used for is to start the compiler, and in no way
does that require the source in the file to be dynamic. The compiler
runs the way it always does, as does the executable.

The Tiny C Compiler handles files being run from the system
(http://bellard.org/tcc/), which is what the shell is doing when it
sees a sha-bang on the first line of a file, just fine. But then that
makes perfect sense because all that's being scripted is the
invocation of the compiler.

E.g. when bash sees the sha-bang in a tcc file all it does is invoke
tcc with the -run option (from the sha-bang line) and the name of the
file to be compiled. When tcc sees the -run option it knows A) to skip
the first line of the file and B) compile the file then immediately
run the executable. That's it. WTF is the big deal.

#!/usr/local/bin/tcc -run
#include <stdio.h>
int main()
{
printf("Hello World\n");
return 0;
}

-joe

Henrik Johansson

unread,
Feb 29, 2012, 2:00:36 AM2/29/12
to golan...@googlegroups.com
I use gorun a lot for tiny scripts, i find it faster and easier to write a small bit of Go than bash or something similar.
Sure backticks and such would be handy but not a huge issue.

I understand the points of the opposition here but having things such as this and for example a repl is not at all a bad choice for a typed compiled language. Haskell has both and its statically super-typed.

I get by with gorun, it works fine and its not a hassle to have to install an extra bit of code. It does not make me not miss a repl however but it can be added later so it has never been a real worry though.

Can we visit this issue at some time later when Go 1 has landed and had more exposure?

Mike Rosset

unread,
Feb 29, 2012, 2:45:12 AM2/29/12
to Henrik Johansson, golan...@googlegroups.com
> I use gorun a lot for tiny scripts, i find it faster and easier to write a small bit of Go than bash or something similar.
> Sure backticks and such would be handy but not a huge issue.
>
> I understand the points of the opposition here but having things such as this and for example a repl is not at all a bad choice for a typed compiled language. Haskell has both and its statically super-typed.
>
> I get by with gorun, it works fine and its not a hassle to have to install an extra bit of code. It does not make me not miss a repl however but it can be added later so it has never been a real worry though.
>
> Can we visit this issue at some time later when Go 1 has landed and had more exposure?

I'm going to have to agree, that shebang support for a statically
compiled language is a unique feature. We understand that there is
some overhead with this, however it really does compliment Go
compilation speeds. (Also I could port all my pythong/ruby/bash crap
to a nice expressive language like go)

Also one point I would like to make it that with the release of Go1,
Having shebang support would actually help the Go bootstrap process,
Since we could rely on Go1 instead of say bash, We could say move
make.bash, all.bash to make.go all.go. Also we could possibly port a
bit of the C code in dist to go. And rely more on Go1 for
bootstrapping.

Just a thought.

Kyle Lemons

unread,
Feb 29, 2012, 3:05:57 AM2/29/12
to Mike Rosset, Henrik Johansson, golan...@googlegroups.com
I'm going to have to agree, that shebang support for a statically
compiled language is a unique feature. We understand that there is
some overhead with this, however it really does compliment Go
compilation speeds. (Also I could port all my pythong/ruby/bash crap
to a nice expressive language like go)

Compilation speed is good, but it's still not instant.  Python, for instance, is a lot closer to instant than compiling and executing a Go executable (the bottleneck is primarily in the link step in my experience).  If you encourage programmers to write code in shell-script style, I have a strong suspicion that the "scripts" would do what python and bash scripts do--outgrow themselves.  Then when it is well past the time where it should be converted to a binary with supporting packages, the programmer will still be fighting that because it's a pain and it changes their process.  This is not a good scenario, especially when the rest of the Go ecosystem (to my mind) encourages good practices.
 
Also one point I would like to make it that with the release of Go1,
Having shebang support would actually help the Go bootstrap process,
Since we could rely on Go1 instead of say bash, We could say move
make.bash, all.bash to make.go all.go. Also we could possibly port a
bit of the C code in dist to go. And rely more on Go1 for
bootstrapping.

Chicken and egg.  You have to start somewhere.  Bash exists and works well.

unread,
Feb 29, 2012, 3:18:54 AM2/29/12
to golang-nuts
In my opinion, the following code:

#!/usr/local/bin/tcc -run
#include <stdio.h>
int main() {
    printf("Hello World\n");
    return 0;
}

can be easily converted into:

hello.c:
#include <stdio.h>
int main() {
    printf("Hello World\n");
    return 0;
}

executable file ~/bin/tcr:
#!/bin/bash
first="$1"
exe="${first%.c}"
tcc -o "${exe}" "$@"
./${exe}
rm -f "${exe}"

When you type "tcr hello.c" on the command line it compiles the C file
and runs it.

In other words, there is no need for TCC to have the -run option.

A universal "run" command that can compile&run pretty much any kind of
source code can be implemented so easily that there is very little
value to put such functionality into programming language
implementations of C, Go, Haskell or even Python:

#!run c
<<<c code>>>

#!run go
<<<go code>>>

#!run haskell
<<<haskell code>>>

#!run python
<<<python code, without #!/usr/bin/python at beginning>>>

On Feb 29, 7:13 am, Joseph Poirier <jdpoir...@gmail.com> wrote:
> On Tue, Feb 28, 2012 at 7:00 PM, Andrew Gerrand <a...@golang.org> wrote:
> > On 29 February 2012 11:46, Krzysztof Kowalczyk <kkowalc...@gmail.com> wrote:
> >> Because I don't particularly care to decode your crypticism. I can
> >> match anyone's snark but its Tuesday so I try to stay constructive.
>
> >> If you want to stay on topic and backup your previous assertions that
> >> gorun-like tool cannot be  made fast or englighten us why it's such a
> >> big deal to skip #! then please do, preferably in non-cryptic way.
>
> > The issue has been discussed ad nauseam on this very mailing list.
> > Search the archives. (I apologize that the Groups search isn't very
> > good.)
>
> > This was a design decision and such decisions can't suit everyone. We
> > can talk about it all day, but the decision has already been made. For
> > what it's worth, no new points have been raised by this thread.
>
> > Jessta has done a reasonable job of summarizing the rationale.
>
> > On 29 February 2012 11:57, Krzysztof Kowalczyk <kkowalc...@gmail.com> wrote:
> >> There's a reason #! convention is honored by virtually every dynamic
> >> language implementation:
> >> "silly" people want it because people use it because it's a useful feature.
>
> > Go isn't a dynamic language.
>
> I don't care one way or the other about this feature but the FUD is ridiculous.
>
> Serious misnomer...there's not much scripting happening when all the
> sha-bang is being used for is to start the compiler, and in no way
> does that require the source in the file to be dynamic. The compiler
> runs the way it always does, as does the executable.
>
> The Tiny C Compiler handles files being run from the system
> (http://bellard.org/tcc/), which is what the shell is doing when it
> sees a sha-bang on the first line of a file, just fine. But then that
> makes perfect sense because all that's being scripted is the
> invocation of the compiler.
>
> E.g. when bash sees the sha-bang in a tcc file all it does is invoke
> tcc with the -run option (from the sha-bang line) and the name of the
> file to be compiled. When tcc sees the -run option it knows A) to skip
> the first line of the file and B) compile the file then immediately
> run the executable. That's it. WTF is the big deal.

Ideas are supposed to be fought with better ideas - not with
vulgarisms.

Mike Rosset

unread,
Feb 29, 2012, 3:28:46 AM2/29/12
to Kyle Lemons, Henrik Johansson, golan...@googlegroups.com
>> I'm going to have to agree, that shebang support for a statically
>> compiled language is a unique feature. We understand that there is
>> some overhead with this, however it really does compliment Go
>> compilation speeds. (Also I could port all my pythong/ruby/bash crap
>> to a nice expressive language like go)
>
>
> Compilation speed is good, but it's still not instant.  Python, for
> instance, is a lot closer to instant than compiling and executing a Go
> executable (the bottleneck is primarily in the link step in my experience).
>  If you encourage programmers to write code in shell-script style, I have a
> strong suspicion that the "scripts" would do what python and bash scripts
> do--outgrow themselves.  Then when it is well past the time where it should
> be converted to a binary with supporting packages, the programmer will still
> be fighting that because it's a pain and it changes their process.  This is
> not a good scenario, especially when the rest of the Go ecosystem (to my
> mind) encourages good practices.

go run main.go works right now, on the same code that I use go build
on. Invoking go run from a shebang vs go run or go build, will have no
impact on how the code is written. And I can still import packages
which I would argue makes for less code in the long run, since I'll
use all my helper packages which all have test units.

>> Also one point I would like to make it that with the release of Go1,
>> Having shebang support would actually help the Go bootstrap process,
>> Since we could rely on Go1 instead of say bash, We could say move
>> make.bash, all.bash to make.go all.go. Also we could possibly port a
>> bit of the C code in dist to go. And rely more on Go1 for
>> bootstrapping.

> Chicken and egg.  You have to start somewhere.  Bash exists and works well.

Yes on unix, however tell that to the windows guys where we have
all.bat and make.bat.

dlin

unread,
Feb 29, 2012, 3:36:30 AM2/29/12
to golan...@googlegroups.com
To try to explain I like the idea to builtin shebang in Go (maybe after Go1).

1. encourage people to taste Go without hurt original system. (just use it to replace python/shell)
2. with shebang builtin, other useful tool work well( eg. gocode,gofmt,gofix).
3. all code/script in Go is cool and clean and easy to keep same style, don't require to learn other language.

To let it beat with exist shell script, maybe implement following will useful
1. support  first line shebang.
2. support omit the 'package main ; import "os" ; func main() {}' when script don't require import.
3. support auto import common library 'os,flag,...' which shell script often used.

Well, this topic is really hot, but, I think it could be delayed after Go 1 to discuss.

Andrew Gerrand

unread,
Feb 29, 2012, 3:38:44 AM2/29/12
to Mike Rosset, golang-nuts, Henrik Johansson, Kyle Lemons

I still don't see how that would help much with bootstrapping. Are you saying we should rewrite everything in Go and ship Go compiler binaries for all platforms we want to support? Sounds like a lot of work for a very marginal gain, and is hardly a good argument for shebang support since it comes down only to the difference between  "./make.go" and "go run make.go", and that's a command you only type once.

Andrew

Joseph Poirier

unread,
Feb 29, 2012, 3:38:56 AM2/29/12
to Mike Rosset, Kyle Lemons, Henrik Johansson, golan...@googlegroups.com
On Wed, Feb 29, 2012 at 2:28 AM, Mike Rosset <mike....@gmail.com> wrote:
>>> I'm going to have to agree, that shebang support for a statically
>>> compiled language is a unique feature. We understand that there is
>>> some overhead with this, however it really does compliment Go
>>> compilation speeds. (Also I could port all my pythong/ruby/bash crap
>>> to a nice expressive language like go)
>>
>>
>> Compilation speed is good, but it's still not instant.  Python, for
>> instance, is a lot closer to instant than compiling and executing a Go
>> executable (the bottleneck is primarily in the link step in my experience).
>>  If you encourage programmers to write code in shell-script style, I have a
>> strong suspicion that the "scripts" would do what python and bash scripts
>> do--outgrow themselves.  Then when it is well past the time where it should
>> be converted to a binary with supporting packages, the programmer will still
>> be fighting that because it's a pain and it changes their process.  This is
>> not a good scenario, especially when the rest of the Go ecosystem (to my
>> mind) encourages good practices.
>
> go run main.go works right now, on the same code that I use go build
> on. Invoking go run from a shebang vs go run or go build, will have no
> impact on how the code is written. And I can still import packages
> which I would argue makes for less code in the long run, since I'll
> use all my helper packages which all have test units.

Right. The shebang is a magic number (no different from a binary
executable's magic number) and having it in a file doesn't
automatically make the file a script. If there's a callable program at
the end of the shebang string, options are collected, arg[0] is set to
the file name, and execv is called (shell_execve (execname, args,
env).

So adding "#!/usr/local/go/bin/go run" to a file and running it from
the command line is exactly the same as doing $ go run x.go

Sanjay Menakuru

unread,
Feb 29, 2012, 3:57:36 AM2/29/12
to golan...@googlegroups.com, Mike Rosset, Kyle Lemons, Henrik Johansson
 `go install myscript && myscript`, `go build && ./myscript` and `chmod u+x myscript.go && ./myscript.go` seem like equivalent amounts of typing to me.

Are you trying to save typing when actively modifying the script? Doesn't seem like a great idea anyways; you might have syntax errors or something.

Sanjay

Joseph Poirier

unread,
Feb 29, 2012, 3:57:33 AM2/29/12
to Mike Rosset, Kyle Lemons, Henrik Johansson, golan...@googlegroups.com

edit: args[0] = execname and not the file name

Mike Rosset

unread,
Feb 29, 2012, 3:59:53 AM2/29/12
to Andrew Gerrand, golang-nuts, Henrik Johansson, Kyle Lemons
> I still don't see how that would help much with bootstrapping. Are you
> saying we should rewrite everything in Go and ship Go compiler binaries for
> all platforms we want to support? Sounds like a lot of work for a very
> marginal gain

Good point, also porting to other Os/Arch would be an issue. So yes
bad example. might still be nice for windows though vs make.bat

> And is hardly a good argument for shebang support since it


> comes down only to the difference between  "./make.go" and "go run make.go",
> and that's a command you only type once.

Yes, but that still has to be done every time, sure this is one case
where you can argue thats easy to type. The fact that go run exists
means that the Go team has situations where they find this useful,
adding shebang support to the compiler to avoid shell wrapper scripts
for those situations IMO is well worth the effort.

minux

unread,
Feb 29, 2012, 4:08:13 AM2/29/12
to Mike Rosset, Andrew Gerrand, golang-nuts, Henrik Johansson, Kyle Lemons
On Wed, Feb 29, 2012 at 4:59 PM, Mike Rosset <mike....@gmail.com> wrote:
> I still don't see how that would help much with bootstrapping. Are you
> saying we should rewrite everything in Go and ship Go compiler binaries for
> all platforms we want to support? Sounds like a lot of work for a very
> marginal gain

Good point, also porting to other Os/Arch would be an issue. So yes
bad example. might still be nice for windows though vs make.bat
Why make.bat is bad?
I don't think we should require a go compiler to be able to bootstrap.
It will also make porting to other platforms difficult.
> And is hardly a good argument for shebang support since it
> comes down only to the difference between  "./make.go" and "go run make.go",
> and that's a command you only type once.

Yes, but that still has to be done every time, sure this is one case
where you can argue thats easy to type. The fact that go run exists
means that the Go team has situations where they find this useful,
adding shebang support to the compiler to avoid shell wrapper scripts
for those situations IMO is well worth the effort.
If you would run the script only once, then don't hurt to type 'go run some.go',
and if you would like to run the script several times, then why not just build
it with 'go build some.go'? If you really really want the script functionality,
you could modify gorun program to strip the shebang line from the script
before sent it to compiler, and use '#!/usr/bin/env gorun'.

I frequently use the 'go run' feature, but only for some one-time test programs,
and 'chmod +x' it then run it seems harder than simply 'go run' it.

minux

unread,
Feb 29, 2012, 4:14:48 AM2/29/12
to Mike Rosset, Andrew Gerrand, golang-nuts, Henrik Johansson, Kyle Lemons
On Wed, Feb 29, 2012 at 5:08 PM, minux <minu...@gmail.com> wrote:
On Wed, Feb 29, 2012 at 4:59 PM, Mike Rosset <mike....@gmail.com> wrote:
> I still don't see how that would help much with bootstrapping. Are you
> saying we should rewrite everything in Go and ship Go compiler binaries for
> all platforms we want to support? Sounds like a lot of work for a very
> marginal gain

Good point, also porting to other Os/Arch would be an issue. So yes
bad example. might still be nice for windows though vs make.bat
Why make.bat is bad?
I don't think we should require a go compiler to be able to bootstrap.
It will also make porting to other platforms difficult.
Also note, on some OS-Arch combinations (Linux/ARM), we simply can't provide a universal
compiler binary which can be run on every possible platforms.
soft/hard floating point, arm/thumb, oabi/eabi, different dynamic linker, different libc, etc.

Rob 'Commander' Pike

unread,
Feb 29, 2012, 4:17:26 AM2/29/12
to minux, Mike Rosset, Andrew Gerrand, golang-nuts, Henrik Johansson, Kyle Lemons
Let's just get rid of files altogether. They always have the wrong contents. Make everything dynamic. The computer should just do what I want without me having to write anything down. Commands can go, too. Stupid things.

-rob

Mike Rosset

unread,
Feb 29, 2012, 4:24:08 AM2/29/12
to minux, Andrew Gerrand, golang-nuts, Henrik Johansson, Kyle Lemons
> Also note, on some OS-Arch combinations (Linux/ARM), we simply can't provide
> a universal
> compiler binary which can be run on every possible platforms.
> soft/hard floating point, arm/thumb, oabi/eabi, different dynamic linker,
> different libc, etc.

Yes, and some Linux/ARM systems do not even have bash, ie andriod. I
do think decoupling bootstrapping with bash, vs building from hg
without bash and Go1 would make build on windows alot easier even if
required you to install Go1 binaries. But all that is offtopic and
just a use case.

My real point is that I much rather be coding things in Go where
possible vs bash,bat,ruby,python and have the convenience of a
shebang. But all in all I can use go run, or a shell wrapper to go
run, in those cases so I wont press the issue.

minux

unread,
Feb 29, 2012, 4:29:47 AM2/29/12
to Mike Rosset, Andrew Gerrand, golang-nuts, Henrik Johansson, Kyle Lemons
On Wed, Feb 29, 2012 at 5:24 PM, Mike Rosset <mike....@gmail.com> wrote:
> Also note, on some OS-Arch combinations (Linux/ARM), we simply can't provide
> a universal
> compiler binary which can be run on every possible platforms.
> soft/hard floating point, arm/thumb, oabi/eabi, different dynamic linker,
> different libc, etc.

Yes, and some Linux/ARM systems do not even have bash, ie andriod. I
do think decoupling bootstrapping with bash, vs building from hg
without bash and Go1 would make build on windows alot easier even if
Why? To build on Windows, you only need a C compiler (mingw) and hg, and
no Unix utility is needed.
Even if we replaced run.bash/make.bash, etc., with Go scripts, we still have
gc which is written in C, not Go.

Joseph Poirier

unread,
Feb 29, 2012, 4:31:39 AM2/29/12
to Rob 'Commander' Pike, minux, Mike Rosset, Andrew Gerrand, golang-nuts, Henrik Johansson, Kyle Lemons
On Wed, Feb 29, 2012 at 3:17 AM, Rob 'Commander' Pike <r...@google.com> wrote:
> Let's just get rid of files altogether. They always have the wrong contents. Make everything dynamic. The computer should just do what I want without me having to write anything down. Commands can go, too. Stupid things.
>
> -rob
>

Candy Mountain Charlie... http://www.youtube.com/watch?v=JPONTneuaF4

Volker Dobler

unread,
Feb 29, 2012, 4:34:15 AM2/29/12
to golang-nuts
On Feb 29, 10:17 am, Rob 'Commander' Pike <r...@google.com> wrote:
> Let's just get rid of files altogether. They always have the wrong contents. Make everything dynamic. The computer should just do what I want without me having to write anything down. Commands can go, too. Stupid things.
>

That is just slightly exaggerated customer speak. You changed fronts?

Volker

Aram Hăvărneanu

unread,
Feb 29, 2012, 7:56:54 AM2/29/12
to Mike Rosset, Kyle Lemons, Henrik Johansson, golan...@googlegroups.com
>> Chicken and egg.  You have to start somewhere.  Bash exists and works well.
>
> Yes on unix, however tell that to the windows guys where we have
> all.bat and make.bat.

cmd.exe exists and works well.

What exactly are you trying to say?

--
Aram Hăvărneanu

Ian Lance Taylor

unread,
Feb 29, 2012, 9:46:26 AM2/29/12
to dlin, golan...@googlegroups.com
dlin <dli...@gmail.com> writes:

> To try to explain I like the idea to builtin shebang in Go (maybe after
> Go1).

Why not just use https://wiki.ubuntu.com/gorun ?

This is an area where people can easily provide their own tools, and
where there is no obviously correct approach.

Ian

Joseph Poirier

unread,
Feb 29, 2012, 12:24:27 PM2/29/12
to Ian Lance Taylor, dlin, golan...@googlegroups.com
On Wed, Feb 29, 2012 at 8:46 AM, Ian Lance Taylor <ia...@google.com> wrote:
> dlin <dli...@gmail.com> writes:
>
>> To try to explain I like the idea to builtin shebang in Go (maybe after
>> Go1).
>
> Why not just use https://wiki.ubuntu.com/gorun ?

Or the quick and dirty (and ugly) method:


#!/usr/bin/env bash
tail -n +4 "in.go" > "out.go" && go run "out.go"
exit 0

package main
import (
"fmt"
)
func main( ) {
fmt.Println("Span And Eggs")
}

Joseph Poirier

unread,
Feb 29, 2012, 1:05:34 PM2/29/12
to Ian Lance Taylor, dlin, golan...@googlegroups.com
On Wed, Feb 29, 2012 at 11:24 AM, Joseph Poirier <jdpo...@gmail.com> wrote:
> On Wed, Feb 29, 2012 at 8:46 AM, Ian Lance Taylor <ia...@google.com> wrote:
>> dlin <dli...@gmail.com> writes:
>>
>>> To try to explain I like the idea to builtin shebang in Go (maybe after
>>> Go1).
>>
>> Why not just use https://wiki.ubuntu.com/gorun ?
>
> Or the quick and dirty (and ugly) method:
>

Yes, the three lines starting with the shebang go at the top of the
"go" source file, then
$ chmod +x ./in.go
$ ./in.go

Krzysztof Kowalczyk

unread,
Feb 29, 2012, 3:24:48 PM2/29/12
to Ian Lance Taylor, dlin, golan...@googlegroups.com

Because: http://golang.org/#%23!%2Fusr%2Fbin%2Fgorun%0A%0Apackage%20main%0A%0Afunc%20main()%20%7B%0A%20%20%20%20println(%22Hello%20world!%22)%0A%7D%0A

gives:

prog.go:1: syntax error: unexpected #
prog.go:1: package statement must be first
prog.go:1: syntax error: unexpected /

If Go compiler simply skips #! line then yes, we can build tools that
work just as well as python or ruby #! scripts.

Since it doesn't, a given file .go file is either correct for the
compiler or correct for gorun but not for both which is not the same
level of convenience as in python or tinycc.

-- kjk

Kyle Lemons

unread,
Feb 29, 2012, 5:07:39 PM2/29/12
to Krzysztof Kowalczyk, Ian Lance Taylor, dlin, golan...@googlegroups.com
On Wed, Feb 29, 2012 at 6:46 AM, Ian Lance Taylor <ia...@google.com> wrote:
> dlin <dli...@gmail.com> writes:
>
>> To try to explain I like the idea to builtin shebang in Go (maybe after
>> Go1).
>
> Why not just use https://wiki.ubuntu.com/gorun ?
>
> This is an area where people can easily provide their own tools, and
> where there is no obviously correct approach.

Because: http://golang.org/#%23!%2Fusr%2Fbin%2Fgorun%0A%0Apackage%20main%0A%0Afunc%20main()%20%7B%0A%20%20%20%20println(%22Hello%20world!%22)%0A%7D%0A

gives:

prog.go:1: syntax error: unexpected #
prog.go:1: package statement must be first
prog.go:1: syntax error: unexpected /

What does the playground have to do with the gorun tool? 

SteveD

unread,
Mar 1, 2012, 5:41:32 AM3/1/12
to golang-nuts
On Feb 29, 11:24 am, Mike Rosset <mike.ros...@gmail.com> wrote:
> My real point is that I much rather be coding things in Go where
> possible vs bash,bat,ruby,python and have the convenience of a
> shebang. But all in all I can use go run, or a shell wrapper to go
> run, in those cases so I wont press the issue.

Exactly. Shebang can be used when available, but Windows works
differently - the executable is deduced from the extension, and if the
extension is in %PATHEXT% then it can be called directly from the
command-line without extension.

If something like gorun is independently maintained then that's cool
(it does a dependency check so it does not rebuild each time it
runs). Some feel that encouraging scripting causes bad code to
happen, but bad code will always happen, even if people have to
explicitly build their programs.

steve d.

mattn

unread,
Mar 1, 2012, 6:09:50 AM3/1/12
to golan...@googlegroups.com, mattn, Jens-Uwe Mager, Miki Tebeka, kritic
currently, gorun uses sysStat structure that's os related. On windows, it's named as winStat. And it's provided for only windows.
So it's impossible to work without changes for Linux/MacOSX.

On Wednesday, February 29, 2012 3:37:09 AM UTC+9, Gustavo Niemeyer wrote:
On Tue, Feb 28, 2012 at 10:11, mattn <matt...@gmail.com> wrote:
> It seems that gorun does not run on windows.

That's only because Windows isn't home for Gustavo. Patches that
enable it to work without changing Linux/MacOS semantics accepted,
though.

-- 
Gustavo Niemeyer

-- I'm not absolutely sure of anything.

On Wednesday, February 29, 2012 3:37:09 AM UTC+9, Gustavo Niemeyer wrote:
On Tue, Feb 28, 2012 at 10:11, mattn <matt...@gmail.com> wrote:
> It seems that gorun does not run on windows.
That's only because Windows isn't home for Gustavo. Patches that
enable it to work without changing Linux/MacOS semantics accepted,
though.

-- 
Gustavo Niemeyer

-- I'm not absolutely sure of anything.

Paul Borman

unread,
Mar 1, 2012, 11:34:58 AM3/1/12
to golang-nuts
So if I understand you requirement, you require that the exact same file, which is a single file go program, be both compilable source as well as an executable script, is that more or less what you are saying?

I hear the others saying you can easily make an executable script by prepending a go program with 3 lines of non-go code.

A main argument I hear against the whole concept is that invoking the compiler for each and every call of the script is perhaps not the best use of cpu cycles when it is so easy to simply install the compiled version.  Using gorun could mitigate this, but I am not sure that is true if you recreate the real go source each time.  Both approaches seem flawed to me as they require someplace to build and run the program from.

I feel like what you really would like is a go interpreter.  Given the design of the Go language an interpreted go would either a) need to be a variant/subset of the language or b) the interpreter will need to compile the code internally anyhow as the first statement may very well depend on the final statement of the source.

If you do want to go forward with this concept, there are solutions there that require no changes to the specification or the compiler, as such, I do not see a compelling reason to add a platform specific solution that does require changes to the compiler and/or specification.

I think at this poing you should abandon the tangental goal of being able to directly execute Go source.  Go source is meant to be compiled.  Use one of the several solutions for turning Go source into an executable file (either by prepending a few lines or even just compiling the source once and for all).

My own view is that scripts are very handy because they can be easily edited and re-run.  Traditionally this has been a less efficient process with compiled languages.  In particular, the compiler is not always there.  Since all solutions, including your own, do require the compiler and the Go team and community have worked hard to make the workflow from source to running as painless as possible I think perhaps now is a good time to reconsider your paradigms and needs.  Many of the original reasons for scripts vs binaries are no longer there, other than habit.

Sebastien Binet

unread,
Mar 1, 2012, 11:58:05 AM3/1/12
to Paul Borman, golang-nuts
Paul,

On Thu, 1 Mar 2012 08:34:58 -0800, Paul Borman <bor...@google.com> wrote:
> So if I understand you requirement, you require that the exact same file,
> which is a single file go program, be both compilable source as well as an
> executable script, is that more or less what you are saying?
>
> I hear the others saying you can easily make an executable script by
> prepending a go program with 3 lines of non-go code.
>
> A main argument I hear against the whole concept is that invoking the
> compiler for each and every call of the script is perhaps not the best use
> of cpu cycles when it is so easy to simply install the compiled version.
> Using gorun could mitigate this, but I am not sure that is true if you
> recreate the real go source each time. Both approaches seem flawed to me
> as they require someplace to build and run the program from.
>
> I feel like what you really would like is a go interpreter. Given the
> design of the Go language an interpreted go would either a) need to be a
> variant/subset of the language or b) the interpreter will need to compile
> the code internally anyhow as the first statement may very well depend on
> the final statement of the source.

there is a beginning of an interpreter over here:
https://bitbucket.org/binet/go-eval

which I salvaged from its old home exp/eval.

-s

--
#########################################
# Dr. Sebastien Binet
# Laboratoire de l'Accelerateur Lineaire
# Universite Paris-Sud XI
# Batiment 200
# 91898 Orsay
#########################################

Joseph Poirier

unread,
Mar 1, 2012, 4:11:01 PM3/1/12
to Paul Borman, golang-nuts

Agreed. It's just not needed.

Although there were, IMHO, a few red herring arguments against,
there's no reason to force the Go compiler proper to recognize the
shebang in order to add _another_ compilation/run mechanism. Those
mechanisms already exists and it's little effort to customize and/or
expand them.

On a side note, the shebang is yet another Dennis Ritchie creation
(http://tinyurl.com/7luzego) - allow interpreted files to run more
like executables.

-joe

Glenn Brown

unread,
Mar 1, 2012, 5:02:43 PM3/1/12
to Joseph Poirier, Paul Borman, golang-nuts

> On a side note, the shebang is yet another Dennis Ritchie creation
> (http://tinyurl.com/7luzego) - allow interpreted files to run more
> like executables.

Now there's a compiler creator who didn't argue against adding script support to his program launcher…

For disenfranchised scripters, here's a demo of 3 lines of black magic:

> cat hi
#!/bin/bash
d="/tmp/$USER/.tgo/src/`basename "$0"`"&&mkdir -p "$d"&&sed 1,3d "$0"|\
(cd "$d"&&cat>"$$.go"&&go run "$$.go" "$@"<&3;s=$?;rm -f $$.go;exit $s)3<&1;exit


package main
import (
"fmt"

"os"
)
func main() {
fmt.Printf ("Hello, World. %v\n", os.Args[1:]);
}
> ./hi I do not expect some to understand this.
Hello, World. [I do not expect some to understand this.]
>

Unfortunately, gofmt barfs on the file, and "go run" does not pass stdin to the run program.

--Glenn

Joseph Poirier

unread,
Mar 1, 2012, 5:40:17 PM3/1/12
to Glenn Brown, Paul Borman, golang-nuts
On Thu, Mar 1, 2012 at 4:02 PM, Glenn Brown <tornad...@gmail.com> wrote:
>
>> On a side note, the shebang is yet another Dennis Ritchie creation
>> (http://tinyurl.com/7luzego) - allow interpreted files to run more
>> like executables.
>
> Now there's a compiler creator who didn't argue against adding script support to his program launcher…
Right, launcher not compiler.


> For disenfranchised scripters, here's a demo of 3 lines of black magic:
>
>> cat hi
> #!/bin/bash
> d="/tmp/$USER/.tgo/src/`basename "$0"`"&&mkdir -p "$d"&&sed 1,3d "$0"|\
> (cd "$d"&&cat>"$$.go"&&go run "$$.go" "$@"<&3;s=$?;rm -f $$.go;exit $s)3<&1;exit
> package main
> import (
>        "fmt"
>        "os"
> )
> func main() {
>        fmt.Printf ("Hello, World. %v\n", os.Args[1:]);
> }
>> ./hi I do not expect some to understand this.
> Hello, World. [I do not expect some to understand this.]
>>
>
> Unfortunately, gofmt barfs on the file, and "go run" does not pass stdin to the run program.
>
> --Glenn

Already done. From an earlier post in this thread.

$ chmod +x ./in.go
$ ./in.go

#!/usr/bin/env bash
tail -n +4 "in.go" > "out.go" && go run "out.go"
exit 0

package main
import (
"fmt"

Rob 'Commander' Pike

unread,
Mar 1, 2012, 5:53:39 PM3/1/12
to Joseph Poirier, Glenn Brown, Paul Borman, golang-nuts

Now there's a compiler creator who didn't argue against adding script support to his program launcher…

C does not support #!.

x.c:1:2: error: invalid preprocessing directive #!

My point is and always has been that putting #! into a compiled language is a category error. Dennis would agree.

-rob

Archos

unread,
Mar 1, 2012, 6:15:52 PM3/1/12
to golang-nuts
This thread is being so long but it shows that there are enough people
in favor to the shebang.
Well, there is really another option to get it, without changing
compiler, and without patching kernel neither shells, being valid for
whatever system. The solution: this weekend when I've some free time
to build it.

Andrew Gerrand

unread,
Mar 1, 2012, 6:55:22 PM3/1/12
to Archos, golang-nuts
On 2 March 2012 10:15, Archos <raul...@sent.com> wrote:
> This thread is being so long but it shows that there are enough people
> in favor to the shebang.
> Well, there is really another option to get it

Yeah, and it's called gorun.

https://wiki.ubuntu.com/gorun

Andrew

Archos

unread,
Mar 1, 2012, 7:01:24 PM3/1/12
to golang-nuts
Yeah, I'm the author of GoNow (renamed from goscript) which was
created before than gorun.

https://github.com/kless/GoNow

On Mar 1, 11:55 pm, Andrew Gerrand <a...@golang.org> wrote:

Krzysztof Kowalczyk

unread,
Mar 1, 2012, 9:41:52 PM3/1/12
to Rob 'Commander' Pike, Joseph Poirier, Glenn Brown, Paul Borman, golang-nuts

tinycc is a C compiler and does support #! so the argument doesn't
state some absolute truth. When C was was created #! probably didn't
exist, it certainly wasn't popular and for many years #! support
wasn't practical due to puny hardware. But as tinycc shows, times have
changed and it's doable and useful.

Why should dogma trump practicality and usefulness? Perl, python and
ruby do it not because they chose a particular implementation
technique but because it's useful for a wide range of things that
people do on Unix systems. Git is partially implemented via perl
scripts and thanks to #! support in Perl the user doesn't have to care
that ./git-svn happens to be a perl script and not x86 binary as it's
irrelevant to his goal.

"compiled language" is not a meaningful term as it's the property of
the implementation and not the language.

V8 is a JavaScript implementation that only compiles directly to x86
and their compiler is probably more sophisticated than Go's x86
compiler. Is V8 not "compiled" due to a minor implementation detail
(that the code is generated and "linked" directly in memory and not
dumped to disk in elf format just so that it can be read back into
memory for execution)?

Is there an argument for why Go compiler can't implement that trivial
change of skipping #! line that doesn't boil down to a personal
opinion that clearly isn't shared by many?

-- kjk

Jamu Kakar

unread,
Mar 1, 2012, 9:55:12 PM3/1/12
to Krzysztof Kowalczyk, Rob 'Commander' Pike, Joseph Poirier, Glenn Brown, Paul Borman, golang-nuts
Hi Krzysztof,

On Thu, Mar 1, 2012 at 11:41 PM, Krzysztof Kowalczyk
<kkowa...@gmail.com> wrote:
> Is there an argument for why Go compiler can't implement that trivial
> change of skipping #! line that doesn't boil down to a personal
> opinion that clearly isn't shared by many?

Being able to use Go in scripts is pretty handy and I'm glad we're
able to take advantage of that functionality with tools like gorun and
gonow. Some points about your comments:

- Putting this functionality in the compiler adds additional
complexity in a core tool that is already pretty complex. Sure, we
could argue that this is a small thing, not a big deal, but small
things add up and create overhead that slows the software down,
creates additional bug vectors and makes it harder for people to
work with the code.

- Putting this functionality in the compiler would effectively
shutdown tools like gorun and gonow. This would have the effect of
limiting the innovation that can happen in this space, because
people will not be compelled to try new ideas out. As it stands now
it's a wide open space. Anyone can come along and propose something
better than what we already have and they have a good chance of
getting traction if they're software is better.

- It already works today. We have gorun and gonow, they work great,
you can choose the one which is best suited to your use cases. What
you're asking for amounts to moving the logic from one place to
another for no obvious benefit. Okay, you have to install gorun or
gonow, but big deal. The 'go' tool makes that so easy that it's a
no-brainer. If you use Ubuntu gorun is already included in the
golang package, so you don't even need to do anything special.

I don't think this is about one opinion vs. another. It's just a
pragmatic decision to limit complexity in the core toolset and it
makes pretty good sense given that tools like gorun and gonow have
emerged to solve the problem.

Thanks,
J.

Rob 'Commander' Pike

unread,
Mar 1, 2012, 9:58:56 PM3/1/12
to Krzysztof Kowalczyk, Joseph Poirier, Glenn Brown, Paul Borman, golang-nuts

I have never said it cannot be done. I have always said it should not be done, and I have explained why.

"Useful" is not an argument for a feature. All features are useful; otherwise they would not be features. The issue is whether the feature justifies its cost. That is a judgement call, and my judgement is, no. Running compilers and linkers, doing megabytes of I/O, and creating temporary binary files is not a justifiable expense for running a small program. For large programs, the amortization is even more in favor of not doing this.

I am firmly against adding a feature to Go that encourages abuse of resources.

If you want the feature, use gorun or an equivalent wrapper program. That's what it's for. I think believe gorun is a mistake, but I'm not stopping you from installing it and using it as you see fit.

-rob

Gustavo Niemeyer

unread,
Mar 1, 2012, 10:26:27 PM3/1/12
to Rob 'Commander' Pike, golang-nuts
On Thu, Mar 1, 2012 at 23:58, Rob 'Commander' Pike <r...@google.com> wrote:
> I think believe gorun is a mistake, but I'm not stopping you from installing it and using it as you see fit.

That silly tool was created at a time when the "go" tool did not
exist, and has brought people from other camps to get in touch with Go
in a way that was simple and familiar to them. My theory is that those
people will shift over to do real programs using the full-fledged
suite, if they happen to appreciate the language, and so far that has
been the case with people I followed. That's why I personally don't
care at all that #! isn't supported, or that gofmt doesn't work, or
that it bothers you ;-). It's just a door onto proper Go. It may well
die now that the "go" tool is so convenient, though.

Jens-Uwe Mager

unread,
Mar 1, 2012, 10:43:14 PM3/1/12
to golan...@googlegroups.com, Rob 'Commander' Pike
It is still useful for example if you happen to use an editor like TextWrangler on the Mac, which has direct support for executing scripts via the shebang mechanism and collect the results. This way you just press one shortcut in your editor and can see the results directly. I use that while developing, where each run has to be recompiled anyways.

Joe Poirier

unread,
Mar 1, 2012, 11:31:50 PM3/1/12
to golang-nuts
Putting the shebang in a Go source file doesn't make it a script. It's
a script when the program listed on the shebang line is an interpreter
that, when executed, is fed the script file. Using the shebang in a Go
file doesn't stop it from getting compiled and only kicks off a series
of events that the shebang wasn't intended start, events that are
better served just as easily in other ways.


A) shebang in a script file, $ ./myscript.x
----------------------------------------------------------
Purpose: to get a script file to run like an executable
Process: bash executes the interpreter identified on the shebang line
passing it the script file's name, the interpretor runs the script
file.

B) shebang in a source file, $ ./file.go
------------------------------------------------------
Purpose: to get a source file to be run like a script file
Process: bash executes the tool (GoRun, GoNow, etc..) identified on
the shebang line passing it the source file's name, the same tool
calls the Go compiler, then the Go linker, then the generated
executable.

C) Running a source file using the Go tool, $ Go run file.go
------------------------------------------------------------------------------------
Purpose: to compile and execute a source file using a single command
Process: bash executes the tool identified on the command line passing
it the source file's name and the 'run' argument, the tool calls the
Go compiler, then the Go linker, then the generated executable.


A: uses the shebang as it was intended.

B: does not use the shebang as it was intended, 4 characters less to
type on the command line but includes 4+ characters more in the source
file as compared to C, the source file is not directly Go compilable.

C: doesn't use the shebang, 4 characters more to type on the command
line but no extra characters included in the source file as compared
to B, the source file is directly Go compilable.


If the difference between A's and B's usage of the shebang isn't clear-
it's not clear if you're calling the use of a shebang in a Go file
that's being compiled scripting-read Ritchie's original shebang email
announcement http://tinyurl.com/7luzego

To see how the shebang is processed in the bash source code (ftp://
ftp.cwru.edu/pub/bash/) look at execute_cmd.c.

-joe

Krzysztof Kowalczyk

unread,
Mar 2, 2012, 12:04:31 AM3/2/12
to Rob 'Commander' Pike, Joseph Poirier, Glenn Brown, Paul Borman, golang-nuts

So your position is that your opinion should dictate how *I* use (I'm
sorry, I meant abuse) *my* resources?

I understand the argument about costs and tradeoffs but I was hoping
for an argument that relates to the costs and tradeoffs of skipping #!
in Go compiler wrt. Go language and its compiler.

An argument that expresses a concern about how I decide to use the
computing power that I paid for is not satisfactory to me but it seems
it's the best I can hope for. You stated your opinion and I should
probably drop it, but...

The efficiency argument is bogus. It's trivial to implement gorun-like
tool so that it compiles only the first time and uses the cached
executable every other time after a cheap dependency check (Go
compiler doesn't recompile everything from scratch every time, does
it?). The only efficiency difference compared to compiling would be
that dependency check.

The choice is not between a compiled Go-compiled executable and Go
"script" but Go "script" and a python or perl script and those are
certainly not faster in interpreting their code so to the extent that
people would replace ruby scripts with Go "scripts" you would be
fighting the good fight.

Even if there was a big difference people make the human efficiency
vs. computing efficiency tradeoffs all the time. You do too. Unless,
of course, you want to tell me that you refuse to type hg
(http://selenic.com/hg/file/b2d6832db306/hg) or any other python or
bash script because you're such a principled person.

To address the final point (and repeat myself): gorun does not provide
the same level of convenience as tinycc or python and it cannot unless
Go compiler skips #!.

Not to mention the logic error of encouraging me to use gorun. You
can't stop me from using Go compiler in a way that doesn't align with
your "judgement call" without changing Unix but you sure are not going
to help me to do the same in a more convenient way because if you
don't fight for the transistors, then who will?

-- kjk

Gustavo Niemeyer

unread,
Mar 2, 2012, 12:25:38 AM3/2/12
to Krzysztof Kowalczyk, Rob 'Commander' Pike, Joseph Poirier, Glenn Brown, Paul Borman, golang-nuts
> So your position is that your opinion should dictate how *I* use (I'm
> sorry, I meant abuse) *my* resources?

LOL.. you're asking that to one of the designers of the language, so
the answer is obviously *yes*.

> The efficiency argument is bogus. It's trivial to implement gorun-like
> tool so that it compiles only the first time and uses the cached

gorun does that.

> To address the final point (and repeat myself): gorun does not provide
> the same level of convenience as tinycc or python and it cannot unless
> Go compiler skips #!.

gorun works with #!.

Sounds like you're more interested in arguing than in using what
you're arguing for.

Rob 'Commander' Pike

unread,
Mar 2, 2012, 1:20:29 AM3/2/12
to golang-nuts
goto again;

Julian Phillips

unread,
Mar 2, 2012, 4:11:21 AM3/2/12
to Glenn Brown, Joseph Poirier, Paul Borman, golang-nuts
On Thu, 1 Mar 2012 14:02:43 -0800, Glenn Brown wrote:
>> On a side note, the shebang is yet another Dennis Ritchie creation
>> (http://tinyurl.com/7luzego) - allow interpreted files to run more
>> like executables.
>
> Now there's a compiler creator who didn't argue against adding script
> support to his program launcher…
>
> For disenfranchised scripters, here's a demo of 3 lines of black
> magic:

Here's some more magic (only one line - but it does use gorun), source
code you can run or compile, which is gofmt friendly:

jp3@rayne: t>ls
t.go
jp3@rayne: t>cat t.go
//usr/bin/env gorun "$0" "$@"; exit

package main

import (
"fmt"
"os"
)

func main() {
fmt.Printf("Args: %v\n", os.Args)
}
jp3@rayne: t>./t.go Hello World!
Args: [./t.go Hello World!]
jp3@rayne: t>gofmt -l *.go
jp3@rayne: t>go build
jp3@rayne: t>ls
t t.go
jp3@rayne: t>./t Hello World!
Args: [./t Hello World!]

This is shell magic though, so you can't exec t.go ...

(I don't see what the big deal about using the compiled binaries is
myself, but ... <shrugs/>)

--
Julian

Aram Hăvărneanu

unread,
Mar 2, 2012, 4:26:59 AM3/2/12
to Krzysztof Kowalczyk, Rob 'Commander' Pike, Joseph Poirier, Glenn Brown, Paul Borman, golang-nuts
I don't understand why one earns for a shebang this much. I write awk
micro-programs every day, you can kind of put a /usr/bin/awk -f
shebang in an awk program, but most often it is not what you really
want, so quite often I have to write shell wrappers that call my awk
programs.

I never felt that I miss anything by writing these shell wrappers,
that's why we have a programmable shell.

--
Aram Hăvărneanu

Aram Hăvărneanu

unread,
Mar 2, 2012, 4:50:30 AM3/2/12
to Krzysztof Kowalczyk, Rob 'Commander' Pike, Joseph Poirier, Glenn Brown, Paul Borman, golang-nuts
> I don't understand why one earns for a shebang this much.

s/earns/yearns/

> you can kind of put a /usr/bin/awk -f
> shebang in an awk program, but most often it is not what you really
> want

And let us remember how BSD solved the "problem":

#!/usr/bin/env -S awk -F: -f ${_} --

Another example of feature creep with questionable gains.

If one wants to fire a compiler and linker every time you run a
command, I'm sure the overhead one needs to endure by not having a
shebang is less than the effort one puts by responding to this thread.

--
Aram Hăvărneanu

mattn

unread,
Mar 2, 2012, 5:01:03 AM3/2/12
to golan...@googlegroups.com, Ian Lance Taylor, dlin
I think this is good solution.
I ported it to windows batch file. :)

https://gist.github.com/1957461

On Thursday, March 1, 2012 2:24:27 AM UTC+9, Joe Poirier wrote:
On Wed, Feb 29, 2012 at 8:46 AM, Ian Lance Taylor <ia...@google.com> wrote:
> dlin <dli...@gmail.com> writes:
>
>> To try to explain I like the idea to builtin shebang in Go (maybe after
>> Go1).
>
> Why not just use https://wiki.ubuntu.com/gorun ?

Or the quick and dirty (and ugly) method:


#!/usr/bin/env bash
tail -n +4  "in.go" > "out.go" && go run "out.go"
exit 0

package main
import (
        "fmt"

Ben Measures

unread,
Mar 2, 2012, 9:09:51 AM3/2/12
to golang-nuts
On 2 Mar, 05:04, Krzysztof Kowalczyk <kkowalc...@gmail.com> wrote:
> On Thu, Mar 1, 2012 at 6:58 PM, Rob 'Commander' Pike <r...@google.com> wrote:
> > On Mar 2, 2012, at 1:41 PM, Krzysztof Kowalczyk wrote:
> >>
> >> why Go compiler can't
>
> > I have never said it cannot be done. I have always said it should not be done, and I have explained why.
>
> So your position is that your opinion should dictate how *I* use (I'm
> sorry, I meant abuse) *my* resources?

Let's rephrase the question:
>>> Why can't you make the gun have a U-shaped barrel so that it can shoot backwards?
>> I have never said it cannot be done. I have always said it should not be done, and I have explained why.
> So your position is that your opinion should dictate how *I* use (I'm sorry, I meant abuse) *my* resources?

Have a fish:
$ cd `mktemp -d`
$ cat <<"EOF" > hello_world.go
package main

import (
"fmt"
)

func main() {
fmt.Print("Hello, world!\n");
}
EOF
$ cat <<"EOF" > goscript.sh
#!/bin/bash

# fail on error or unset variables
set -o errexit
set -o nounset

# bin
basenamebin=/bin/basename
dirnamebin=/usr/bin/dirname
readlinkbin=/usr/bin/readlink

# locations
scriptdir=`$dirnamebin "$BASH_SOURCE[0]"`; scriptdir=`$readlinkbin -f
"$scriptdir"`
scriptname=`$basenamebin "$BASH_SOURCE[0]"`; scriptname="${scriptname
%.sh\[0\]}"

if [ ! -f "$scriptdir"/"${scriptname}.go" ]; then
echo "$scriptdir/${scriptname}.go: No such file"
exit 1
fi

if [ "$scriptdir"/"${scriptname}.go" -nt "$scriptdir"/"$scriptname" ];
then
( cd "$scriptdir" && go build "${scriptname}.go" )
fi

"$scriptdir"/"$scriptname"
EOF
$ chmod 755 goscript.sh
$ ln -s goscript.sh hello_world.sh
$ ./hello_world.sh

--
Benjamin

Liigo Zhuang

unread,
Mar 2, 2012, 11:25:22 AM3/2/12
to Rob 'Commander' Pike, golang-nuts

A very trial change is needed to gc to skip #! line in go source files. No a bad thing. +1

在 2012-3-2 下午2:20,"Rob &apos;Commander&apos; Pike" <r...@google.com>写道:
goto again;

Paul Borman

unread,
Mar 2, 2012, 11:29:03 AM3/2/12
to golang-nuts
Go is open source and distributed in source.  You are free to patch your version of the go compiler to do just this and install it on your system.  hg will bring forward your change each time you pull and update..  Problem solved.

Do not expect it as part of the official distribution.  The Go team is not in favor of it and they decide what goes into the language.  Thankfully Go was not designed by committee.  Use C++ or Ada for committee designed languages.

Glenn Brown

unread,
Mar 2, 2012, 12:30:14 PM3/2/12
to Rob 'Commander' Pike, Joseph Poirier, Paul Borman, golang-nuts
I understand and respect the decision to keep the unix-specific #! out of Go, which is rightly focusing on features with much higher cost/benefit ratios. I expect a platform-independent solution like ignoring tokens before 'package' would be similarly rejected, and also understand that. Just because I wish I could gofmt my shebanged one-off scripts in arbitrary directories without setting environment variables does not mean it is right for the language.

Thanks, Rob, for engaging the community, considering half-baked ideas, and explaining your rational when rejecting them.

--Glenn

Glenn Brown

unread,
Mar 2, 2012, 12:41:24 PM3/2/12
to Rob 'Commander' Pike, Joseph Poirier, Paul Borman, golang-nuts
> focusing on features with much higher cost/benefit ratios

^higher^lower

Gustavo Niemeyer

unread,
Mar 2, 2012, 12:50:06 PM3/2/12
to Rob 'Commander' Pike, golang-nuts
> goto again;

shebang.go:7: goto again jumps over declaration of reason at shebang.go:8

Dzmitry Lahoda

unread,
Jun 21, 2023, 2:33:57 PM6/21/23
to golang-nuts
rust just got shebang and cargo in one file. i was hoping using go as good fit for some cases. but seem it will be rust. we are go, bash, nix, rust coders. sure there is some js in our repo. but i hate it. i like to so script which goes into production. bash and nix goes to ops and devs and qa. rust and go go to devs. so with rust now i can at least start and know where it ends. hope go will be sane in that area soon too. go is very good language for one file things so, speed of compilation faster than speed of python or powershell or js whatever garbage they do to setup and run.

Jan Mercl

unread,
Jun 21, 2023, 3:14:11 PM6/21/23
to Dzmitry Lahoda, golang-nuts
On Wed, Jun 21, 2023 at 8:33 PM Dzmitry Lahoda <dzmitry...@gmail.com> wrote:
>
> rust just got shebang and cargo in one file. i was hoping using go as good fit for some cases. but seem it will be rust. we are go, bash, nix, rust coders. sure there is some js in our repo. but i hate it. i like to so script which goes into production. bash and nix goes to ops and devs and qa. rust and go go to devs. so with rust now i can at least start and know where it ends. hope go will be sane in that area soon too. go is very good language for one file things so, speed of compilation faster than speed of python or powershell or js whatever garbage they do to setup and run.

See for example https://stackoverflow.com/a/30082862

Dzmitry Lahoda

unread,
Jun 21, 2023, 6:20:09 PM6/21/23
to Jan Mercl, golang-nuts
have seen, but 
1. nix will not fix it to point to  proper go, need custom derivation
2. hard to recall these symbols each time
3. exit issue
4. what else operational issue not named?
and:
5. go is not shell language, but it has super nice remote packages to do shell like things. cli, process, unix handling. etc. so i can shortcut go to be as short as bash. and these tools are super maintained, unlike attempts in csharp or haskell.

so i do not get bash experience in go because local default package are more system level, not shell. btw rust by design has shell like crates used in build.rs.

i have seen i can mount some local packages, sure i can wrap these mounts for one liner in nix, but how to run that go script by random people drowning in doing setups.

i can build around all for such scripts, even there is dead go run project doing so. but i have seen only default tooling wins. at least in enterprise and crud coding. 

so because setting go shell script is hurdle, not default out of box, it will not be adopted, regardless what people say it is oss, feel free to contrib)))

so instead of doing go shell scripts, and grow them into tooling as time goes, other way will happen.  other is use bash, python, rust, js.
Reply all
Reply to author
Forward
0 new messages